Skip to main content

wire_e2e_identity/acquisition/
thumbprint.rs

1use const_oid::db::{
2    rfc5912::{ID_EC_PUBLIC_KEY, SECP_256_R_1, SECP_384_R_1, SECP_521_R_1},
3    rfc8410::ID_ED_25519,
4};
5use rusty_jwt_tools::{
6    jsonwebtoken::{
7        DecodingKey,
8        errors::Result as JsonWebTokenResult,
9        jwk::{Jwk, ThumbprintHash},
10    },
11    prelude::JwsAlgorithm,
12};
13
14use crate::{acme, acquisition::error::CertificateError};
15
16/// The hash algorithm used for all thumbprints, regardless of the MLS ciphersuite.
17const THUMBPRINT_HASH: ThumbprintHash = ThumbprintHash::SHA256;
18
19/// Used to compute the MLS thumbprint of a Basic Credential
20pub fn compute_raw_key_thumbprint(sign_alg: JwsAlgorithm, signature_public_key: &[u8]) -> acme::Result<String> {
21    let key = match sign_alg {
22        JwsAlgorithm::ES256 | JwsAlgorithm::ES384 | JwsAlgorithm::ES512 => {
23            DecodingKey::from_ec_der(signature_public_key)
24        }
25        JwsAlgorithm::EdDSA => DecodingKey::from_ed_der(signature_public_key),
26    };
27    Ok(thumbprint(&key)?)
28}
29
30/// See: <https://datatracker.ietf.org/doc/html/rfc8037#appendix-A.3>
31pub(crate) fn try_compute_jwk_canonicalized_thumbprint(
32    cert: &x509_cert::TbsCertificate,
33) -> Result<String, CertificateError> {
34    let spki = cert.subject_public_key_info();
35    let curve = spki
36        .algorithm
37        .parameters
38        .as_ref()
39        .and_then(|param| x509_cert::spki::ObjectIdentifier::from_bytes(param.value()).ok());
40    let public_key = spki.subject_public_key.raw_bytes();
41
42    let key = match (spki.algorithm.oid, curve) {
43        (ID_ED_25519, None) => DecodingKey::from_ed_der(public_key),
44        (ID_EC_PUBLIC_KEY, Some(SECP_256_R_1 | SECP_384_R_1 | SECP_521_R_1)) => DecodingKey::from_ec_der(public_key),
45        _ => return Err(CertificateError::UnsupportedPublicKey),
46    };
47    Ok(thumbprint(&key)?)
48}
49
50fn thumbprint(key: &DecodingKey) -> JsonWebTokenResult<String> {
51    Jwk::from_decoding_key(key, None)?.thumbprint(THUMBPRINT_HASH)
52}