wire_e2e_identity/acme/identity/
thumbprint.rs

1use jwt_simple::prelude::*;
2use rusty_jwt_tools::{
3    jwk::TryIntoJwk,
4    prelude::{HashAlgorithm, JwkThumbprint, JwsAlgorithm},
5};
6use x509_cert::spki::SubjectPublicKeyInfoOwned;
7
8use crate::acme::{RustyAcmeError, RustyAcmeResult, error::CertificateError};
9
10/// Used to compute the MLS thumbprint of a Basic Credential
11pub fn compute_raw_key_thumbprint(
12    sign_alg: JwsAlgorithm,
13    hash_alg: HashAlgorithm,
14    signature_public_key: &[u8],
15) -> RustyAcmeResult<String> {
16    let jwk = match sign_alg {
17        JwsAlgorithm::Ed25519 => Ed25519PublicKey::from_bytes(signature_public_key)?.try_into_jwk()?,
18        JwsAlgorithm::P256 => ES256PublicKey::from_bytes(signature_public_key)?.try_into_jwk()?,
19        JwsAlgorithm::P384 => ES384PublicKey::from_bytes(signature_public_key)?.try_into_jwk()?,
20        JwsAlgorithm::P521 => ES512PublicKey::from_bytes(signature_public_key)?.try_into_jwk()?,
21    };
22    let thumbprint = JwkThumbprint::generate(&jwk, hash_alg)?;
23    Ok(thumbprint.kid)
24}
25
26/// See: https://datatracker.ietf.org/doc/html/rfc8037#appendix-A.3
27pub(crate) fn try_compute_jwk_canonicalized_thumbprint(
28    cert: &x509_cert::TbsCertificate,
29    hash_alg: HashAlgorithm,
30) -> RustyAcmeResult<String> {
31    let jwk = try_into_jwk(&cert.subject_public_key_info)?;
32    let thumbprint = JwkThumbprint::generate(&jwk, hash_alg)?;
33    Ok(thumbprint.kid)
34}
35
36fn try_into_jwk(spki: &SubjectPublicKeyInfoOwned) -> RustyAcmeResult<Jwk> {
37    use const_oid::db::{
38        rfc5912::{ID_EC_PUBLIC_KEY, SECP_256_R_1, SECP_384_R_1, SECP_521_R_1},
39        rfc8410::{ID_ED_448, ID_ED_25519},
40    };
41    let params = spki
42        .algorithm
43        .parameters
44        .as_ref()
45        .and_then(|param| x509_cert::spki::ObjectIdentifier::from_bytes(param.value()).ok());
46
47    match (spki.algorithm.oid, params) {
48        (ID_ED_25519, None) => Ok(Ed25519PublicKey::from_bytes(spki.subject_public_key.raw_bytes())?.try_into_jwk()?),
49        (ID_ED_448, None) => Err(RustyAcmeError::InvalidCertificate(
50            CertificateError::UnsupportedPublicKey,
51        )),
52        (ID_EC_PUBLIC_KEY, Some(SECP_256_R_1)) => {
53            Ok(ES256PublicKey::from_bytes(spki.subject_public_key.raw_bytes())?.try_into_jwk()?)
54        }
55        (ID_EC_PUBLIC_KEY, Some(SECP_384_R_1)) => {
56            Ok(ES384PublicKey::from_bytes(spki.subject_public_key.raw_bytes())?.try_into_jwk()?)
57        }
58        (ID_EC_PUBLIC_KEY, Some(SECP_521_R_1)) => {
59            Ok(ES512PublicKey::from_bytes(spki.subject_public_key.raw_bytes())?.try_into_jwk()?)
60        }
61        _ => Err(RustyAcmeError::InvalidCertificate(
62            CertificateError::UnsupportedPublicKey,
63        )),
64    }
65}