From 183c652b0576b55f8cc602206180d8d19308ae15 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Fri, 16 Jul 2021 18:41:07 +0300 Subject: [PATCH] More docs --- transports/tls-quic/src/verifier.rs | 35 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/transports/tls-quic/src/verifier.rs b/transports/tls-quic/src/verifier.rs index 0dacc506cb75..c91a071e0bc5 100644 --- a/transports/tls-quic/src/verifier.rs +++ b/transports/tls-quic/src/verifier.rs @@ -20,9 +20,9 @@ use rustls::{ internal::msgs::handshake::DigitallySignedStruct, - internal::msgs::enums::SignatureScheme, - Certificate, ClientCertVerified, - HandshakeSignatureValid, ServerCertVerified, TLSError, + Certificate, ClientCertVerified, DistinguishedNames, + HandshakeSignatureValid, RootCertStore, ServerCertVerified, + SignatureScheme, TLSError, }; /// Implementation of the `rustls` certificate verification traits for libp2p. @@ -42,6 +42,9 @@ impl Libp2pCertificateVerifier { SignatureScheme::ECDSA_NISTP256_SHA256, // TODO SignatureScheme::ED448 is not supported by `ring` yet SignatureScheme::ED25519, + + // In particular, RSA SHOULD NOT be used unless + // no elliptic curve algorithms are supported. SignatureScheme::RSA_PSS_SHA512, SignatureScheme::RSA_PSS_SHA384, SignatureScheme::RSA_PSS_SHA256, @@ -55,11 +58,11 @@ impl Libp2pCertificateVerifier { impl rustls::ServerCertVerifier for Libp2pCertificateVerifier { fn verify_server_cert( &self, - _roots: &rustls::RootCertStore, - presented_certs: &[rustls::Certificate], + _roots: &RootCertStore, + presented_certs: &[Certificate], _dns_name: webpki::DNSNameRef<'_>, _ocsp_response: &[u8], - ) -> Result { + ) -> Result { verify_certs(presented_certs).map(|_| ServerCertVerified::assertion()) } @@ -69,6 +72,8 @@ impl rustls::ServerCertVerifier for Libp2pCertificateVerifier { _cert: &Certificate, _dss: &DigitallySignedStruct, ) -> Result { + // The libp2p handshake uses TLS 1.3 (and higher). + // Endpoints MUST NOT negotiate lower TLS versions. Err(TLSError::PeerIncompatibleError("Only TLS 1.3 certificates are supported".to_string())) } @@ -94,7 +99,7 @@ impl rustls::ClientCertVerifier for Libp2pCertificateVerifier { fn client_auth_root_subjects( &self, _dns_name: Option<&webpki::DNSName>, - ) -> Option { + ) -> Option { Some(vec![]) } @@ -102,7 +107,7 @@ impl rustls::ClientCertVerifier for Libp2pCertificateVerifier { &self, presented_certs: &[Certificate], _dns_name: Option<&webpki::DNSName>, - ) -> Result { + ) -> Result { verify_certs(presented_certs).map(|_| ClientCertVerified::assertion()) } @@ -112,6 +117,8 @@ impl rustls::ClientCertVerifier for Libp2pCertificateVerifier { _cert: &Certificate, _dss: &DigitallySignedStruct, ) -> Result { + // The libp2p handshake uses TLS 1.3 (and higher). + // Endpoints MUST NOT negotiate lower TLS versions. Err(TLSError::PeerIncompatibleError("Only TLS 1.3 certificates are supported".to_string())) } @@ -129,7 +136,13 @@ impl rustls::ClientCertVerifier for Libp2pCertificateVerifier { } } -fn verify_certs(presented_certs: &[Certificate]) -> Result<(), rustls::TLSError> { +/// When receiving the certificate chain, an endpoint +/// MUST check these conditions and abort the connection attempt if +/// (a) the presented certificate is not yet valid, OR +/// (b) if it is expired. +/// 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_certs(presented_certs: &[Certificate]) -> Result<(), TLSError> { if presented_certs.len() != 1 { return Err(TLSError::NoCertificatesPresented); } @@ -145,14 +158,14 @@ fn verify_certs(presented_certs: &[Certificate]) -> Result<(), rustls::TLSError> fn verify_tls13_signature( cert: &Certificate, - signature_scheme: rustls::SignatureScheme, + signature_scheme: SignatureScheme, message: &[u8], signature: &[u8], ) -> Result { let certificate = crate::certificate::parse_certificate(cert.as_ref()) .map_err(|_| TLSError::CorruptMessage)?; if certificate.verify_signature(signature_scheme, message, signature) { - Ok(rustls::HandshakeSignatureValid::assertion()) + Ok(HandshakeSignatureValid::assertion()) } else { Err(TLSError::CorruptMessage) }