core_crypto/mls/
external_sender.rs1use openmls::{
2 extensions::ExternalSender as MlsExternalSender,
3 prelude::{Credential as MlsCredential, OpenMlsCrypto as _, OpenMlsSignaturePublicKey, SignatureScheme},
4};
5use rusty_jwt_tools::{
6 jsonwebtoken::{
7 DecodingKey,
8 errors::Error as JsonWebTokenError,
9 jwk::{AlgorithmParameters, EllipticCurve, Jwk},
10 },
11 prelude::RustyJwtError,
12};
13
14use crate::{Error, OpenMlsError, Result, mls_provider::CRYPTO};
15
16const WIRE_SERVER_IDENTITY: &str = "wire-server";
17
18#[derive(
22 Debug, Clone, PartialEq, Eq, derive_more::From, derive_more::Into, derive_more::Deref, derive_more::DerefMut,
23)]
24pub struct ExternalSender(pub(crate) MlsExternalSender);
25
26impl ExternalSender {
27 pub fn serialize(&self) -> Vec<u8> {
31 self.0.signature_key().as_slice().to_vec()
32 }
33
34 pub fn parse_jwk(jwk: &[u8]) -> Result<ExternalSender> {
38 let jwk = serde_json::from_slice::<Jwk>(jwk)
39 .map_err(JsonWebTokenError::from)
40 .map_err(RustyJwtError::from)?;
41 let signature_scheme = match &jwk.algorithm {
42 AlgorithmParameters::EllipticCurve(params) => match params.curve {
43 EllipticCurve::P256 => SignatureScheme::ECDSA_SECP256R1_SHA256,
44 EllipticCurve::P384 => SignatureScheme::ECDSA_SECP384R1_SHA384,
45 EllipticCurve::P521 => SignatureScheme::ECDSA_SECP521R1_SHA512,
46 _ => return Err(RustyJwtError::UnsupportedAlgorithm.into()),
47 },
48 AlgorithmParameters::OctetKeyPair(params) if matches!(params.curve, EllipticCurve::Ed25519) => {
49 SignatureScheme::ED25519
50 }
51 _ => return Err(RustyJwtError::UnsupportedAlgorithm.into()),
52 };
53 let key = DecodingKey::from_jwk(&jwk).map_err(RustyJwtError::from)?;
55 let key = key.try_get_as_bytes().map_err(RustyJwtError::from)?;
56 Self::parse_public_key(key, signature_scheme)
57 }
58
59 pub fn parse_public_key(key: &[u8], signature_scheme: SignatureScheme) -> Result<ExternalSender> {
65 CRYPTO
66 .validate_signature_key(signature_scheme, key)
67 .map_err(OpenMlsError::wrap("validating signature key"))?;
68 let key = OpenMlsSignaturePublicKey::new(key.into(), signature_scheme)
69 .map_err(OpenMlsError::wrap("creating new signature public key"))?;
70 Ok(MlsExternalSender::new(key.into(), MlsCredential::new_basic(WIRE_SERVER_IDENTITY.into())).into())
71 }
72
73 pub fn parse(key: &[u8], signature_scheme: SignatureScheme) -> Result<ExternalSender> {
78 Self::parse_jwk(key).or_else(|_| Self::parse_public_key(key, signature_scheme))
79 }
80}
81
82impl TryFrom<Vec<u8>> for ExternalSender {
83 type Error = Error;
84
85 fn try_from(value: Vec<u8>) -> Result<Self> {
86 Self::parse_jwk(&value)
87 }
88}