@@ -6,13 +6,19 @@ use std::{
66 sync:: Arc ,
77 task:: { Context , Poll } ,
88} ;
9+ use DigestAlgorithm :: { Sha1 , Sha256 , Sha384 , Sha512 } ;
910
1011use futures:: future:: { FutureExt , TryFutureExt } ;
1112use ring:: digest;
12- use rustls:: { ClientConfig , ServerName } ;
13+ use rustls:: ClientConfig ;
14+ use rustls:: pki_types:: ServerName ;
1315use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
1416use tokio_postgres:: tls:: { ChannelBinding , MakeTlsConnect , TlsConnect } ;
1517use tokio_rustls:: { client:: TlsStream , TlsConnector } ;
18+ use x509_certificate:: { algorithm, DigestAlgorithm , SignatureAlgorithm , X509Certificate } ;
19+ use SignatureAlgorithm :: {
20+ EcdsaSha256 , EcdsaSha384 , Ed25519 , NoSignature , RsaSha1 , RsaSha256 , RsaSha384 , RsaSha512 ,
21+ } ;
1622
1723#[ derive( Clone ) ]
1824pub struct MakeRustlsConnect {
3945 ServerName :: try_from ( hostname)
4046 . map ( |dns_name| {
4147 RustlsConnect ( Some ( RustlsConnectData {
42- hostname : dns_name,
48+ hostname : dns_name. to_owned ( ) ,
4349 connector : Arc :: clone ( & self . config ) . into ( ) ,
4450 } ) )
4551 } )
5056pub struct RustlsConnect ( Option < RustlsConnectData > ) ;
5157
5258struct RustlsConnectData {
53- hostname : ServerName ,
59+ hostname : ServerName < ' static > ,
5460 connector : TlsConnector ,
5561}
5662
@@ -83,10 +89,26 @@ where
8389 fn channel_binding ( & self ) -> ChannelBinding {
8490 let ( _, session) = self . 0 . get_ref ( ) ;
8591 match session. peer_certificates ( ) {
86- Some ( certs) if !certs. is_empty ( ) => {
87- let sha256 = digest:: digest ( & digest:: SHA256 , certs[ 0 ] . as_ref ( ) ) ;
88- ChannelBinding :: tls_server_end_point ( sha256. as_ref ( ) . into ( ) )
89- }
92+ Some ( certs) if !certs. is_empty ( ) => X509Certificate :: from_der ( & certs[ 0 ] )
93+ . ok ( )
94+ . and_then ( |cert| cert. signature_algorithm ( ) )
95+ . map ( |algorithm| match algorithm {
96+ // Note: SHA1 is upgraded to SHA256 as per https://datatracker.ietf.org/doc/html/rfc5929#section-4.1
97+ RsaSha1 | RsaSha256 | EcdsaSha256 => & digest:: SHA256 ,
98+ RsaSha384 | EcdsaSha384 => & digest:: SHA384 ,
99+ RsaSha512 => & digest:: SHA512 ,
100+ Ed25519 => & digest:: SHA512 ,
101+ NoSignature ( algo) => match algo {
102+ Sha1 | Sha256 => & digest:: SHA256 ,
103+ Sha384 => & digest:: SHA384 ,
104+ Sha512 => & digest:: SHA512 ,
105+ } ,
106+ } )
107+ . map ( |algorithm| {
108+ let hash = digest:: digest ( algorithm, certs[ 0 ] . as_ref ( ) ) ;
109+ ChannelBinding :: tls_server_end_point ( hash. as_ref ( ) . into ( ) )
110+ } )
111+ . unwrap_or ( ChannelBinding :: none ( ) ) ,
90112 _ => ChannelBinding :: none ( ) ,
91113 }
92114 }
@@ -130,30 +152,62 @@ where
130152mod tests {
131153 use super :: * ;
132154 use futures:: future:: TryFutureExt ;
133- use rustls:: { client:: ServerCertVerified , client:: ServerCertVerifier , Certificate , Error } ;
134- use std:: time:: SystemTime ;
135-
155+ use rustls:: {
156+ client:: danger:: ServerCertVerifier ,
157+ client:: danger:: { HandshakeSignatureValid , ServerCertVerified } ,
158+ Error , SignatureScheme ,
159+ } ;
160+ use rustls:: pki_types:: { CertificateDer , UnixTime } ;
161+
162+ #[ derive( Debug ) ]
136163 struct AcceptAllVerifier { }
137164 impl ServerCertVerifier for AcceptAllVerifier {
138165 fn verify_server_cert (
139166 & self ,
140- _end_entity : & Certificate ,
141- _intermediates : & [ Certificate ] ,
142- _server_name : & ServerName ,
143- _scts : & mut dyn Iterator < Item = & [ u8 ] > ,
167+ _end_entity : & CertificateDer < ' _ > ,
168+ _intermediates : & [ CertificateDer < ' _ > ] ,
169+ _server_name : & ServerName < ' _ > ,
144170 _ocsp_response : & [ u8 ] ,
145- _now : SystemTime ,
171+ _now : UnixTime ,
146172 ) -> Result < ServerCertVerified , Error > {
147173 Ok ( ServerCertVerified :: assertion ( ) )
148174 }
175+
176+ fn verify_tls12_signature (
177+ & self ,
178+ _message : & [ u8 ] ,
179+ _cert : & CertificateDer < ' _ > ,
180+ _dss : & rustls:: DigitallySignedStruct ,
181+ ) -> Result < rustls:: client:: danger:: HandshakeSignatureValid , Error > {
182+ Ok ( HandshakeSignatureValid :: assertion ( ) )
183+ }
184+
185+ fn verify_tls13_signature (
186+ & self ,
187+ _message : & [ u8 ] ,
188+ _cert : & CertificateDer < ' _ > ,
189+ _dss : & rustls:: DigitallySignedStruct ,
190+ ) -> Result < rustls:: client:: danger:: HandshakeSignatureValid , Error > {
191+ Ok ( HandshakeSignatureValid :: assertion ( ) )
192+ }
193+
194+ fn supported_verify_schemes ( & self ) -> Vec < SignatureScheme > {
195+ vec ! [
196+ SignatureScheme :: ECDSA_NISTP384_SHA384 ,
197+ SignatureScheme :: ECDSA_NISTP256_SHA256 ,
198+ SignatureScheme :: RSA_PSS_SHA512 ,
199+ SignatureScheme :: RSA_PSS_SHA384 ,
200+ SignatureScheme :: RSA_PSS_SHA256 ,
201+ SignatureScheme :: ED25519 ,
202+ ]
203+ }
149204 }
150205
151206 #[ tokio:: test]
152207 async fn it_works ( ) {
153208 env_logger:: builder ( ) . is_test ( true ) . try_init ( ) . unwrap ( ) ;
154209
155210 let mut config = rustls:: ClientConfig :: builder ( )
156- . with_safe_defaults ( )
157211 . with_root_certificates ( rustls:: RootCertStore :: empty ( ) )
158212 . with_no_client_auth ( ) ;
159213 config
0 commit comments