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