#![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Rfc7469;
#[cfg(feature = "alloc")]
impl Rfc7469 {
#[cfg(feature = "x509-cert")]
pub fn compute_x509_cert(cert: &x509_cert::Certificate) -> alloc::string::String {
Self::compute_for_public_key_bytes(
cert.tbs_certificate()
.subject_public_key_info()
.subject_public_key
.raw_bytes(),
)
}
#[cfg(feature = "rustls-pki-types")]
pub fn compute_rustls_pki_types(
cert: &rustls_pki_types::TrustAnchor<'_>,
) -> alloc::string::String {
Self::compute_for_public_key_bytes(&cert.subject_public_key_info)
}
pub fn compute_for_public_key_bytes(public_key_bytes: &[u8]) -> alloc::string::String {
use base64::Engine;
use sha2::Digest;
let digest = sha2::Sha256::digest(public_key_bytes);
base64::engine::general_purpose::STANDARD.encode(digest)
}
}
#[cfg(feature = "x509-cert")]
struct DigestDerWriter<T>(pub T);
#[cfg(feature = "x509-cert")]
impl<T> x509_cert::der::Writer for DigestDerWriter<T>
where
T: sha2::Digest,
{
fn write(&mut self, slice: &[u8]) -> x509_cert::der::Result<()> {
self.0.update(slice);
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Sha256([u8; 32]);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Sha256Ref<'a>(&'a [u8; 32]);
impl Sha256 {
#[cfg(feature = "x509-cert")]
pub fn compute_x509_cert(cert: &x509_cert::Certificate) -> Self {
use sha2::Digest;
use x509_cert::der::Encode;
let digest = sha2::Sha256::new();
let mut digest = DigestDerWriter(digest);
cert.encode(&mut digest).unwrap();
let DigestDerWriter(digest) = digest;
Self::from_fingerprint_bytes(digest.finalize().into())
}
#[cfg(feature = "rustls-pki-types")]
pub fn compute_rustls_pki_types(cert: rustls_pki_types::CertificateDer<'_>) -> Self {
Self::compute_for_der(&cert)
}
pub fn compute_for_der(cert: &[u8]) -> Self {
use sha2::Digest;
Self::from_fingerprint_bytes(sha2::Sha256::digest(cert).into())
}
pub const fn from_fingerprint_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub const fn into_inner(self) -> [u8; 32] {
self.0
}
pub const fn as_ref(&self) -> Sha256Ref<'_> {
Sha256Ref(&self.0)
}
}
impl<'a> Sha256Ref<'a> {
pub const fn from_fingerprint_bytes(bytes: &'a [u8; 32]) -> Self {
Self(bytes)
}
pub const fn into_inner(self) -> &'a [u8; 32] {
self.0
}
}
impl core::fmt::Display for Sha256 {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.as_ref().fmt(f)
}
}
impl core::fmt::Display for Sha256Ref<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut first = true;
for byte in self.0 {
if first {
first = false;
} else {
f.write_str(":")?;
}
write!(f, "{:02X}", byte)?;
}
Ok(())
}
}