Skip to content

Commit

Permalink
chore(tls): Refactor parsing certificate and identity (#1763)
Browse files Browse the repository at this point in the history
* chore(tls): Refactor parsing Certificate

* chore(tls): Refactor parsing Identity

* chore(tls): Change method to convert certificate and identity to rustls-pki-types type to independent function
  • Loading branch information
tottoto authored Nov 5, 2024
1 parent fe66c8c commit 8def0bb
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 33 deletions.
9 changes: 5 additions & 4 deletions tonic/src/transport/channel/service/tls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fmt;
use std::io::Cursor;
use std::sync::Arc;

use hyper_util::rt::TokioIo;
Expand All @@ -13,7 +12,9 @@ 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::{
convert_certificate_to_pki_types, convert_identity_to_pki_types, TlsError, ALPN_H2,
};
use crate::transport::tls::{Certificate, Identity};

#[derive(Clone)]
Expand Down Expand Up @@ -55,13 +56,13 @@ impl TlsConnector {
}

for cert in ca_certs {
add_certs_from_pem(&mut Cursor::new(cert), &mut roots)?;
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) = load_identity(identity)?;
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(),
Expand Down
8 changes: 4 additions & 4 deletions tonic/src/transport/server/service/tls.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fmt, io::Cursor, sync::Arc};
use std::{fmt, sync::Arc};

use tokio::io::{AsyncRead, AsyncWrite};
use tokio_rustls::{
Expand All @@ -8,7 +8,7 @@ use tokio_rustls::{
};

use crate::transport::{
service::tls::{add_certs_from_pem, load_identity, ALPN_H2},
service::tls::{convert_certificate_to_pki_types, convert_identity_to_pki_types, ALPN_H2},
Certificate, Identity,
};

Expand All @@ -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(convert_certificate_to_pki_types(&cert)?);
let verifier = if client_auth_optional {
WebPkiClientVerifier::builder(roots.into()).allow_unauthenticated()
} else {
Expand All @@ -40,7 +40,7 @@ impl TlsAcceptor {
}
};

let (cert, key) = load_identity(identity)?;
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());
Expand Down
38 changes: 13 additions & 25 deletions tonic/src/transport/service/tls.rs
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -38,29 +35,20 @@ impl fmt::Display for TlsError {

impl std::error::Error for TlsError {}

pub(crate) fn load_identity(
identity: Identity,
) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>), TlsError> {
let cert = rustls_pemfile::certs(&mut Cursor::new(identity.cert))
pub(crate) fn convert_certificate_to_pki_types(
certificate: &Certificate,
) -> Result<Vec<CertificateDer<'static>>, TlsError> {
rustls_pemfile::certs(&mut Cursor::new(certificate))
.collect::<Result<Vec<_>, _>>()
.map_err(|_| TlsError::CertificateParseError)?;
.map_err(|_| TlsError::CertificateParseError)
}

let Ok(Some(key)) = rustls_pemfile::private_key(&mut Cursor::new(identity.key)) else {
pub(crate) fn convert_identity_to_pki_types(
identity: &Identity,
) -> Result<(Vec<CertificateDer<'static>>, 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))
}

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::<Result<Vec<_>, _>>()? {
roots
.add(cert)
.map_err(|_| TlsError::CertificateParseError)?;
}

Ok(())
}

0 comments on commit 8def0bb

Please sign in to comment.