Begin implementing client certificate validator

This commit is contained in:
Nathan Fisher 2023-08-18 19:01:14 -04:00
parent 8dcd8455d4
commit 8cc3c13389
6 changed files with 48 additions and 8 deletions

View file

@ -40,7 +40,8 @@ impl Connection {
if store.has_mailuser(&request.recipient.to_string()) { if store.has_mailuser(&request.recipient.to_string()) {
let id = Id::new()?; let id = Id::new()?;
let msg = MessageParser::new(&id.to_string()).parse(&request.message)?; let msg = MessageParser::new(&id.to_string()).parse(&request.message)?;
store.add_message(&request.recipient.to_string(), "Inbox", msg) store
.add_message(&request.recipient.to_string(), "Inbox", msg)
.map_err(|e| Error::Storage(e.to_string()))?; .map_err(|e| Error::Storage(e.to_string()))?;
true true
} else { } else {

View file

@ -1,6 +1,7 @@
use crate::mailuser::Mailuser; use crate::{fingerprint::GetFingerprint, mailuser::Mailuser};
use rustls::server::{ClientCertVerified, ClientCertVerifier}; use rustls::server::{ClientCertVerified, ClientCertVerifier};
use std::sync::Mutex; use std::{sync::{Arc, Mutex}, io::Read};
use x509_parser::prelude::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Verifier<S: FingerPrintStore> { pub struct Verifier<S: FingerPrintStore> {
@ -24,6 +25,23 @@ impl<S: FingerPrintStore> ClientCertVerifier for Verifier<S> {
intermediates: &[rustls::Certificate], intermediates: &[rustls::Certificate],
now: std::time::SystemTime, now: std::time::SystemTime,
) -> Result<ClientCertVerified, rustls::Error> { ) -> Result<ClientCertVerified, rustls::Error> {
let fingerprint = end_entity.fingerprint()?;
if let Ok(store) = self.store.lock() {
if let Some(user) = store.get_mailuser(&fingerprint.fingerprint) {
let (_, pk) = X509Certificate::from_der(end_entity.as_ref()).map_err(|e| {
rustls::Error::InvalidCertificate(rustls::CertificateError::Other(Arc::new(e)))
})?;
let subject = pk.subject();
let mut name_match = false;
subject.iter_common_name().for_each(|n| {
let mut val = n.attr_value().data;
let mut name = String::new();
if val.read_to_string(&mut name).is_ok() {
name_match = name == user.to_string();
}
});
}
}
todo!() todo!()
} }
} }

View file

@ -1,4 +1,7 @@
use {std::fmt, x509_parser::prelude::X509Error}; use {
std::{fmt, sync::Arc},
x509_parser::prelude::X509Error,
};
#[derive(Debug)] #[derive(Debug)]
/// Errors which can occur when fingerprinting a certificate /// Errors which can occur when fingerprinting a certificate
@ -38,3 +41,15 @@ impl From<x509_parser::nom::Err<x509_parser::error::X509Error>> for Error {
Self::X509(value.into()) Self::X509(value.into())
} }
} }
impl From<Error> for rustls::Error {
fn from(value: Error) -> Self {
match value {
Error::Fmt => Self::General(String::from("Format Error")),
Error::InvalidForDate => Self::InvalidCertificate(rustls::CertificateError::Expired),
Error::X509(e) => {
Self::InvalidCertificate(rustls::CertificateError::Other(Arc::new(e)))
}
}
}
}

View file

@ -1,7 +1,6 @@
use { use {
std::{ std::{
error, error, fmt,
fmt,
fs::File, fs::File,
io::{self, Read}, io::{self, Read},
time::{SystemTime, SystemTimeError, UNIX_EPOCH}, time::{SystemTime, SystemTimeError, UNIX_EPOCH},

View file

@ -9,7 +9,12 @@ mod error;
mod id; mod id;
mod link; mod link;
mod parser; mod parser;
pub use {error::Error, id::{Error as IdError, Id}, link::Link, parser::Parser}; pub use {
error::Error,
id::{Error as IdError, Id},
link::Link,
parser::Parser,
};
#[derive(Clone, Debug, Default, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
pub struct Recipients { pub struct Recipients {

View file

@ -6,7 +6,9 @@ pub use super::{
mailbox::{Error as ParseMailboxError, Mailbox}, mailbox::{Error as ParseMailboxError, Mailbox},
mailstore::{Account, Domain, Filesystem, FilesystemError, Folder, MailStore}, mailstore::{Account, Domain, Filesystem, FilesystemError, Folder, MailStore},
mailuser::Mailuser, mailuser::Mailuser,
message::{Error as ParseMessageError, Id, IdError, Link, Message, Parser as MessageParser, Recipients}, message::{
Error as ParseMessageError, Id, IdError, Link, Message, Parser as MessageParser, Recipients,
},
//receiver, //receiver,
request::{Error as ParseRequestError, Request}, request::{Error as ParseRequestError, Request},
response::{Error as ParseResponseError, Response}, response::{Error as ParseResponseError, Response},