Begin implementing client certificate validator
This commit is contained in:
parent
8dcd8455d4
commit
8cc3c13389
6 changed files with 48 additions and 8 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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},
|
||||||
|
|
Loading…
Add table
Reference in a new issue