Skip to content

add support for parsing X509 certs from DER #2375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions tonic/src/transport/tls.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use base64::Engine as _;

/// Represents a X509 certificate.
#[derive(Debug, Clone)]
pub struct Certificate {
Expand All @@ -20,6 +22,17 @@ impl Certificate {
Self { pem }
}

/// Parse a DER encoded X509 Certificate.
///
/// The provided DER should include exactly one DER encoded certificate.
pub fn from_der(der: impl AsRef<[u8]>) -> Self {
let der = der.as_ref();
let pem = der2pem(der);
Self {
pem: pem.into_bytes(),
}
}

/// Get a immutable reference to underlying certificate
pub fn get_ref(&self) -> &[u8] {
self.pem.as_slice()
Expand Down Expand Up @@ -57,4 +70,20 @@ impl Identity {
let key = key.as_ref().into();
Self { cert, key }
}

/// Parse a DER encoded certificate and private key.
///
/// The provided cert must contain exactly one DER encoded certificate.
pub fn from_der(cert: impl AsRef<[u8]>, key: impl AsRef<[u8]>) -> Self {
let cert = Certificate::from_der(cert);
let key = key.as_ref().into();
Self { cert, key }
}
}

fn der2pem(der: &[u8]) -> String {
const RFC7468_HEADER: &str = "-----BEGIN CERTIFICATE-----";
const RFC7468_FOOTER: &str = "-----END CERTIFICATE-----";
let pem = crate::util::base64::STANDARD_NO_PAD.encode(der);
format!("{RFC7468_HEADER}\n{pem}\n{RFC7468_FOOTER}\n")
}
Loading