From 917afee741840ee490723f970ece86a2593f663e Mon Sep 17 00:00:00 2001 From: tottoto Date: Sat, 29 Jun 2024 19:24:09 +0900 Subject: [PATCH 1/3] chore(tls): Refactor parsing Certificate --- tonic/src/transport/channel/service/tls.rs | 5 ++-- tonic/src/transport/server/service/tls.rs | 6 ++--- tonic/src/transport/service/tls.rs | 28 ++++++++-------------- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/tonic/src/transport/channel/service/tls.rs b/tonic/src/transport/channel/service/tls.rs index 656e9fb31..09f0b0bd5 100644 --- a/tonic/src/transport/channel/service/tls.rs +++ b/tonic/src/transport/channel/service/tls.rs @@ -1,5 +1,4 @@ use std::fmt; -use std::io::Cursor; use std::sync::Arc; use hyper_util::rt::TokioIo; @@ -13,7 +12,7 @@ use tokio_rustls::{ }; use super::io::BoxedIo; -use crate::transport::service::tls::{add_certs_from_pem, load_identity, TlsError, ALPN_H2}; +use crate::transport::service::tls::{load_identity, TlsError, ALPN_H2}; use crate::transport::tls::{Certificate, Identity}; #[derive(Clone)] @@ -55,7 +54,7 @@ impl TlsConnector { } for cert in ca_certs { - add_certs_from_pem(&mut Cursor::new(cert), &mut roots)?; + roots.add_parsable_certificates(cert.parse()?); } let builder = builder.with_root_certificates(roots); diff --git a/tonic/src/transport/server/service/tls.rs b/tonic/src/transport/server/service/tls.rs index d69a6a46b..f813cbcfd 100644 --- a/tonic/src/transport/server/service/tls.rs +++ b/tonic/src/transport/server/service/tls.rs @@ -1,4 +1,4 @@ -use std::{fmt, io::Cursor, sync::Arc}; +use std::{fmt, sync::Arc}; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_rustls::{ @@ -8,7 +8,7 @@ use tokio_rustls::{ }; use crate::transport::{ - service::tls::{add_certs_from_pem, load_identity, ALPN_H2}, + service::tls::{load_identity, ALPN_H2}, Certificate, Identity, }; @@ -29,7 +29,7 @@ impl TlsAcceptor { None => builder.with_no_client_auth(), Some(cert) => { let mut roots = RootCertStore::empty(); - add_certs_from_pem(&mut Cursor::new(cert), &mut roots)?; + roots.add_parsable_certificates(cert.parse()?); let verifier = if client_auth_optional { WebPkiClientVerifier::builder(roots.into()).allow_unauthenticated() } else { diff --git a/tonic/src/transport/service/tls.rs b/tonic/src/transport/service/tls.rs index cdc2cf7ee..d10d02000 100644 --- a/tonic/src/transport/service/tls.rs +++ b/tonic/src/transport/service/tls.rs @@ -1,11 +1,8 @@ use std::{fmt, io::Cursor}; -use tokio_rustls::rustls::{ - pki_types::{CertificateDer, PrivateKeyDer}, - RootCertStore, -}; +use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer}; -use crate::transport::Identity; +use crate::transport::{Certificate, Identity}; /// h2 alpn in plain format for rustls. pub(crate) const ALPN_H2: &[u8] = b"h2"; @@ -38,6 +35,14 @@ impl fmt::Display for TlsError { impl std::error::Error for TlsError {} +impl Certificate { + pub(crate) fn parse(&self) -> Result>, TlsError> { + rustls_pemfile::certs(&mut Cursor::new(&self.pem)) + .collect::, _>>() + .map_err(|_| TlsError::CertificateParseError) + } +} + pub(crate) fn load_identity( identity: Identity, ) -> Result<(Vec>, PrivateKeyDer<'static>), TlsError> { @@ -51,16 +56,3 @@ pub(crate) fn load_identity( Ok((cert, key)) } - -pub(crate) fn add_certs_from_pem( - mut certs: &mut dyn std::io::BufRead, - roots: &mut RootCertStore, -) -> Result<(), crate::BoxError> { - for cert in rustls_pemfile::certs(&mut certs).collect::, _>>()? { - roots - .add(cert) - .map_err(|_| TlsError::CertificateParseError)?; - } - - Ok(()) -} From 2efa31833e06f42473edb1bb35cd7a910630c0f4 Mon Sep 17 00:00:00 2001 From: tottoto Date: Sat, 29 Jun 2024 19:24:26 +0900 Subject: [PATCH 2/3] chore(tls): Refactor parsing Identity --- tonic/src/transport/channel/service/tls.rs | 4 ++-- tonic/src/transport/server/service/tls.rs | 7 ++----- tonic/src/transport/service/tls.rs | 22 ++++++++++------------ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/tonic/src/transport/channel/service/tls.rs b/tonic/src/transport/channel/service/tls.rs index 09f0b0bd5..9149d62c3 100644 --- a/tonic/src/transport/channel/service/tls.rs +++ b/tonic/src/transport/channel/service/tls.rs @@ -12,7 +12,7 @@ use tokio_rustls::{ }; use super::io::BoxedIo; -use crate::transport::service::tls::{load_identity, TlsError, ALPN_H2}; +use crate::transport::service::tls::{TlsError, ALPN_H2}; use crate::transport::tls::{Certificate, Identity}; #[derive(Clone)] @@ -60,7 +60,7 @@ impl TlsConnector { let builder = builder.with_root_certificates(roots); let mut config = match identity { Some(identity) => { - let (client_cert, client_key) = load_identity(identity)?; + let (client_cert, client_key) = identity.parse()?; builder.with_client_auth_cert(client_cert, client_key)? } None => builder.with_no_client_auth(), diff --git a/tonic/src/transport/server/service/tls.rs b/tonic/src/transport/server/service/tls.rs index f813cbcfd..9b69194eb 100644 --- a/tonic/src/transport/server/service/tls.rs +++ b/tonic/src/transport/server/service/tls.rs @@ -7,10 +7,7 @@ use tokio_rustls::{ TlsAcceptor as RustlsAcceptor, }; -use crate::transport::{ - service::tls::{load_identity, ALPN_H2}, - Certificate, Identity, -}; +use crate::transport::{service::tls::ALPN_H2, Certificate, Identity}; #[derive(Clone)] pub(crate) struct TlsAcceptor { @@ -40,7 +37,7 @@ impl TlsAcceptor { } }; - let (cert, key) = load_identity(identity)?; + let (cert, key) = identity.parse()?; let mut config = builder.with_single_cert(cert, key)?; config.alpn_protocols.push(ALPN_H2.into()); diff --git a/tonic/src/transport/service/tls.rs b/tonic/src/transport/service/tls.rs index d10d02000..7e9172b9e 100644 --- a/tonic/src/transport/service/tls.rs +++ b/tonic/src/transport/service/tls.rs @@ -43,16 +43,14 @@ impl Certificate { } } -pub(crate) fn load_identity( - identity: Identity, -) -> Result<(Vec>, PrivateKeyDer<'static>), TlsError> { - let cert = rustls_pemfile::certs(&mut Cursor::new(identity.cert)) - .collect::, _>>() - .map_err(|_| TlsError::CertificateParseError)?; - - let Ok(Some(key)) = rustls_pemfile::private_key(&mut Cursor::new(identity.key)) else { - return Err(TlsError::PrivateKeyParseError); - }; - - Ok((cert, key)) +impl Identity { + pub(crate) fn parse( + &self, + ) -> Result<(Vec>, PrivateKeyDer<'static>), TlsError> { + let cert = self.cert.parse()?; + let Ok(Some(key)) = rustls_pemfile::private_key(&mut Cursor::new(&self.key)) else { + return Err(TlsError::PrivateKeyParseError); + }; + Ok((cert, key)) + } } From 335e1a901120cd21362395ecd85111d2cefb1f11 Mon Sep 17 00:00:00 2001 From: tottoto Date: Thu, 4 Jul 2024 01:14:36 +0900 Subject: [PATCH 3/3] chore(tls): Change method to convert certificate and identity to rustls-pki-types type to independent function --- tonic/src/transport/channel/service/tls.rs | 8 +++--- tonic/src/transport/server/service/tls.rs | 9 ++++--- tonic/src/transport/service/tls.rs | 30 ++++++++++------------ 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/tonic/src/transport/channel/service/tls.rs b/tonic/src/transport/channel/service/tls.rs index 9149d62c3..629a4fe26 100644 --- a/tonic/src/transport/channel/service/tls.rs +++ b/tonic/src/transport/channel/service/tls.rs @@ -12,7 +12,9 @@ use tokio_rustls::{ }; use super::io::BoxedIo; -use crate::transport::service::tls::{TlsError, ALPN_H2}; +use crate::transport::service::tls::{ + convert_certificate_to_pki_types, convert_identity_to_pki_types, TlsError, ALPN_H2, +}; use crate::transport::tls::{Certificate, Identity}; #[derive(Clone)] @@ -54,13 +56,13 @@ impl TlsConnector { } for cert in ca_certs { - roots.add_parsable_certificates(cert.parse()?); + roots.add_parsable_certificates(convert_certificate_to_pki_types(&cert)?); } let builder = builder.with_root_certificates(roots); let mut config = match identity { Some(identity) => { - let (client_cert, client_key) = identity.parse()?; + let (client_cert, client_key) = convert_identity_to_pki_types(&identity)?; builder.with_client_auth_cert(client_cert, client_key)? } None => builder.with_no_client_auth(), diff --git a/tonic/src/transport/server/service/tls.rs b/tonic/src/transport/server/service/tls.rs index 9b69194eb..395d5132b 100644 --- a/tonic/src/transport/server/service/tls.rs +++ b/tonic/src/transport/server/service/tls.rs @@ -7,7 +7,10 @@ use tokio_rustls::{ TlsAcceptor as RustlsAcceptor, }; -use crate::transport::{service::tls::ALPN_H2, Certificate, Identity}; +use crate::transport::{ + service::tls::{convert_certificate_to_pki_types, convert_identity_to_pki_types, ALPN_H2}, + Certificate, Identity, +}; #[derive(Clone)] pub(crate) struct TlsAcceptor { @@ -26,7 +29,7 @@ impl TlsAcceptor { None => builder.with_no_client_auth(), Some(cert) => { let mut roots = RootCertStore::empty(); - roots.add_parsable_certificates(cert.parse()?); + roots.add_parsable_certificates(convert_certificate_to_pki_types(&cert)?); let verifier = if client_auth_optional { WebPkiClientVerifier::builder(roots.into()).allow_unauthenticated() } else { @@ -37,7 +40,7 @@ impl TlsAcceptor { } }; - let (cert, key) = identity.parse()?; + let (cert, key) = convert_identity_to_pki_types(&identity)?; let mut config = builder.with_single_cert(cert, key)?; config.alpn_protocols.push(ALPN_H2.into()); diff --git a/tonic/src/transport/service/tls.rs b/tonic/src/transport/service/tls.rs index 7e9172b9e..1b0c1c458 100644 --- a/tonic/src/transport/service/tls.rs +++ b/tonic/src/transport/service/tls.rs @@ -35,22 +35,20 @@ impl fmt::Display for TlsError { impl std::error::Error for TlsError {} -impl Certificate { - pub(crate) fn parse(&self) -> Result>, TlsError> { - rustls_pemfile::certs(&mut Cursor::new(&self.pem)) - .collect::, _>>() - .map_err(|_| TlsError::CertificateParseError) - } +pub(crate) fn convert_certificate_to_pki_types( + certificate: &Certificate, +) -> Result>, TlsError> { + rustls_pemfile::certs(&mut Cursor::new(certificate)) + .collect::, _>>() + .map_err(|_| TlsError::CertificateParseError) } -impl Identity { - pub(crate) fn parse( - &self, - ) -> Result<(Vec>, PrivateKeyDer<'static>), TlsError> { - let cert = self.cert.parse()?; - let Ok(Some(key)) = rustls_pemfile::private_key(&mut Cursor::new(&self.key)) else { - return Err(TlsError::PrivateKeyParseError); - }; - Ok((cert, key)) - } +pub(crate) fn convert_identity_to_pki_types( + identity: &Identity, +) -> Result<(Vec>, PrivateKeyDer<'static>), TlsError> { + let cert = convert_certificate_to_pki_types(&identity.cert)?; + let Ok(Some(key)) = rustls_pemfile::private_key(&mut Cursor::new(&identity.key)) else { + return Err(TlsError::PrivateKeyParseError); + }; + Ok((cert, key)) }