use crate::cert::error::{CertificateError, PrivateKeyError};
use crate::cert::parsing::{
extract_spiffe_ids_from_uri_san, parse_der_encoded_bytes_as_x509_certificate,
};
use crate::SpiffeId;
use pkcs8::PrivateKeyInfo;
use x509_parser::certificate::X509Certificate;
use zeroize::Zeroize;
pub mod error;
pub(crate) mod parsing;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Certificate(Vec<u8>);
impl Certificate {
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn spiffe_id(&self) -> Result<SpiffeId, CertificateError> {
let x509 = parse_der_encoded_bytes_as_x509_certificate(self.as_bytes())?;
extract_single_spiffe_id_from_uri_san(&x509)
}
}
impl AsRef<[u8]> for Certificate {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl From<X509Certificate<'_>> for Certificate {
fn from(cert: X509Certificate<'_>) -> Self {
Self(cert.as_raw().to_vec())
}
}
impl TryFrom<&[u8]> for Certificate {
type Error = CertificateError;
fn try_from(der_bytes: &[u8]) -> Result<Self, Self::Error> {
parse_der_encoded_bytes_as_x509_certificate(der_bytes)?;
Ok(Self(Vec::from(der_bytes)))
}
}
impl TryFrom<Vec<u8>> for Certificate {
type Error = CertificateError;
fn try_from(der_bytes: Vec<u8>) -> Result<Self, Self::Error> {
parse_der_encoded_bytes_as_x509_certificate(&der_bytes)?;
Ok(Self(der_bytes))
}
}
#[derive(Clone, Eq, PartialEq, Zeroize)]
#[zeroize(drop)]
pub struct PrivateKey(Vec<u8>);
impl PrivateKey {
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
impl AsRef<[u8]> for PrivateKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl TryFrom<&[u8]> for PrivateKey {
type Error = PrivateKeyError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
PrivateKeyInfo::try_from(bytes).map_err(PrivateKeyError::DecodePkcs8)?;
Ok(Self(Vec::from(bytes)))
}
}
impl TryFrom<Vec<u8>> for PrivateKey {
type Error = PrivateKeyError;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
PrivateKeyInfo::try_from(bytes.as_slice()).map_err(PrivateKeyError::DecodePkcs8)?;
Ok(Self(bytes))
}
}
impl std::fmt::Debug for PrivateKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PrivateKey")
.field("len", &self.0.len())
.finish()
}
}
pub fn spiffe_id_from_der(der: &[u8]) -> Result<SpiffeId, CertificateError> {
let x509 = parse_der_encoded_bytes_as_x509_certificate(der)?;
extract_single_spiffe_id_from_uri_san(&x509)
}
pub(crate) fn extract_single_spiffe_id_from_uri_san(
cert: &X509Certificate<'_>,
) -> Result<SpiffeId, CertificateError> {
let mut ids = extract_spiffe_ids_from_uri_san(cert)?.into_iter();
let Some(first) = ids.next() else {
return Err(CertificateError::MissingSpiffeId);
};
if ids.next().is_some() {
return Err(CertificateError::MultipleSpiffeIds);
}
Ok(first)
}