@@ -6,6 +6,7 @@ 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;
@@ -14,6 +15,10 @@ use rustls::pki_types::ServerName;
1415use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
1516use tokio_postgres:: tls:: { ChannelBinding , MakeTlsConnect , TlsConnect } ;
1617use 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+ } ;
1722
1823#[ derive( Clone ) ]
1924pub struct MakeRustlsConnect {
@@ -84,10 +89,26 @@ where
8489 fn channel_binding ( & self ) -> ChannelBinding {
8590 let ( _, session) = self . 0 . get_ref ( ) ;
8691 match session. peer_certificates ( ) {
87- Some ( certs) if !certs. is_empty ( ) => {
88- let sha256 = digest:: digest ( & digest:: SHA256 , certs[ 0 ] . as_ref ( ) ) ;
89- ChannelBinding :: tls_server_end_point ( sha256. as_ref ( ) . into ( ) )
90- }
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 ( ) ) ,
91112 _ => ChannelBinding :: none ( ) ,
92113 }
93114 }
0 commit comments