Skip to main content

wire_e2e_identity/
utils.rs

1use certval::ExtensionProcessing as _;
2use jwt_simple::{
3    algorithms::{ECDSAP256PublicKeyLike as _, ECDSAP384PublicKeyLike as _, ECDSAP521PublicKeyLike as _},
4    prelude::{ES256KeyPair, ES384KeyPair, ES512KeyPair, Ed25519KeyPair, Jwk},
5};
6use rusty_jwt_tools::{
7    jwk::TryIntoJwk as _,
8    prelude::{JwsAlgorithm, Pem},
9};
10use spki::AlgorithmIdentifierOwned;
11use x509_cert::ext::pkix::AuthorityKeyIdentifier;
12
13use crate::{error::E2eIdentityResult, validation};
14
15pub fn generate_key(sign_alg: JwsAlgorithm) -> E2eIdentityResult<Pem> {
16    let pem = match sign_alg {
17        JwsAlgorithm::P256 => ES256KeyPair::generate().to_pem()?,
18        JwsAlgorithm::P384 => ES384KeyPair::generate().to_pem()?,
19        JwsAlgorithm::P521 => ES512KeyPair::generate().to_pem()?,
20        JwsAlgorithm::Ed25519 => Ed25519KeyPair::generate().to_pem(),
21    };
22    Ok(pem.into())
23}
24
25pub fn pem_from_bytes(bytes: &[u8], sign_alg: JwsAlgorithm) -> E2eIdentityResult<Pem> {
26    let pem = match sign_alg {
27        JwsAlgorithm::P256 => ES256KeyPair::from_bytes(bytes)?.to_pem()?,
28        JwsAlgorithm::P384 => ES384KeyPair::from_bytes(bytes)?.to_pem()?,
29        JwsAlgorithm::P521 => ES512KeyPair::from_bytes(bytes)?.to_pem()?,
30        JwsAlgorithm::Ed25519 => Ed25519KeyPair::from_bytes(bytes)?.to_pem(),
31    };
32    Ok(pem.into())
33}
34
35pub(crate) fn public_jwk_from_pem_keypair(alg: JwsAlgorithm, keypair: &Pem) -> E2eIdentityResult<Jwk> {
36    let jwk = match alg {
37        JwsAlgorithm::P256 => ES256KeyPair::from_pem(keypair)?.public_key().try_into_jwk()?,
38        JwsAlgorithm::P384 => ES384KeyPair::from_pem(keypair)?.public_key().try_into_jwk()?,
39        JwsAlgorithm::P521 => ES512KeyPair::from_pem(keypair)?.public_key().try_into_jwk()?,
40        JwsAlgorithm::Ed25519 => Ed25519KeyPair::from_pem(keypair)?.public_key().try_into_jwk()?,
41    };
42    Ok(jwk)
43}
44
45pub(crate) fn public_key_bytes(alg: JwsAlgorithm, keypair: &Pem) -> E2eIdentityResult<Vec<u8>> {
46    let bytes = match alg {
47        JwsAlgorithm::P256 => ES256KeyPair::from_pem(keypair)?
48            .public_key()
49            .public_key()
50            .to_bytes_uncompressed(),
51        JwsAlgorithm::P384 => ES384KeyPair::from_pem(keypair)?
52            .public_key()
53            .public_key()
54            .to_bytes_uncompressed(),
55        JwsAlgorithm::P521 => ES512KeyPair::from_pem(keypair)?
56            .public_key()
57            .public_key()
58            .to_bytes_uncompressed(),
59        JwsAlgorithm::Ed25519 => Ed25519KeyPair::from_pem(keypair)?.public_key().to_bytes(),
60    };
61    Ok(bytes)
62}
63
64pub(crate) fn jws_alg_to_x509_identifier(alg: JwsAlgorithm) -> AlgorithmIdentifierOwned {
65    match alg {
66        JwsAlgorithm::Ed25519 => AlgorithmIdentifierOwned {
67            oid: const_oid::db::rfc8410::ID_ED_25519,
68            parameters: None,
69        },
70        JwsAlgorithm::P256 => AlgorithmIdentifierOwned {
71            oid: const_oid::db::rfc5912::ID_EC_PUBLIC_KEY,
72            parameters: Some(const_oid::db::rfc5912::SECP_256_R_1.into()),
73        },
74        JwsAlgorithm::P384 => AlgorithmIdentifierOwned {
75            oid: const_oid::db::rfc5912::ID_EC_PUBLIC_KEY,
76            parameters: Some(const_oid::db::rfc5912::SECP_384_R_1.into()),
77        },
78        JwsAlgorithm::P521 => AlgorithmIdentifierOwned {
79            oid: const_oid::db::rfc5912::ID_EC_PUBLIC_KEY,
80            parameters: Some(const_oid::db::rfc5912::SECP_521_R_1.into()),
81        },
82    }
83}
84
85pub(crate) fn extract_ski_aki_from_cert(cert: &x509_cert::Certificate) -> validation::Result<(String, Option<String>)> {
86    let cert = certval::PDVCertificate::try_from(cert.clone())?;
87
88    let ski = cert
89        .get_extension(&const_oid::db::rfc5912::ID_CE_SUBJECT_KEY_IDENTIFIER)?
90        .ok_or(validation::Error::MissingSki)?;
91    let ski = match ski {
92        certval::PDVExtension::SubjectKeyIdentifier(ski) => hex::encode(ski.0.as_bytes()),
93        _ => return Err(validation::Error::ImplementationError),
94    };
95
96    let aki = cert
97        .get_extension(&const_oid::db::rfc5912::ID_CE_AUTHORITY_KEY_IDENTIFIER)?
98        .and_then(|ext| match ext {
99            certval::PDVExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier { key_identifier, .. }) => {
100                key_identifier.as_ref()
101            }
102            _ => None,
103        })
104        .map(|ki| hex::encode(ki.as_bytes()));
105
106    Ok((ski, aki))
107}