1+ use std:: collections:: HashMap ;
12use std:: ptr;
23use std:: sync:: Arc ;
34
@@ -13,13 +14,26 @@ use crate::evp_pkey::{
1314 ecdsa_sha256, ecdsa_sha384, ecdsa_sha512, ed25519, rsa_pkcs1_sha256, rsa_pkcs1_sha384,
1415 rsa_pkcs1_sha512, rsa_pss_sha256, rsa_pss_sha384, rsa_pss_sha512, EvpPkey , EvpScheme ,
1516} ;
16- use crate :: x509:: OwnedX509Stack ;
17+ use crate :: x509:: { OwnedX509 , OwnedX509Stack } ;
1718
1819/// This matches up to the implied state machine in `SSL_CTX_use_certificate_chain_file`
1920/// and `SSL_CTX_use_PrivateKey_file`, and matching man pages.
2021#[ derive( Clone , Default , Debug ) ]
2122pub struct CertifiedKeySet {
22- item : KeySetItem ,
23+ by_algorithm : HashMap < u8 , KeySetItem > ,
24+
25+ /// The algorithm of the most-recently altered item.
26+ last_algorithm : Option < SignatureAlgorithm > ,
27+
28+ /// The most-recently provided cert chain tail.
29+ ///
30+ /// Because a cert chain tail does not contain its end-entity cert,
31+ /// we can't determine which algorithm it is for until we see the
32+ /// end-entity cert.
33+ ///
34+ /// This is used only if `last_algorithm` does not record the right
35+ /// slot in `by_algorithm`.
36+ pending_cert_chain_tail : Option < Vec < CertificateDer < ' static > > > ,
2337}
2438
2539impl CertifiedKeySet {
@@ -47,54 +61,76 @@ impl CertifiedKeySet {
4761 & mut self ,
4862 chain : Vec < CertificateDer < ' static > > ,
4963 ) -> Result < ( ) , error:: Error > {
50- self . item . adopt_chain_tail ( Some ( chain) ) ;
51- Ok ( ( ) )
64+ if let Some ( alg) = self . last_algorithm {
65+ let item = self . item_mut ( alg) ;
66+ item. adopt_chain_tail ( Some ( chain) ) ;
67+ item. promote ( )
68+ } else {
69+ self . pending_cert_chain_tail = Some ( chain) ;
70+ Ok ( ( ) )
71+ }
5272 }
5373
5474 pub fn stage_certificate_end_entity (
5575 & mut self ,
5676 end : CertificateDer < ' static > ,
5777 ) -> Result < ( ) , error:: Error > {
58- self . item . cert_end_entity = Some ( end) ;
59- self . item . promote ( )
78+ let alg = OwnedX509 :: parse_der ( end. as_ref ( ) )
79+ . ok_or_else ( || error:: Error :: bad_data ( "cannot parse certificate" ) )
80+ . map ( |x509| x509. public_key ( ) . algorithm ( ) ) ?;
81+ self . last_algorithm = Some ( alg) ;
82+
83+ let tail = self . pending_cert_chain_tail . take ( ) ;
84+ let item = self . item_mut ( alg) ;
85+ item. adopt_chain_tail ( tail) ;
86+ item. cert_end_entity = Some ( end) ;
87+ item. promote ( )
6088 }
6189
6290 pub fn commit_private_key ( & mut self , key : EvpPkey ) -> Result < ( ) , error:: Error > {
63- self . item . key = Some ( key) ;
64- self . item . promote ( )
91+ let alg = key. algorithm ( ) ;
92+ self . last_algorithm = Some ( alg) ;
93+
94+ let tail = self . pending_cert_chain_tail . take ( ) ;
95+ let item = self . item_mut ( alg) ;
96+ item. adopt_chain_tail ( tail) ;
97+ item. key = Some ( key) ;
98+ item. promote ( )
6599 }
66100
67101 pub fn client_resolver ( & self ) -> Option < Arc < dyn ResolvesClientCert > > {
68- self . item
69- . constructed
70- . as_ref ( )
71- . map ( |ck| ck. client_resolver ( ) )
102+ Some ( Arc :: new ( ResolverByAlgorithm :: new ( & self . by_algorithm ) ) )
72103 }
73104
74105 pub fn server_resolver ( & self ) -> Option < Arc < dyn ResolvesServerCert > > {
75- self . item
76- . constructed
77- . as_ref ( )
78- . map ( |ck| ck. server_resolver ( ) )
106+ Some ( Arc :: new ( ResolverByAlgorithm :: new ( & self . by_algorithm ) ) )
79107 }
80108
81109 /// For `SSL_get_certificate`
82110 pub fn borrow_current_cert ( & self ) -> * mut X509 {
83- self . item
84- . constructed
85- . as_ref ( )
111+ self . last_algorithm
112+ . and_then ( |alg| self . item ( alg ) )
113+ . and_then ( |item| item . constructed . as_ref ( ) )
86114 . map ( |ck| ck. borrow_cert ( ) )
87115 . unwrap_or ( ptr:: null_mut ( ) )
88116 }
89117
90118 /// For `SSL_get_privatekey`
91119 pub fn borrow_current_key ( & self ) -> * mut EVP_PKEY {
92- self . item
93- . constructed
94- . as_ref ( )
120+ self . last_algorithm
121+ . and_then ( |alg| self . item ( alg ) )
122+ . and_then ( |item| item . constructed . as_ref ( ) )
95123 . map ( |ck| ck. borrow_key ( ) )
96124 . unwrap_or ( ptr:: null_mut ( ) )
97125 }
126+
127+ fn item ( & self , alg : SignatureAlgorithm ) -> Option < & KeySetItem > {
128+ self . by_algorithm . get ( & u8:: from ( alg) )
129+ }
130+
131+ fn item_mut ( & mut self , alg : SignatureAlgorithm ) -> & mut KeySetItem {
132+ self . by_algorithm . entry ( u8:: from ( alg) ) . or_default ( )
133+ }
98134}
99135
100136#[ derive( Clone , Debug , Default ) ]
@@ -187,45 +223,72 @@ impl OpenSslCertifiedKey {
187223 fn borrow_key ( & self ) -> * mut EVP_PKEY {
188224 self . key . borrow_ref ( )
189225 }
190-
191- fn client_resolver ( & self ) -> Arc < dyn ResolvesClientCert > {
192- Arc :: new ( AlwaysResolvesClientCert ( Arc :: new ( sign:: CertifiedKey :: new (
193- self . rustls_chain . clone ( ) ,
194- Arc :: new ( OpenSslKey ( self . key . clone ( ) ) ) ,
195- ) ) ) )
196- }
197-
198- fn server_resolver ( & self ) -> Arc < dyn ResolvesServerCert > {
199- Arc :: new ( AlwaysResolvesServerCert ( Arc :: new ( sign:: CertifiedKey :: new (
200- self . rustls_chain . clone ( ) ,
201- Arc :: new ( OpenSslKey ( self . key . clone ( ) ) ) ,
202- ) ) ) )
203- }
204226}
205227
206228#[ derive( Debug ) ]
207- struct AlwaysResolvesClientCert ( Arc < sign:: CertifiedKey > ) ;
229+ struct ResolverByAlgorithm ( HashMap < u8 , Arc < sign:: CertifiedKey > > ) ;
230+
231+ impl ResolverByAlgorithm {
232+ fn new ( by_algorithm : & HashMap < u8 , KeySetItem > ) -> Self {
233+ let mut keys = HashMap :: new ( ) ;
234+ for ( alg, item) in by_algorithm. iter ( ) {
235+ let Some ( constructed) = & item. constructed else {
236+ continue ;
237+ } ;
238+ keys. insert (
239+ * alg,
240+ Arc :: new ( sign:: CertifiedKey :: new (
241+ constructed. rustls_chain . clone ( ) ,
242+ Arc :: new ( OpenSslKey ( constructed. key . clone ( ) ) ) ,
243+ ) ) ,
244+ ) ;
245+ }
246+ Self ( keys)
247+ }
248+ }
208249
209- impl ResolvesClientCert for AlwaysResolvesClientCert {
250+ impl ResolvesClientCert for ResolverByAlgorithm {
210251 fn has_certs ( & self ) -> bool {
211- true
252+ ! self . 0 . is_empty ( )
212253 }
213254
214255 fn resolve (
215256 & self ,
216257 _root_hint_subjects : & [ & [ u8 ] ] ,
217- _schemes : & [ SignatureScheme ] ,
258+ schemes : & [ SignatureScheme ] ,
218259 ) -> Option < Arc < sign:: CertifiedKey > > {
219- Some ( Arc :: clone ( & self . 0 ) )
260+ for scheme in schemes {
261+ if let Some ( key) = self . 0 . get ( & u8:: from ( scheme_algorithm ( scheme) ) ) {
262+ return Some ( key. clone ( ) ) ;
263+ }
264+ }
265+ None
220266 }
221267}
222268
223- #[ derive( Debug ) ]
224- struct AlwaysResolvesServerCert ( Arc < sign:: CertifiedKey > ) ;
269+ impl ResolvesServerCert for ResolverByAlgorithm {
270+ fn resolve ( & self , client_hello : ClientHello ) -> Option < Arc < sign:: CertifiedKey > > {
271+ for scheme in client_hello. signature_schemes ( ) {
272+ if let Some ( key) = self . 0 . get ( & u8:: from ( scheme_algorithm ( scheme) ) ) {
273+ return Some ( key. clone ( ) ) ;
274+ }
275+ }
276+ None
277+ }
278+ }
225279
226- impl ResolvesServerCert for AlwaysResolvesServerCert {
227- fn resolve ( & self , _client_hello : ClientHello ) -> Option < Arc < sign:: CertifiedKey > > {
228- Some ( Arc :: clone ( & self . 0 ) )
280+ fn scheme_algorithm ( scheme : & SignatureScheme ) -> SignatureAlgorithm {
281+ use SignatureScheme :: * ;
282+ match * scheme {
283+ RSA_PKCS1_SHA1 | RSA_PKCS1_SHA256 | RSA_PKCS1_SHA384 | RSA_PKCS1_SHA512
284+ | RSA_PSS_SHA256 | RSA_PSS_SHA384 | RSA_PSS_SHA512 => SignatureAlgorithm :: RSA ,
285+ ECDSA_SHA1_Legacy
286+ | ECDSA_NISTP256_SHA256
287+ | ECDSA_NISTP384_SHA384
288+ | ECDSA_NISTP521_SHA512 => SignatureAlgorithm :: ECDSA ,
289+ ED25519 => SignatureAlgorithm :: ED25519 ,
290+ ED448 => SignatureAlgorithm :: ED448 ,
291+ _ => SignatureAlgorithm :: Unknown ( 0 ) ,
229292 }
230293}
231294
0 commit comments