1use super::ResolvesClientCert;
2#[cfg(feature = "logging")]
3use crate::log::{debug, trace};
4use crate::msgs::enums::ExtensionType;
5use crate::msgs::handshake::ServerExtension;
6use crate::msgs::handshake::{CertificateChain, DistinguishedName};
7use crate::{sign, SignatureScheme};
8
9use alloc::boxed::Box;
10use alloc::sync::Arc;
11use alloc::vec::Vec;
12
13#[derive(Debug)]
14pub(super) struct ServerCertDetails {
15 pub(super) cert_chain: CertificateChain,
16 pub(super) ocsp_response: Vec<u8>,
17}
18
19impl ServerCertDetails {
20 pub(super) fn new(cert_chain: CertificateChain, ocsp_response: Vec<u8>) -> Self {
21 Self {
22 cert_chain,
23 ocsp_response,
24 }
25 }
26}
27
28pub(super) struct ClientHelloDetails {
29 pub(super) sent_extensions: Vec<ExtensionType>,
30}
31
32impl ClientHelloDetails {
33 pub(super) fn new() -> Self {
34 Self {
35 sent_extensions: Vec::new(),
36 }
37 }
38
39 pub(super) fn server_sent_unsolicited_extensions(
40 &self,
41 received_exts: &[ServerExtension],
42 allowed_unsolicited: &[ExtensionType],
43 ) -> bool {
44 for ext: &ServerExtension in received_exts {
45 let ext_type: ExtensionType = ext.get_type();
46 if !self.sent_extensions.contains(&ext_type) && !allowed_unsolicited.contains(&ext_type)
47 {
48 trace!("Unsolicited extension {:?}", ext_type);
49 return true;
50 }
51 }
52
53 false
54 }
55}
56
57pub(super) enum ClientAuthDetails {
58 /// Send an empty `Certificate` and no `CertificateVerify`.
59 Empty { auth_context_tls13: Option<Vec<u8>> },
60 /// Send a non-empty `Certificate` and a `CertificateVerify`.
61 Verify {
62 certkey: Arc<sign::CertifiedKey>,
63 signer: Box<dyn sign::Signer>,
64 auth_context_tls13: Option<Vec<u8>>,
65 },
66}
67
68impl ClientAuthDetails {
69 pub(super) fn resolve(
70 resolver: &dyn ResolvesClientCert,
71 canames: Option<&[DistinguishedName]>,
72 sigschemes: &[SignatureScheme],
73 auth_context_tls13: Option<Vec<u8>>,
74 ) -> Self {
75 let acceptable_issuers = canames
76 .unwrap_or_default()
77 .iter()
78 .map(|p| p.as_ref())
79 .collect::<Vec<&[u8]>>();
80
81 if let Some(certkey) = resolver.resolve(&acceptable_issuers, sigschemes) {
82 if let Some(signer) = certkey.key.choose_scheme(sigschemes) {
83 debug!("Attempting client auth");
84 return Self::Verify {
85 certkey,
86 signer,
87 auth_context_tls13,
88 };
89 }
90 }
91
92 debug!("Client auth requested but no cert/sigscheme available");
93 Self::Empty { auth_context_tls13 }
94 }
95}
96