Skip to content

Commit

Permalink
Merge branch 'update-rustls-tls' of github.com:libp2p/rust-libp2p int…
Browse files Browse the repository at this point in the history
…o retrohacker/ring@0.17.8
  • Loading branch information
jxs committed May 14, 2024
2 parents d716602 + 3e7728c commit 5c3e4fe
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 33 deletions.
30 changes: 21 additions & 9 deletions transports/tls/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,22 @@ static P2P_SIGNATURE_ALGORITHM: &rcgen::SignatureAlgorithm = &rcgen::PKCS_ECDSA_
/// certificate extension containing the public key of the given keypair.
pub fn generate(
identity_keypair: &identity::Keypair,
) -> Result<(rustls::Certificate, rustls::PrivateKey), GenError> {
) -> Result<
(
rustls::pki_types::CertificateDer<'static>,
rustls::pki_types::PrivateKeyDer<'static>,
),
GenError,
> {
// Keypair used to sign the certificate.
// SHOULD NOT be related to the host's key.
// Endpoints MAY generate a new key and certificate
// for every connection attempt, or they MAY reuse the same key
// and certificate for multiple connections.
let certificate_keypair = rcgen::KeyPair::generate(P2P_SIGNATURE_ALGORITHM)?;
let rustls_key = rustls::PrivateKey(certificate_keypair.serialize_der());
let rustls_key = rustls::pki_types::PrivateKeyDer::from(
rustls::pki_types::PrivatePkcs8KeyDer::from(certificate_keypair.serialize_der()),
);

let certificate = {
let mut params = rcgen::CertificateParams::new(vec![]);
Expand All @@ -67,7 +75,7 @@ pub fn generate(
rcgen::Certificate::from_params(params)?
};

let rustls_certificate = rustls::Certificate(certificate.serialize_der()?);
let rustls_certificate = rustls::pki_types::CertificateDer::from(certificate.serialize_der()?);

Ok((rustls_certificate, rustls_key))
}
Expand All @@ -76,7 +84,9 @@ pub fn generate(
///
/// For this to succeed, the certificate must contain the specified extension and the signature must
/// match the embedded public key.
pub fn parse(certificate: &rustls::Certificate) -> Result<P2pCertificate<'_>, ParseError> {
pub fn parse<'a>(
certificate: &'a rustls::pki_types::CertificateDer<'a>,
) -> Result<P2pCertificate<'a>, ParseError> {
let certificate = parse_unverified(certificate.as_ref())?;

certificate.verify()?;
Expand Down Expand Up @@ -481,7 +491,9 @@ mod tests {

#[test]
fn rsa_pss_sha384() {
let cert = rustls::Certificate(include_bytes!("./test_assets/rsa_pss_sha384.der").to_vec());
let cert = rustls::pki_types::CertificateDer::from(
include_bytes!("./test_assets/rsa_pss_sha384.der").to_vec(),
);

let cert = parse(&cert).unwrap();

Expand All @@ -502,7 +514,7 @@ mod tests {

#[test]
fn can_parse_certificate_with_ed25519_keypair() {
let certificate = rustls::Certificate(hex!("308201773082011ea003020102020900f5bd0debaa597f52300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d030107034200046bf9871220d71dcb3483ecdfcbfcc7c103f8509d0974b3c18ab1f1be1302d643103a08f7a7722c1b247ba3876fe2c59e26526f479d7718a85202ddbe47562358a37f307d307b060a2b0601040183a25a01010101ff046a30680424080112207fda21856709c5ae12fd6e8450623f15f11955d384212b89f56e7e136d2e17280440aaa6bffabe91b6f30c35e3aa4f94b1188fed96b0ffdd393f4c58c1c047854120e674ce64c788406d1c2c4b116581fd7411b309881c3c7f20b46e54c7e6fe7f0f300a06082a8648ce3d040302034700304402207d1a1dbd2bda235ff2ec87daf006f9b04ba076a5a5530180cd9c2e8f6399e09d0220458527178c7e77024601dbb1b256593e9b96d961b96349d1f560114f61a87595").to_vec());
let certificate = rustls::pki_types::CertificateDer::from(hex!("308201773082011ea003020102020900f5bd0debaa597f52300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d030107034200046bf9871220d71dcb3483ecdfcbfcc7c103f8509d0974b3c18ab1f1be1302d643103a08f7a7722c1b247ba3876fe2c59e26526f479d7718a85202ddbe47562358a37f307d307b060a2b0601040183a25a01010101ff046a30680424080112207fda21856709c5ae12fd6e8450623f15f11955d384212b89f56e7e136d2e17280440aaa6bffabe91b6f30c35e3aa4f94b1188fed96b0ffdd393f4c58c1c047854120e674ce64c788406d1c2c4b116581fd7411b309881c3c7f20b46e54c7e6fe7f0f300a06082a8648ce3d040302034700304402207d1a1dbd2bda235ff2ec87daf006f9b04ba076a5a5530180cd9c2e8f6399e09d0220458527178c7e77024601dbb1b256593e9b96d961b96349d1f560114f61a87595").to_vec());

let peer_id = parse(&certificate).unwrap().peer_id();

Expand All @@ -516,7 +528,7 @@ mod tests {

#[test]
fn fails_to_parse_bad_certificate_with_ed25519_keypair() {
let certificate = rustls::Certificate(hex!("308201773082011da003020102020830a73c5d896a1109300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004bbe62df9a7c1c46b7f1f21d556deec5382a36df146fb29c7f1240e60d7d5328570e3b71d99602b77a65c9b3655f62837f8d66b59f1763b8c9beba3be07778043a37f307d307b060a2b0601040183a25a01010101ff046a3068042408011220ec8094573afb9728088860864f7bcea2d4fd412fef09a8e2d24d482377c20db60440ecabae8354afa2f0af4b8d2ad871e865cb5a7c0c8d3dbdbf42de577f92461a0ebb0a28703e33581af7d2a4f2270fc37aec6261fcc95f8af08f3f4806581c730a300a06082a8648ce3d040302034800304502202dfb17a6fa0f94ee0e2e6a3b9fb6e986f311dee27392058016464bd130930a61022100ba4b937a11c8d3172b81e7cd04aedb79b978c4379c2b5b24d565dd5d67d3cb3c").to_vec());
let certificate = rustls::pki_types::CertificateDer::from(hex!("308201773082011da003020102020830a73c5d896a1109300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004bbe62df9a7c1c46b7f1f21d556deec5382a36df146fb29c7f1240e60d7d5328570e3b71d99602b77a65c9b3655f62837f8d66b59f1763b8c9beba3be07778043a37f307d307b060a2b0601040183a25a01010101ff046a3068042408011220ec8094573afb9728088860864f7bcea2d4fd412fef09a8e2d24d482377c20db60440ecabae8354afa2f0af4b8d2ad871e865cb5a7c0c8d3dbdbf42de577f92461a0ebb0a28703e33581af7d2a4f2270fc37aec6261fcc95f8af08f3f4806581c730a300a06082a8648ce3d040302034800304502202dfb17a6fa0f94ee0e2e6a3b9fb6e986f311dee27392058016464bd130930a61022100ba4b937a11c8d3172b81e7cd04aedb79b978c4379c2b5b24d565dd5d67d3cb3c").to_vec());

let error = parse(&certificate).unwrap_err();

Expand All @@ -525,7 +537,7 @@ mod tests {

#[test]
fn can_parse_certificate_with_ecdsa_keypair() {
let certificate = rustls::Certificate(hex!("308201c030820166a003020102020900eaf419a6e3edb4a6300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d030107034200048dbf1116c7c608d6d5292bd826c3feb53483a89fce434bf64538a359c8e07538ff71f6766239be6a146dcc1a5f3bb934bcd4ae2ae1d4da28ac68b4a20593f06ba381c63081c33081c0060a2b0601040183a25a01010101ff0481ae3081ab045f0803125b3059301306072a8648ce3d020106082a8648ce3d0301070342000484b93fa456a74bd0153919f036db7bc63c802f055bc7023395d0203de718ee0fc7b570b767cdd858aca6c7c4113ff002e78bd2138ac1a3b26dde3519e06979ad04483046022100bc84014cea5a41feabdf4c161096564b9ccf4b62fbef4fe1cd382c84e11101780221009204f086a84cb8ed8a9ddd7868dc90c792ee434adf62c66f99a08a5eba11615b300a06082a8648ce3d0403020348003045022054b437be9a2edf591312d68ff24bf91367ad4143f76cf80b5658f232ade820da022100e23b48de9df9c25d4c83ddddf75d2676f0b9318ee2a6c88a736d85eab94a912f").to_vec());
let certificate = rustls::pki_types::CertificateDer::from(hex!("308201c030820166a003020102020900eaf419a6e3edb4a6300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d030107034200048dbf1116c7c608d6d5292bd826c3feb53483a89fce434bf64538a359c8e07538ff71f6766239be6a146dcc1a5f3bb934bcd4ae2ae1d4da28ac68b4a20593f06ba381c63081c33081c0060a2b0601040183a25a01010101ff0481ae3081ab045f0803125b3059301306072a8648ce3d020106082a8648ce3d0301070342000484b93fa456a74bd0153919f036db7bc63c802f055bc7023395d0203de718ee0fc7b570b767cdd858aca6c7c4113ff002e78bd2138ac1a3b26dde3519e06979ad04483046022100bc84014cea5a41feabdf4c161096564b9ccf4b62fbef4fe1cd382c84e11101780221009204f086a84cb8ed8a9ddd7868dc90c792ee434adf62c66f99a08a5eba11615b300a06082a8648ce3d0403020348003045022054b437be9a2edf591312d68ff24bf91367ad4143f76cf80b5658f232ade820da022100e23b48de9df9c25d4c83ddddf75d2676f0b9318ee2a6c88a736d85eab94a912f").to_vec());

let peer_id = parse(&certificate).unwrap().peer_id();

Expand All @@ -539,7 +551,7 @@ mod tests {

#[test]
fn can_parse_certificate_with_secp256k1_keypair() {
let certificate = rustls::Certificate(hex!("3082018230820128a003020102020900f3b305f55622cfdf300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000458f7e9581748ff9bdd933b655cc0e5552a1248f840658cc221dec2186b5a2fe4641b86ab7590a3422cdbb1000cf97662f27e5910d7569f22feed8829c8b52e0fa38188308185308182060a2b0601040183a25a01010101ff0471306f042508021221026b053094d1112bce799dc8026040ae6d4eb574157929f1598172061f753d9b1b04463044022040712707e97794c478d93989aaa28ae1f71c03af524a8a4bd2d98424948a782302207b61b7f074b696a25fb9e0059141a811cccc4cc28042d9301b9b2a4015e87470300a06082a8648ce3d04030203480030450220143ae4d86fdc8675d2480bb6912eca5e39165df7f572d836aa2f2d6acfab13f8022100831d1979a98f0c4a6fb5069ca374de92f1a1205c962a6d90ad3d7554cb7d9df4").to_vec());
let certificate = rustls::pki_types::CertificateDer::from(hex!("3082018230820128a003020102020900f3b305f55622cfdf300a06082a8648ce3d04030230003020170d3735303130313030303030305a180f34303936303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000458f7e9581748ff9bdd933b655cc0e5552a1248f840658cc221dec2186b5a2fe4641b86ab7590a3422cdbb1000cf97662f27e5910d7569f22feed8829c8b52e0fa38188308185308182060a2b0601040183a25a01010101ff0471306f042508021221026b053094d1112bce799dc8026040ae6d4eb574157929f1598172061f753d9b1b04463044022040712707e97794c478d93989aaa28ae1f71c03af524a8a4bd2d98424948a782302207b61b7f074b696a25fb9e0059141a811cccc4cc28042d9301b9b2a4015e87470300a06082a8648ce3d04030203480030450220143ae4d86fdc8675d2480bb6912eca5e39165df7f572d836aa2f2d6acfab13f8022100831d1979a98f0c4a6fb5069ca374de92f1a1205c962a6d90ad3d7554cb7d9df4").to_vec());

let peer_id = parse(&certificate).unwrap().peer_id();

Expand Down
7 changes: 5 additions & 2 deletions transports/tls/src/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use libp2p_core::upgrade::{InboundConnectionUpgrade, OutboundConnectionUpgrade};
use libp2p_core::UpgradeInfo;
use libp2p_identity as identity;
use libp2p_identity::PeerId;
use rustls::{CommonState, ServerName};
use rustls::{pki_types::ServerName, CommonState};

use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;

Expand Down Expand Up @@ -103,7 +104,9 @@ where
async move {
// Spec: In order to keep this flexibility for future versions, clients that only support the version of the handshake defined in this document MUST NOT send any value in the Server Name Indication.
// Setting `ServerName` to unspecified will disable the use of the SNI extension.
let name = ServerName::IpAddress(IpAddr::V4(Ipv4Addr::UNSPECIFIED));
let name = ServerName::IpAddress(rustls::pki_types::IpAddr::from(IpAddr::V4(
Ipv4Addr::UNSPECIFIED,
)));

let stream = futures_rustls::TlsConnector::from(Arc::new(self.client))
.connect(name, socket)
Expand Down
49 changes: 27 additions & 22 deletions transports/tls/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
use crate::certificate;
use libp2p_identity::PeerId;
use rustls::{
cipher_suite::{
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
crypto::ring::cipher_suite::{
TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256,
},
client::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
server::{ClientCertVerified, ClientCertVerifier},
Certificate, CertificateError, DigitallySignedStruct, DistinguishedName, SignatureScheme,
pki_types::CertificateDer,
server::danger::{ClientCertVerified, ClientCertVerifier},
CertificateError, DigitallySignedStruct, DistinguishedName, OtherError, SignatureScheme,
SupportedCipherSuite, SupportedProtocolVersion,
};
use std::sync::Arc;
Expand All @@ -56,6 +57,7 @@ pub(crate) static CIPHERSUITES: &[SupportedCipherSuite] = &[
/// Implementation of the `rustls` certificate verification traits for libp2p.
///
/// Only TLS 1.3 is supported. TLS 1.2 should be disabled in the configuration of `rustls`.
#[derive(Debug)]
pub(crate) struct Libp2pCertificateVerifier {
/// The peer ID we intend to connect to
remote_peer_id: Option<PeerId>,
Expand Down Expand Up @@ -103,12 +105,11 @@ impl Libp2pCertificateVerifier {
impl ServerCertVerifier for Libp2pCertificateVerifier {
fn verify_server_cert(
&self,
end_entity: &Certificate,
intermediates: &[Certificate],
_server_name: &rustls::ServerName,
_scts: &mut dyn Iterator<Item = &[u8]>,
end_entity: &CertificateDer,
intermediates: &[CertificateDer],
_server_name: &rustls::pki_types::ServerName,
_ocsp_response: &[u8],
_now: std::time::SystemTime,
_now: rustls::pki_types::UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
let peer_id = verify_presented_certs(end_entity, intermediates)?;

Expand All @@ -130,7 +131,7 @@ impl ServerCertVerifier for Libp2pCertificateVerifier {
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &Certificate,
_cert: &CertificateDer,
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
unreachable!("`PROTOCOL_VERSIONS` only allows TLS 1.3")
Expand All @@ -139,7 +140,7 @@ impl ServerCertVerifier for Libp2pCertificateVerifier {
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &Certificate,
cert: &CertificateDer,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls13_signature(cert, dss.scheme, message, dss.signature())
Expand All @@ -162,15 +163,15 @@ impl ClientCertVerifier for Libp2pCertificateVerifier {
true
}

fn client_auth_root_subjects(&self) -> &[DistinguishedName] {
fn root_hint_subjects(&self) -> &[DistinguishedName] {
&[]
}

fn verify_client_cert(
&self,
end_entity: &Certificate,
intermediates: &[Certificate],
_now: std::time::SystemTime,
end_entity: &CertificateDer,
intermediates: &[CertificateDer],
_now: rustls::pki_types::UnixTime,
) -> Result<ClientCertVerified, rustls::Error> {
verify_presented_certs(end_entity, intermediates)?;

Expand All @@ -180,7 +181,7 @@ impl ClientCertVerifier for Libp2pCertificateVerifier {
fn verify_tls12_signature(
&self,
_message: &[u8],
_cert: &Certificate,
_cert: &CertificateDer,
_dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
unreachable!("`PROTOCOL_VERSIONS` only allows TLS 1.3")
Expand All @@ -189,7 +190,7 @@ impl ClientCertVerifier for Libp2pCertificateVerifier {
fn verify_tls13_signature(
&self,
message: &[u8],
cert: &Certificate,
cert: &CertificateDer,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, rustls::Error> {
verify_tls13_signature(cert, dss.scheme, message, dss.signature())
Expand All @@ -207,8 +208,8 @@ impl ClientCertVerifier for Libp2pCertificateVerifier {
/// Endpoints MUST abort the connection attempt if more than one certificate is received,
/// or if the certificate’s self-signature is not valid.
fn verify_presented_certs(
end_entity: &Certificate,
intermediates: &[Certificate],
end_entity: &CertificateDer,
intermediates: &[CertificateDer],
) -> Result<PeerId, rustls::Error> {
if !intermediates.is_empty() {
return Err(rustls::Error::General(
Expand All @@ -222,7 +223,7 @@ fn verify_presented_certs(
}

fn verify_tls13_signature(
cert: &Certificate,
cert: &CertificateDer,
signature_scheme: SignatureScheme,
message: &[u8],
signature: &[u8],
Expand All @@ -237,7 +238,9 @@ impl From<certificate::ParseError> for rustls::Error {
use webpki::Error::*;
match e {
BadDer => rustls::Error::InvalidCertificate(CertificateError::BadEncoding),
e => rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(e))),
e => {
rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(Arc::new(e))))
}
}
}
}
Expand All @@ -248,7 +251,9 @@ impl From<certificate::VerificationError> for rustls::Error {
InvalidSignatureForPublicKey => {
rustls::Error::InvalidCertificate(CertificateError::BadSignature)
}
other => rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(other))),
other => rustls::Error::InvalidCertificate(CertificateError::Other(OtherError(
Arc::new(other),
))),
}
}
}

0 comments on commit 5c3e4fe

Please sign in to comment.