initial commit

This commit is contained in:
2024-10-14 15:40:03 +02:00
commit 6aba35b15a
7 changed files with 791 additions and 0 deletions

View 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
View 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(())
}