Compare commits
No commits in common. "temp" and "main" have entirely different histories.
@ -14,4 +14,4 @@ tokio = "1.39.2"
|
|||||||
tokio-rustls = "0.26.0"
|
tokio-rustls = "0.26.0"
|
||||||
webpki = "0.22.4"
|
webpki = "0.22.4"
|
||||||
webpki-roots = "0.26.3"
|
webpki-roots = "0.26.3"
|
||||||
x509-parser = { version = "0.16.0", features = ["verify"]}
|
x509-parser = "0.16.0"
|
||||||
|
@ -64,7 +64,7 @@ impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
|||||||
_: &[u8],
|
_: &[u8],
|
||||||
_: rustls::pki_types::UnixTime,
|
_: rustls::pki_types::UnixTime,
|
||||||
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
||||||
let ret_deserial = X509Certificate::from_der(end_entity.iter().as_slice());
|
let ret_deserial = X509Certificate::from_der(&end_entity.iter().as_slice());
|
||||||
let x509 = match ret_deserial {
|
let x509 = match ret_deserial {
|
||||||
Ok((_, x509)) => x509,
|
Ok((_, x509)) => x509,
|
||||||
_ => panic!("wtf"),
|
_ => panic!("wtf"),
|
||||||
@ -73,8 +73,7 @@ impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
|||||||
.subject()
|
.subject()
|
||||||
.iter_common_name()
|
.iter_common_name()
|
||||||
.next()
|
.next()
|
||||||
.and_then(|cn| cn.as_str().ok())
|
.and_then(|cn| cn.as_str().ok()).unwrap();
|
||||||
.unwrap();
|
|
||||||
info!(
|
info!(
|
||||||
"Server Cert: CN: {}, CA: {}, serverName : {:?}",
|
"Server Cert: CN: {}, CA: {}, serverName : {:?}",
|
||||||
cn,
|
cn,
|
||||||
@ -84,7 +83,7 @@ impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
|||||||
|
|
||||||
// end_entity
|
// end_entity
|
||||||
for (idx, ica) in intermediates.iter().enumerate() {
|
for (idx, ica) in intermediates.iter().enumerate() {
|
||||||
let ret_deserial = X509Certificate::from_der(ica.iter().as_slice());
|
let ret_deserial = X509Certificate::from_der(&ica.iter().as_slice());
|
||||||
let x509 = match ret_deserial {
|
let x509 = match ret_deserial {
|
||||||
Ok((_, x509)) => x509,
|
Ok((_, x509)) => x509,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
@ -93,8 +92,12 @@ impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
|||||||
.subject()
|
.subject()
|
||||||
.iter_common_name()
|
.iter_common_name()
|
||||||
.next()
|
.next()
|
||||||
.and_then(|cn| cn.as_str().ok())
|
.and_then(|cn| cn.as_str().ok());
|
||||||
.unwrap_or_default();
|
let cn = match cn {
|
||||||
|
Some(name) => name,
|
||||||
|
_ => "",
|
||||||
|
};
|
||||||
|
|
||||||
info!("[{idx}] CN: {}, CA: {}", cn, x509.is_ca());
|
info!("[{idx}] CN: {}, CA: {}", cn, x509.is_ca());
|
||||||
}
|
}
|
||||||
info!("verify cert done");
|
info!("verify cert done");
|
||||||
@ -102,21 +105,22 @@ impl rustls::client::danger::ServerCertVerifier for NoCertificateVerification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
||||||
vec![
|
let mut ss = Vec::<rustls::SignatureScheme>::new();
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA1,
|
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA1);
|
||||||
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
|
ss.push(rustls::SignatureScheme::ECDSA_SHA1_Legacy);
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA256,
|
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA256);
|
||||||
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
|
ss.push(rustls::SignatureScheme::ECDSA_NISTP256_SHA256);
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA384,
|
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA384);
|
||||||
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
|
ss.push(rustls::SignatureScheme::ECDSA_NISTP384_SHA384);
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA512,
|
ss.push(rustls::SignatureScheme::RSA_PKCS1_SHA512);
|
||||||
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
|
ss.push(rustls::SignatureScheme::ECDSA_NISTP521_SHA512);
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA256,
|
ss.push(rustls::SignatureScheme::RSA_PSS_SHA256);
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA384,
|
ss.push(rustls::SignatureScheme::RSA_PSS_SHA384);
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA512,
|
ss.push(rustls::SignatureScheme::RSA_PSS_SHA512);
|
||||||
rustls::SignatureScheme::ED25519,
|
ss.push(rustls::SignatureScheme::ED25519);
|
||||||
rustls::SignatureScheme::ED448,
|
ss.push(rustls::SignatureScheme::ED448);
|
||||||
]
|
|
||||||
|
ss
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,15 +142,15 @@ fn main() -> Result<(), Box<dyn StdError>> {
|
|||||||
let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name)?;
|
let mut conn = rustls::ClientConnection::new(Arc::new(config), server_name)?;
|
||||||
let mut sock = std::net::TcpStream::connect("localhost:10080")?;
|
let mut sock = std::net::TcpStream::connect("localhost:10080")?;
|
||||||
let mut tls_conn = rustls::Stream::new(&mut conn, &mut sock);
|
let mut tls_conn = rustls::Stream::new(&mut conn, &mut sock);
|
||||||
let mut rbuf: [u8; 1024] = [0; 1024];
|
let mut rbuf : [u8; 1024] = [0; 1024];
|
||||||
|
|
||||||
let wstring = "Hello Rust!";
|
let wstring = "Hello Rust!";
|
||||||
let wsize = match tls_conn.write(wstring.as_bytes()) {
|
let wsize = match tls_conn.write(wstring.as_bytes()) {
|
||||||
Ok(size) => size,
|
Ok(size) => size,
|
||||||
Err(ec) => {
|
Err(ec) => {
|
||||||
error!("Write Error: {}", ec.kind().to_string());
|
error!("Write Error: {}", ec.kind().to_string());
|
||||||
usize::MAX
|
usize::MAX
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
info!("Send Data ({wsize}): {wstring}");
|
info!("Send Data ({wsize}): {wstring}");
|
||||||
|
|
||||||
@ -155,7 +159,7 @@ fn main() -> Result<(), Box<dyn StdError>> {
|
|||||||
Err(ec) => {
|
Err(ec) => {
|
||||||
error!("Read Error: {}", ec.kind().to_string());
|
error!("Read Error: {}", ec.kind().to_string());
|
||||||
0
|
0
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let utf8string = String::from_utf8(rbuf[0..rsize].to_vec()).expect("could not encoded utf8");
|
let utf8string = String::from_utf8(rbuf[0..rsize].to_vec()).expect("could not encoded utf8");
|
||||||
|
@ -189,7 +189,6 @@ fn load_use_certificate(crt_name: &str, store: &mut RootCertStore) {
|
|||||||
let deserialized_cert = X509Certificate::from_der(cert.iter().as_slice());
|
let deserialized_cert = X509Certificate::from_der(cert.iter().as_slice());
|
||||||
match deserialized_cert {
|
match deserialized_cert {
|
||||||
Ok((_, x509)) => {
|
Ok((_, x509)) => {
|
||||||
x509.verify_signature(public_key)
|
|
||||||
let cn = x509
|
let cn = x509
|
||||||
.subject()
|
.subject()
|
||||||
.iter_common_name()
|
.iter_common_name()
|
||||||
@ -260,12 +259,6 @@ fn main() -> Result<(), Box<dyn StdError>> {
|
|||||||
let mut tls_conn = rustls::Stream::new(&mut conn, &mut sock);
|
let mut tls_conn = rustls::Stream::new(&mut conn, &mut sock);
|
||||||
let mut rbuf: [u8; 1024] = [0; 1024];
|
let mut rbuf: [u8; 1024] = [0; 1024];
|
||||||
|
|
||||||
if let Err(e) = tls_conn.conn.complete_io(tls_conn.sock) {
|
|
||||||
error!("TLS handshake failure - {}:{}", e.kind(), e.to_string());
|
|
||||||
tls_conn.sock.shutdown(std::net::Shutdown::Both).expect("stream shutdown failure");
|
|
||||||
return Err(Box::new(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
let wstring = "Hello Rust!";
|
let wstring = "Hello Rust!";
|
||||||
let wsize = match tls_conn.write(wstring.as_bytes()) {
|
let wsize = match tls_conn.write(wstring.as_bytes()) {
|
||||||
Ok(size) => size,
|
Ok(size) => size,
|
||||||
|
130
src/main.rs
130
src/main.rs
@ -2,7 +2,6 @@ extern crate pretty_env_logger;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use rustls::server::danger::ClientCertVerifier;
|
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read, Write};
|
use std::io::{BufReader, Read, Write};
|
||||||
@ -12,15 +11,12 @@ use std::sync::Arc;
|
|||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version = "1.0")]
|
#[command(version = "1.0")]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// fullchain certificate name. format PEM
|
|
||||||
#[arg(short, long, value_name = "Certificate")]
|
#[arg(short, long, value_name = "Certificate")]
|
||||||
|
/// fullchain certificate name. format PEM
|
||||||
cert: String,
|
cert: String,
|
||||||
/// server privateKey name. format PEM
|
|
||||||
#[arg(short, long, value_name = "PrivateKey")]
|
#[arg(short, long, value_name = "PrivateKey")]
|
||||||
|
/// server privateKey name. format PEM
|
||||||
key: String,
|
key: String,
|
||||||
/// mTLS Mode
|
|
||||||
#[arg(short = 'm')]
|
|
||||||
mtls: Option<bool>,
|
|
||||||
/// set log level
|
/// set log level
|
||||||
#[arg(short, long, value_name = "Log Level", value_enum)]
|
#[arg(short, long, value_name = "Log Level", value_enum)]
|
||||||
level: Option<Level>,
|
level: Option<Level>,
|
||||||
@ -56,6 +52,12 @@ impl Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum KeyPath {
|
||||||
|
Cert = 0,
|
||||||
|
Pkey = 1,
|
||||||
|
}
|
||||||
|
|
||||||
fn initialize_log(options: &Cli) {
|
fn initialize_log(options: &Cli) {
|
||||||
let level = match options.level {
|
let level = match options.level {
|
||||||
Some(level) => level.to_level_filter(),
|
Some(level) => level.to_level_filter(),
|
||||||
@ -86,119 +88,39 @@ fn initialize_log(options: &Cli) {
|
|||||||
info!("Hi -");
|
info!("Hi -");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
fn parse_args() -> Vec<String> {
|
||||||
struct CliCertVerifier;
|
|
||||||
// {
|
|
||||||
|
|
||||||
// supported: Arc<crypto::CryptoProvider>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl CliCertVerifier {
|
|
||||||
// fn new(roots: Arc<RootCertStore>) -> Self {
|
|
||||||
// Self {
|
|
||||||
// supported : Arc::clone(crypto::CryptoProvider::get_default_or_install_from_crate_features()),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl ClientCertVerifier for CliCertVerifier {
|
|
||||||
fn offer_client_auth(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn client_auth_mandatory(&self) -> bool {
|
|
||||||
self.offer_client_auth()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn root_hint_subjects(&self) -> &[rustls::DistinguishedName] {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_client_cert(
|
|
||||||
&self,
|
|
||||||
_end_entity: &rustls::pki_types::CertificateDer<'_>,
|
|
||||||
_intermediates: &[rustls::pki_types::CertificateDer<'_>],
|
|
||||||
_now: rustls::pki_types::UnixTime,
|
|
||||||
) -> Result<rustls::server::danger::ClientCertVerified, rustls::Error> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_tls12_signature(
|
|
||||||
&self,
|
|
||||||
_message: &[u8],
|
|
||||||
_cert: &rustls::pki_types::CertificateDer<'_>,
|
|
||||||
_dss: &rustls::DigitallySignedStruct,
|
|
||||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
|
||||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_tls13_signature(
|
|
||||||
&self,
|
|
||||||
_message: &[u8],
|
|
||||||
_cert: &rustls::pki_types::CertificateDer<'_>,
|
|
||||||
_dss: &rustls::DigitallySignedStruct,
|
|
||||||
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
|
||||||
Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
|
|
||||||
// NOTE: This should be in priority order, with the most preferred first.
|
|
||||||
// enum에서 복사 했기 때문에 우선순위가 반영되어있지 않음
|
|
||||||
vec![
|
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA1,
|
|
||||||
rustls::SignatureScheme::ECDSA_SHA1_Legacy,
|
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA256,
|
|
||||||
rustls::SignatureScheme::ECDSA_NISTP256_SHA256,
|
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA384,
|
|
||||||
rustls::SignatureScheme::ECDSA_NISTP384_SHA384,
|
|
||||||
rustls::SignatureScheme::RSA_PKCS1_SHA512,
|
|
||||||
rustls::SignatureScheme::ECDSA_NISTP521_SHA512,
|
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA256,
|
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA384,
|
|
||||||
rustls::SignatureScheme::RSA_PSS_SHA512,
|
|
||||||
rustls::SignatureScheme::ED25519,
|
|
||||||
rustls::SignatureScheme::ED448,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn StdError>> {
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
initialize_log(&cli);
|
initialize_log(&cli);
|
||||||
|
|
||||||
let certs = rustls_pemfile::certs(&mut BufReader::new(&mut File::open(cli.cert)?))
|
vec![cli.cert.clone(), cli.key.clone()]
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
}
|
||||||
let private_key =
|
|
||||||
rustls_pemfile::private_key(&mut BufReader::new(&mut File::open(cli.key)?))?.unwrap();
|
|
||||||
|
|
||||||
let use_mtls = match cli.mtls {
|
fn main() -> Result<(), Box<dyn StdError>> {
|
||||||
Some(mtls) => mtls,
|
let key_path = parse_args();
|
||||||
None => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let config = if use_mtls {
|
let certs = rustls_pemfile::certs(&mut BufReader::new(&mut File::open(
|
||||||
rustls::ServerConfig::builder()
|
&key_path[KeyPath::Cert as usize][0..],
|
||||||
.with_client_cert_verifier(Arc::new(CliCertVerifier))
|
)?))
|
||||||
} else {
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
rustls::ServerConfig::builder()
|
let private_key = rustls_pemfile::private_key(&mut BufReader::new(&mut File::open(
|
||||||
.with_no_client_auth()
|
&key_path[KeyPath::Pkey as usize][0..],
|
||||||
}.with_single_cert(certs, private_key)?;
|
)?))?
|
||||||
|
.unwrap();
|
||||||
|
let config = rustls::ServerConfig::builder()
|
||||||
|
.with_no_client_auth()
|
||||||
|
.with_single_cert(certs, private_key)?;
|
||||||
|
|
||||||
let listener = TcpListener::bind(format!("[::]:{}", 10080)).unwrap();
|
let listener = TcpListener::bind(format!("[::]:{}", 10080)).unwrap();
|
||||||
trace!("Bound TCP Server");
|
trace!("Bound TCP Server");
|
||||||
|
|
||||||
let mut rbuf = [0u8; 1024 * 64]; // 64kb
|
let mut rbuf = [0u8; 1024 * 64]; // 64kb
|
||||||
for r_tcp in listener.incoming() {
|
for r_tcp in listener.incoming() {
|
||||||
debug!("wait Client");
|
|
||||||
let mut stream = r_tcp.expect("Accept Failure");
|
let mut stream = r_tcp.expect("Accept Failure");
|
||||||
stream.set_nodelay(true).expect("Set no delay Failure");
|
stream.set_nodelay(true).expect("Set no delay Failure");
|
||||||
let mut tls_conn =
|
let mut tls_conn =
|
||||||
rustls::ServerConnection::new(Arc::new(config.clone())).expect("TLS Server Error");
|
rustls::ServerConnection::new(Arc::new(config.clone())).expect("TLS Server Error");
|
||||||
if let Err(e) = tls_conn.complete_io(&mut stream) {
|
tls_conn.complete_io(&mut stream)?;
|
||||||
error!("TLS handshake failure - {}:{}", e.kind(), e.to_string());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
debug!("handshake done!?");
|
debug!("handshake done!?");
|
||||||
|
|
||||||
let rsize = match tls_conn.reader().read(&mut rbuf) {
|
let rsize = match tls_conn.reader().read(&mut rbuf) {
|
||||||
@ -217,7 +139,7 @@ fn main() -> Result<(), Box<dyn StdError>> {
|
|||||||
.writer()
|
.writer()
|
||||||
.write_fmt(format_args!("Echo, Client say: {}", utf8string))?;
|
.write_fmt(format_args!("Echo, Client say: {}", utf8string))?;
|
||||||
debug!("Send Data");
|
debug!("Send Data");
|
||||||
tls_conn.complete_io(&mut stream).expect("Send Flush Error");
|
tls_conn.complete_io(&mut stream)?;
|
||||||
// -> drop tls_conn
|
// -> drop tls_conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user