xwt_cert_fingerprint/
lib.rs1#![no_std]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct Rfc7469;
14
15#[cfg(feature = "alloc")]
16impl Rfc7469 {
17 #[cfg(feature = "x509-cert")]
19 pub fn compute_x509_cert(cert: &x509_cert::Certificate) -> alloc::string::String {
20 Self::compute_for_public_key_bytes(
21 cert.tbs_certificate
22 .subject_public_key_info
23 .subject_public_key
24 .raw_bytes(),
25 )
26 }
27
28 #[cfg(feature = "rustls-pki-types")]
30 pub fn compute_rustls_pki_types(
31 cert: &rustls_pki_types::TrustAnchor<'_>,
32 ) -> alloc::string::String {
33 Self::compute_for_public_key_bytes(&cert.subject_public_key_info)
34 }
35
36 pub fn compute_for_public_key_bytes(public_key_bytes: &[u8]) -> alloc::string::String {
38 use base64::Engine;
39 use sha2::Digest;
40
41 let digest = sha2::Sha256::digest(public_key_bytes);
42 base64::engine::general_purpose::STANDARD.encode(digest)
43 }
44}
45
46#[cfg(feature = "x509-cert")]
48struct DigestDerWriter<T>(pub T);
49
50#[cfg(feature = "x509-cert")]
51impl<T> x509_cert::der::Writer for DigestDerWriter<T>
52where
53 T: sha2::Digest,
54{
55 fn write(&mut self, slice: &[u8]) -> x509_cert::der::Result<()> {
56 self.0.update(slice);
57 Ok(())
58 }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub struct Sha256([u8; 32]);
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub struct Sha256Ref<'a>(&'a [u8; 32]);
80
81impl Sha256 {
82 #[cfg(feature = "x509-cert")]
84 pub fn compute_x509_cert(cert: &x509_cert::Certificate) -> Self {
85 use sha2::Digest;
86 use x509_cert::der::Encode;
87
88 let digest = sha2::Sha256::new();
89 let mut digest = DigestDerWriter(digest);
90 cert.encode(&mut digest).unwrap();
91 let DigestDerWriter(digest) = digest;
92 Self::from_fingerprint_bytes(digest.finalize().into())
93 }
94
95 #[cfg(feature = "rustls-pki-types")]
98 pub fn compute_rustls_pki_types(cert: rustls_pki_types::CertificateDer<'_>) -> Self {
99 Self::compute_for_der(&cert)
100 }
101
102 pub fn compute_for_der(cert: &[u8]) -> Self {
105 use sha2::Digest;
106 Self::from_fingerprint_bytes(sha2::Sha256::digest(cert).into())
107 }
108
109 pub const fn from_fingerprint_bytes(bytes: [u8; 32]) -> Self {
113 Self(bytes)
114 }
115
116 pub const fn into_inner(self) -> [u8; 32] {
118 self.0
119 }
120
121 pub const fn as_ref(&self) -> Sha256Ref<'_> {
123 Sha256Ref(&self.0)
124 }
125}
126
127impl<'a> Sha256Ref<'a> {
128 pub const fn from_fingerprint_bytes(bytes: &'a [u8; 32]) -> Self {
132 Self(bytes)
133 }
134
135 pub const fn into_inner(self) -> &'a [u8; 32] {
137 self.0
138 }
139}
140
141impl core::fmt::Display for Sha256 {
142 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
143 self.as_ref().fmt(f)
144 }
145}
146
147impl core::fmt::Display for Sha256Ref<'_> {
148 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
149 let mut first = true;
150 for byte in self.0 {
151 if first {
152 first = false;
153 } else {
154 f.write_str(":")?;
155 }
156 write!(f, "{:02X}", byte)?;
157 }
158 Ok(())
159 }
160}