114 lines
3.1 KiB
Rust
114 lines
3.1 KiB
Rust
use super::ResolvesClientCert;
|
|
#[cfg(feature = "logging")]
|
|
use crate::log::{debug, trace};
|
|
use crate::msgs::enums::ExtensionType;
|
|
use crate::msgs::handshake::CertificatePayload;
|
|
use crate::msgs::handshake::SCTList;
|
|
use crate::msgs::handshake::ServerExtension;
|
|
use crate::{sign, DistinguishedNames, SignatureScheme};
|
|
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Debug)]
|
|
pub(super) struct ServerCertDetails {
|
|
pub(super) cert_chain: CertificatePayload,
|
|
pub(super) ocsp_response: Vec<u8>,
|
|
pub(super) scts: Option<SCTList>,
|
|
}
|
|
|
|
impl ServerCertDetails {
|
|
pub(super) fn new(
|
|
cert_chain: CertificatePayload,
|
|
ocsp_response: Vec<u8>,
|
|
scts: Option<SCTList>,
|
|
) -> Self {
|
|
Self {
|
|
cert_chain,
|
|
ocsp_response,
|
|
scts,
|
|
}
|
|
}
|
|
|
|
pub(super) fn scts(&self) -> impl Iterator<Item = &[u8]> {
|
|
self.scts
|
|
.as_deref()
|
|
.unwrap_or(&[])
|
|
.iter()
|
|
.map(|payload| payload.0.as_slice())
|
|
}
|
|
}
|
|
|
|
pub(super) struct ClientHelloDetails {
|
|
pub(super) sent_extensions: Vec<ExtensionType>,
|
|
}
|
|
|
|
impl ClientHelloDetails {
|
|
pub(super) fn new() -> Self {
|
|
Self {
|
|
sent_extensions: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub(super) fn server_may_send_sct_list(&self) -> bool {
|
|
self.sent_extensions
|
|
.contains(&ExtensionType::SCT)
|
|
}
|
|
|
|
pub(super) fn server_sent_unsolicited_extensions(
|
|
&self,
|
|
received_exts: &[ServerExtension],
|
|
allowed_unsolicited: &[ExtensionType],
|
|
) -> bool {
|
|
for ext in received_exts {
|
|
let ext_type = ext.get_type();
|
|
if !self.sent_extensions.contains(&ext_type) && !allowed_unsolicited.contains(&ext_type)
|
|
{
|
|
trace!("Unsolicited extension {:?}", ext_type);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
}
|
|
|
|
pub(super) enum ClientAuthDetails {
|
|
/// Send an empty `Certificate` and no `CertificateVerify`.
|
|
Empty { auth_context_tls13: Option<Vec<u8>> },
|
|
/// Send a non-empty `Certificate` and a `CertificateVerify`.
|
|
Verify {
|
|
certkey: Arc<sign::CertifiedKey>,
|
|
signer: Box<dyn sign::Signer>,
|
|
auth_context_tls13: Option<Vec<u8>>,
|
|
},
|
|
}
|
|
|
|
impl ClientAuthDetails {
|
|
pub(super) fn resolve(
|
|
resolver: &dyn ResolvesClientCert,
|
|
canames: Option<&DistinguishedNames>,
|
|
sigschemes: &[SignatureScheme],
|
|
auth_context_tls13: Option<Vec<u8>>,
|
|
) -> Self {
|
|
let acceptable_issuers = canames
|
|
.map(Vec::as_slice)
|
|
.unwrap_or_default()
|
|
.iter()
|
|
.map(|p| p.0.as_slice())
|
|
.collect::<Vec<&[u8]>>();
|
|
|
|
if let Some(certkey) = resolver.resolve(&acceptable_issuers, sigschemes) {
|
|
if let Some(signer) = certkey.key.choose_scheme(sigschemes) {
|
|
debug!("Attempting client auth");
|
|
return Self::Verify {
|
|
certkey,
|
|
signer,
|
|
auth_context_tls13,
|
|
};
|
|
}
|
|
}
|
|
|
|
debug!("Client auth requested but no cert/sigscheme available");
|
|
Self::Empty { auth_context_tls13 }
|
|
}
|
|
}
|