Skip to content

Commit 50740ad

Browse files
authored
Merge branch 'master' into ring-0.17
2 parents 531c8af + 795cd4d commit 50740ad

File tree

3 files changed

+74
-20
lines changed

3 files changed

+74
-20
lines changed

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ readme = "README.md"
1111
[dependencies]
1212
futures = { version = "0.3", default-features = false }
1313
ring = { version = "0.17", default-features = false }
14-
rustls = { version = "0.21", default-features = false }
14+
rustls = { version = "0.22.1", default-features = false }
1515
tokio = { version = "1", default-features = false }
1616
tokio-postgres = { version = "0.7", default-features = false }
17-
tokio-rustls = { version = "0.24", default-features = false }
17+
tokio-rustls = { version = "0.25", default-features = false }
18+
x509-certificate = {version = "0.21.0", default-features = false }
1819

1920
[dev-dependencies]
2021
env_logger = { version = "0.8", default-features = false }
2122
tokio = { version = "1", features = ["macros", "rt"] }
2223
tokio-postgres = "0.7"
23-
rustls = { version = "0.21", features = ["dangerous_configuration"] }
24+
rustls = { version = "0.22" }

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ and the [tokio-postgres asynchronous PostgreSQL client library](https://github.c
1010

1111
```
1212
let config = rustls::ClientConfig::builder()
13-
.with_safe_defaults()
1413
.with_root_certificates(rustls::RootCertStore::empty())
1514
.with_no_client_auth();
1615
let tls = tokio_postgres_rustls::MakeRustlsConnect::new(config);

src/lib.rs

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ use std::{
66
sync::Arc,
77
task::{Context, Poll},
88
};
9+
use DigestAlgorithm::{Sha1, Sha256, Sha384, Sha512};
910

1011
use futures::future::{FutureExt, TryFutureExt};
1112
use ring::digest;
12-
use rustls::{ClientConfig, ServerName};
13+
use rustls::ClientConfig;
14+
use rustls::pki_types::ServerName;
1315
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
1416
use tokio_postgres::tls::{ChannelBinding, MakeTlsConnect, TlsConnect};
1517
use 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)]
1824
pub struct MakeRustlsConnect {
@@ -39,7 +45,7 @@ where
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
})
@@ -50,7 +56,7 @@ where
5056
pub struct RustlsConnect(Option<RustlsConnectData>);
5157

5258
struct 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
130152
mod 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

Comments
 (0)