initial commit
This commit is contained in:
81
src/certificate_resolver.rs
Normal file
81
src/certificate_resolver.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
use rustls::{server::{ResolvesServerCert, ClientHello}, sign::{CertifiedKey, SigningKey, Signer as TLSSigner}, SignatureScheme, SignatureAlgorithm};
|
||||
use rustls_pki_types::CertificateDer;
|
||||
use std::{sync::Arc, fs, io::BufReader};
|
||||
use ed25519_dalek::Signer;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CertificateResolver {
|
||||
cert_filename: String,
|
||||
key: [u8; 32]
|
||||
}
|
||||
|
||||
impl CertificateResolver {
|
||||
pub fn new(cert_filename: String, key: [u8; 32]) -> Self {
|
||||
Self {
|
||||
cert_filename,
|
||||
key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResolvesServerCert for CertificateResolver {
|
||||
fn resolve(&self, client_hello: ClientHello) -> Option<Arc<CertifiedKey>> {
|
||||
if !client_hello.signature_schemes().contains(&SignatureScheme::ED25519) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let certfile = fs::File::open(self.cert_filename.as_str()).unwrap();
|
||||
let mut reader = BufReader::new(certfile);
|
||||
let cert: CertificateDer = rustls_pemfile::certs(&mut reader).unwrap().first().ok_or(()).unwrap().to_owned().into();
|
||||
|
||||
Some(Arc::new(CertifiedKey {
|
||||
cert: vec![cert],
|
||||
key: Arc::new(Ed25519Key{
|
||||
key: self.key
|
||||
}),
|
||||
ocsp: None
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Ed25519Key {
|
||||
key: [u8; 32]
|
||||
}
|
||||
|
||||
impl SigningKey for Ed25519Key {
|
||||
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn TLSSigner>> {
|
||||
if offered.contains(&SignatureScheme::ED25519) {
|
||||
Some(Box::new(Ed25519Signer::new(&self.key)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn algorithm(&self) -> SignatureAlgorithm {
|
||||
SignatureAlgorithm::ED25519
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Ed25519Signer {
|
||||
key: ed25519_dalek::SigningKey
|
||||
}
|
||||
|
||||
impl Ed25519Signer {
|
||||
fn new(key: &[u8; 32]) -> Self {
|
||||
Self {
|
||||
key: ed25519_dalek::SigningKey::from_bytes(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TLSSigner for Ed25519Signer {
|
||||
fn scheme(&self) -> SignatureScheme {
|
||||
SignatureScheme::ED25519
|
||||
}
|
||||
|
||||
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, rustls::Error> {
|
||||
Ok(self.key.sign(message).to_vec())
|
||||
}
|
||||
}
|
||||
59
src/main.rs
Normal file
59
src/main.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
mod certificate_resolver;
|
||||
|
||||
use std::{error::Error, io::Write};
|
||||
use std::net::TcpListener;
|
||||
use std::sync::Arc;
|
||||
use rustls::server::{ServerConfig, Acceptor};
|
||||
use certificate_resolver::CertificateResolver;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::init();
|
||||
|
||||
let ed25519_key = [67, 172, 227, 162, 104, 7, 219, 85, 140, 212, 238, 223, 8, 206, 63, 0, 91, 20, 173, 188, 82, 207, 110, 235, 3, 55, 237, 2, 25, 65, 40, 186];
|
||||
|
||||
let cert_resolver = Arc::new(CertificateResolver::new("./ed25519.crt".to_string(), ed25519_key));
|
||||
|
||||
let config = Arc::new(ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_cert_resolver(cert_resolver));
|
||||
|
||||
|
||||
let listener = TcpListener::bind("127.0.0.1:1337").unwrap();
|
||||
|
||||
for stream in listener.incoming() {
|
||||
let mut stream = stream.unwrap();
|
||||
let mut acceptor = Acceptor::default();
|
||||
|
||||
// Read TLS packets until we've consumed a full client hello and are ready to accept a
|
||||
// connection.
|
||||
let accepted = loop {
|
||||
acceptor.read_tls(&mut stream).unwrap();
|
||||
if let Some(accepted) = acceptor.accept().unwrap() {
|
||||
break accepted;
|
||||
}
|
||||
};
|
||||
|
||||
let mut conn = accepted.into_connection(config.clone())?;
|
||||
|
||||
// Proceed with handling the ServerConnection
|
||||
// Important: We do no error handling here, but you should!
|
||||
_ = conn.complete_io(&mut stream);
|
||||
|
||||
// let mut buf: Vec<u8> = Vec::new();
|
||||
// conn.reader().read_to_end(&mut buf).unwrap();
|
||||
// println!("{:?}", buf);
|
||||
|
||||
let mut writer = conn.writer();
|
||||
|
||||
writer.write_all("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nIt works!!!".as_bytes())?;
|
||||
writer.flush()?;
|
||||
|
||||
conn.write_tls(&mut stream).unwrap();
|
||||
_ = conn.complete_io(&mut stream);
|
||||
conn.send_close_notify();
|
||||
_ = conn.complete_io(&mut stream);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user