Add certificates
- Refactor `Recipient` out of `MailContext`. - Add lookup of authenticated certificates for recipients.
This commit is contained in:
@@ -19,6 +19,7 @@ log4rs = "1.3.0"
|
|||||||
sequoia-cert-store = "0.7.1"
|
sequoia-cert-store = "0.7.1"
|
||||||
sequoia-directories = "0.1.0"
|
sequoia-directories = "0.1.0"
|
||||||
sequoia-openpgp = "2.1.0"
|
sequoia-openpgp = "2.1.0"
|
||||||
|
sequoia-wot = "0.15.0"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_derive = "1.0.228"
|
serde_derive = "1.0.228"
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
|
|||||||
+38
-1
@@ -4,12 +4,18 @@
|
|||||||
// cryptographic functions
|
// cryptographic functions
|
||||||
//
|
//
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow;
|
use anyhow;
|
||||||
use sequoia_openpgp::parse::Parse;
|
use sequoia_openpgp::parse::Parse;
|
||||||
use sequoia_openpgp::{Fingerprint, Cert};
|
use sequoia_openpgp::{Fingerprint, Cert};
|
||||||
use sequoia_openpgp::cert::raw::RawCertParser;
|
use sequoia_openpgp::cert::raw::RawCertParser;
|
||||||
use sequoia_cert_store::CertStore;
|
use sequoia_cert_store::{Store, CertStore, LazyCert};
|
||||||
|
use sequoia_wot::{self as wot};
|
||||||
|
use wot::store::Store as _;
|
||||||
|
|
||||||
use crate::types::errors::HuskError;
|
use crate::types::errors::HuskError;
|
||||||
|
use crate::types::husk_context::HuskContext;
|
||||||
|
|
||||||
pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result<Cert> {
|
pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result<Cert> {
|
||||||
|
|
||||||
@@ -45,3 +51,34 @@ pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result<Cert> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_certificates<'hc>(context: &HuskContext<'hc>, email: &str)
|
||||||
|
-> Vec<Arc<LazyCert<'hc>>> {
|
||||||
|
|
||||||
|
let cert_store = &context.cert_store;
|
||||||
|
let trust_roots = vec![(context.local_trust_root.fingerprint(), wot::FULLY_TRUSTED)];
|
||||||
|
let wot_store = wot::store::CertStore::from_store(cert_store, &context.policy, None);
|
||||||
|
let nb = wot::NetworkBuilder::rooted(&wot_store, &*trust_roots);
|
||||||
|
let n = nb.build();
|
||||||
|
|
||||||
|
let bindings: Vec<_> = n.lookup_synopses_by_email(email)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(fp, userid)| (fp, Some(userid)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut result = vec![];
|
||||||
|
for (fpr, some_userid) in bindings {
|
||||||
|
if let Some(userid) = some_userid {
|
||||||
|
let paths = n.authenticate(userid, &fpr, wot::FULLY_TRUSTED);
|
||||||
|
if paths.len() > 0 {
|
||||||
|
log::debug!("authenticated!!!");
|
||||||
|
for (path, _) in paths.iter() {
|
||||||
|
if let Ok(cert) = cert_store.lookup_by_cert_fpr(&path.target().fingerprint()) {
|
||||||
|
result.push(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ impl<'hc> HuskContext<'hc> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_recipient(&mut self, rcpt: String) -> anyhow::Result<()> {
|
pub fn add_recipient(&mut self, rcpt: String) -> anyhow::Result<()> {
|
||||||
self.mail.add_recipient(rcpt)
|
|
||||||
|
let certs = crypto::get_certificates(&self, rcpt.as_str());
|
||||||
|
|
||||||
|
self.mail.add_recipient(rcpt, certs)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,34 +4,20 @@
|
|||||||
// Mail Context
|
// Mail Context
|
||||||
//
|
//
|
||||||
|
|
||||||
use anyhow;
|
use std::sync::Arc;
|
||||||
|
use sequoia_cert_store::LazyCert;
|
||||||
|
|
||||||
use sequoia_openpgp::cert::ValidCert;
|
use crate::types::recipient::Recipient;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub struct MailContext<'mc> {
|
||||||
pub struct Recipient<'r> {
|
|
||||||
pub email: String,
|
|
||||||
pub cert: Option<ValidCert<'r>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for Recipient<'_> {
|
|
||||||
fn from(email: String) -> Self {
|
|
||||||
Recipient {
|
|
||||||
email: email,
|
|
||||||
cert: None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MailContext<'c> {
|
|
||||||
pub sender: Option<String>,
|
pub sender: Option<String>,
|
||||||
pub recipients: Vec<Recipient<'c>>,
|
pub recipients: Vec<Recipient<'mc>>,
|
||||||
// header
|
// header
|
||||||
// body
|
// body
|
||||||
// body size
|
// body size
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MailContext<'_> {
|
impl<'mc> MailContext<'mc> {
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
MailContext {
|
MailContext {
|
||||||
@@ -44,8 +30,9 @@ impl MailContext<'_> {
|
|||||||
self.sender = Some(sender);
|
self.sender = Some(sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_recipient(&mut self, rcpt: String) -> anyhow::Result<()> {
|
pub fn add_recipient(&mut self, rcpt: String, certs: Vec<Arc<LazyCert<'mc>>>) -> anyhow::Result<()> {
|
||||||
let recipient: Recipient = rcpt.into();
|
let mut recipient: Recipient = rcpt.into();
|
||||||
|
recipient.certs = certs;
|
||||||
|
|
||||||
self.recipients.push(recipient);
|
self.recipients.push(recipient);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod husk_context;
|
pub mod husk_context;
|
||||||
pub mod mail_context;
|
pub mod mail_context;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
|
pub mod recipient;
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Husk milter
|
||||||
|
//
|
||||||
|
// Recipient
|
||||||
|
//
|
||||||
|
|
||||||
|
use anyhow;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::ffi::CString;
|
||||||
|
use sequoia_cert_store::LazyCert;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Recipient<'r> {
|
||||||
|
pub email: String,
|
||||||
|
pub certs: Vec<Arc<LazyCert<'r>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Recipient<'_> {
|
||||||
|
fn from(email: String) -> Self {
|
||||||
|
Recipient {
|
||||||
|
email: email,
|
||||||
|
certs: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<CString> for Recipient<'_> {
|
||||||
|
|
||||||
|
type Error=anyhow::Error;
|
||||||
|
|
||||||
|
fn try_from(value: CString) -> Result<Self, Self::Error> {
|
||||||
|
match value.into_string() {
|
||||||
|
Ok(s) => Ok(s.into()),
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user