Add: Server, Client
- Client: No Verify Server Certificate
This commit is contained in:
parent
132eee8091
commit
eb30b7c2df
170
src/bin/allow_any_cert_client.rs
Normal file
170
src/bin/allow_any_cert_client.rs
Normal file
@ -0,0 +1,170 @@
|
||||
extern crate pretty_env_logger;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
use rustls::version::TLS13;
|
||||
use rustls::RootCertStore;
|
||||
use std::error::Error as StdError;
|
||||
use std::io::{Read, Write};
|
||||
use std::sync::Arc;
|
||||
use x509_parser::prelude::*;
|
||||
|
||||
fn initialize_log() {
|
||||
pretty_env_logger::formatted_timed_builder()
|
||||
.format(|buf, record| {
|
||||
// We are reusing `anstyle` but there are `anstyle-*` crates to adapt it to your
|
||||
// preferred styling crate.
|
||||
let mut level_style = buf.default_level_style(record.level());
|
||||
let arg_style = level_style.clone();
|
||||
let timestamp = buf.timestamp_micros();
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
"[{timestamp} {:6}] {:>30}:{:<5} - {}",
|
||||
level_style.set_bold(true).value(record.level()),
|
||||
record.file_static().unwrap(),
|
||||
record.line().unwrap(),
|
||||
arg_style.value(record.args())
|
||||
)
|
||||
})
|
||||
.format_timestamp_micros()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
info!("Hi -");
|
||||
}
|
||||
|
||||
// 모든 인증서를 신뢰하는 인증서 검증기 (모든 인증서 PASS)
|
||||
#[derive(Debug)]
|
||||
struct NoCertificateVerification;
|
||||
|
||||
impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
_: &[u8],
|
||||
_: &rustls::pki_types::CertificateDer<'_>,
|
||||
_: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
_: &[u8],
|
||||
_: &rustls::pki_types::CertificateDer<'_>,
|
||||
_: &rustls::DigitallySignedStruct,
|
||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
end_entity: &rustls::pki_types::CertificateDer<'_>,
|
||||
intermediates: &[rustls::pki_types::CertificateDer<'_>],
|
||||
server_name: &rustls::pki_types::ServerName<'_>,
|
||||
_: &[u8],
|
||||
_: rustls::pki_types::UnixTime,
|
||||
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
||||
let ret_deserial = X509Certificate::from_der(&end_entity.iter().as_slice());
|
||||
let x509 = match ret_deserial {
|
||||
Ok((_, x509)) => x509,
|
||||
_ => panic!("wtf"),
|
||||
};
|
||||
let cn = x509
|
||||
.subject()
|
||||
.iter_common_name()
|
||||
.next()
|
||||
.and_then(|cn| cn.as_str().ok()).unwrap();
|
||||
info!(
|
||||
"Server Cert: CN: {}, CA: {}, serverName : {:?}",
|
||||
cn,
|
||||
x509.is_ca(),
|
||||
server_name
|
||||
);
|
||||
|
||||
// end_entity
|
||||
for (idx, ica) in intermediates.iter().enumerate() {
|
||||
let ret_deserial = X509Certificate::from_der(&ica.iter().as_slice());
|
||||
let x509 = match ret_deserial {
|
||||
Ok((_, x509)) => x509,
|
||||
_ => continue,
|
||||
};
|
||||
let cn = x509
|
||||
.subject()
|
||||
.iter_common_name()
|
||||
.next()
|
||||
.and_then(|cn| cn.as_str().ok());
|
||||
let cn = match cn {
|
||||
Some(name) => name,
|
||||
_ => "",
|
||||
};
|
||||
|
||||
info!("[{idx}] CN: {}, CA: {}", cn, x509.is_ca());
|
||||
}
|
||||
info!("verify cert done");
|
||||
Ok(rustls::client::danger::ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||
let mut ss = Vec::<rustls::SignatureScheme>::new();
|
||||
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA1);
|
||||
ss.push(rustls::SignatureScheme::ECDSA_SHA1_Legacy);
|
||||
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA256);
|
||||
ss.push(rustls::SignatureScheme::ECDSA_NISTP256_SHA256);
|
||||
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA384);
|
||||
ss.push(rustls::SignatureScheme::ECDSA_NISTP384_SHA384);
|
||||
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA512);
|
||||
ss.push(rustls::SignatureScheme::ECDSA_NISTP521_SHA512);
|
||||
ss.push(rustls::SignatureScheme::RSA_PSS_SHA256);
|
||||
ss.push(rustls::SignatureScheme::RSA_PSS_SHA384);
|
||||
ss.push(rustls::SignatureScheme::RSA_PSS_SHA512);
|
||||
ss.push(rustls::SignatureScheme::ED25519);
|
||||
ss.push(rustls::SignatureScheme::ED448);
|
||||
|
||||
ss
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn StdError>> {
|
||||
initialize_log();
|
||||
|
||||
let mut config = rustls::ClientConfig::builder_with_protocol_versions(&[&TLS13])
|
||||
.with_root_certificates(RootCertStore::empty())
|
||||
.with_no_client_auth();
|
||||
{
|
||||
// point
|
||||
config
|
||||
.dangerous()
|
||||
.set_certificate_verifier(Arc::new(NoCertificateVerification));
|
||||
config.enable_early_data = false;
|
||||
}
|
||||
|
||||
let server_name = "scope.co.kr".try_into()?;
|
||||
let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name)?;
|
||||
let mut sock = std::net::TcpStream::connect("localhost:10080")?;
|
||||
let mut tls_conn = rustls::Stream::new(&mut conn, &mut sock);
|
||||
let mut rbuf : [u8; 1024] = [0; 1024];
|
||||
|
||||
let wstring = "Hello Rust!";
|
||||
let wsize = match tls_conn.write(wstring.as_bytes()) {
|
||||
Ok(size) => size,
|
||||
Err(ec) => {
|
||||
error!("Write Error: {}", ec.kind().to_string());
|
||||
usize::MAX
|
||||
},
|
||||
};
|
||||
info!("Send Data ({wsize}): {wstring}");
|
||||
|
||||
let rsize = match tls_conn.read(&mut rbuf) {
|
||||
Ok(size) => size,
|
||||
Err(ec) => {
|
||||
error!("Read Error: {}", ec.kind().to_string());
|
||||
0
|
||||
},
|
||||
};
|
||||
|
||||
let utf8string = String::from_utf8(rbuf[0..rsize].to_vec()).expect("could not encoded utf8");
|
||||
info!("Received message from Server ({rsize}): {utf8string}");
|
||||
|
||||
info!("Bye -");
|
||||
Ok(())
|
||||
}
|
84
src/main.rs
Normal file
84
src/main.rs
Normal file
@ -0,0 +1,84 @@
|
||||
extern crate pretty_env_logger;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
use std::env;
|
||||
use std::error::Error as StdError;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::net::TcpListener;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn initialize_log() {
|
||||
pretty_env_logger::formatted_timed_builder()
|
||||
.format(|buf, record| {
|
||||
// We are reusing `anstyle` but there are `anstyle-*` crates to adapt it to your
|
||||
// preferred styling crate.
|
||||
let mut level_style = buf.default_level_style(record.level());
|
||||
let arg_style = level_style.clone();
|
||||
let timestamp = buf.timestamp_micros();
|
||||
|
||||
writeln!(
|
||||
buf,
|
||||
"[{timestamp} {:6}] {:>30}:{:<5} - {}",
|
||||
level_style.set_bold(true).value(record.level()),
|
||||
record.file_static().unwrap(),
|
||||
record.line().unwrap(),
|
||||
arg_style.value(record.args())
|
||||
)
|
||||
})
|
||||
.format_timestamp_micros()
|
||||
.filter_level(log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
info!("Hi -");
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn StdError>> {
|
||||
initialize_log();
|
||||
|
||||
let mut args = env::args();
|
||||
args.next();
|
||||
let cert_file = args.next().expect("missing certificate file argument");
|
||||
let private_key_file = args.next().expect("missing private key file argument");
|
||||
|
||||
let certs = rustls_pemfile::certs(&mut BufReader::new(&mut File::open(cert_file)?))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let private_key =
|
||||
rustls_pemfile::private_key(&mut BufReader::new(&mut File::open(private_key_file)?))?
|
||||
.unwrap();
|
||||
let config = rustls::ServerConfig::builder()
|
||||
.with_no_client_auth()
|
||||
.with_single_cert(certs, private_key)?;
|
||||
|
||||
let listener = TcpListener::bind(format!("[::]:{}", 10080)).unwrap();
|
||||
trace!("Bound TCP Server");
|
||||
|
||||
let mut rbuf = [0u8; 1024 * 64]; // 64kb
|
||||
for r_tcp in listener.incoming() {
|
||||
let mut stream = r_tcp.expect("Accept Failure");
|
||||
stream.set_nodelay(true).expect("Set no delay Failure");
|
||||
let mut tls_conn =
|
||||
rustls::ServerConnection::new(Arc::new(config.clone())).expect("TLS Server Error");
|
||||
tls_conn.complete_io(&mut stream)?;
|
||||
debug!("handshake done!?");
|
||||
|
||||
let rsize = match tls_conn.reader().read(&mut rbuf) {
|
||||
Ok(size) => size,
|
||||
Err(ec) => {
|
||||
error!("Read Error: {}", ec.to_string());
|
||||
continue
|
||||
}
|
||||
};
|
||||
|
||||
let utf8string = String::from_utf8(rbuf[0..rsize].to_vec()).expect("could not encoded utf8");
|
||||
info!("Received message from client ({rsize}): {utf8string}");
|
||||
|
||||
tls_conn.writer().write_fmt(format_args!("Echo, Client say: {}", utf8string))?;
|
||||
debug!("Send Data");
|
||||
tls_conn.complete_io(&mut stream)?;
|
||||
// -> drop tls_conn
|
||||
}
|
||||
|
||||
info!("Bye -");
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user