1use crate::{
2 e2e_identity::{device_status::DeviceStatus, id::WireQualifiedClientId},
3 prelude::MlsCredentialType,
4};
5use std::str::FromStr;
6use x509_cert::der::pem::LineEnding;
78use super::{Error, Result};
910/// Represents the identity claims identifying a client
11/// Those claims are verifiable by any member in the group
12#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
13pub struct WireIdentity {
14/// Unique client identifier e.g. `T4Coy4vdRzianwfOgXpn6A:6add501bacd1d90e@whitehouse.gov`
15pub client_id: String,
16/// MLS thumbprint
17pub thumbprint: String,
18/// Status of the Credential at the moment T when this object is created
19pub status: DeviceStatus,
20/// Indicates whether the credential is Basic or X509
21pub credential_type: MlsCredentialType,
22/// In case 'credential_type' is [MlsCredentialType::X509] this is populated
23pub x509_identity: Option<X509Identity>,
24}
2526/// Represents the parts of [WireIdentity] that are specific to a X509 certificate (and not a Basic one).
27///
28/// We don't use an enum here since the sole purpose of this is to be exposed through the FFI (and
29/// union types are impossible to carry over the FFI boundary)
30#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
31pub struct X509Identity {
32/// user handle e.g. `john_wire`
33pub handle: String,
34/// Name as displayed in the messaging application e.g. `John Fitzgerald Kennedy`
35pub display_name: String,
36/// DNS domain for which this identity proof was generated e.g. `whitehouse.gov`
37pub domain: String,
38/// X509 certificate identifying this client in the MLS group ; PEM encoded
39pub certificate: String,
40/// X509 certificate serial number
41pub serial_number: String,
42/// X509 certificate not before as Unix timestamp
43pub not_before: u64,
44/// X509 certificate not after as Unix timestamp
45pub not_after: u64,
46}
4748impl<'a> TryFrom<(wire_e2e_identity::prelude::WireIdentity, &'a [u8])> for WireIdentity {
49type Error = Error;
5051fn try_from((i, cert): (wire_e2e_identity::prelude::WireIdentity, &'a [u8])) -> Result<Self> {
52use x509_cert::der::Decode as _;
53let document = x509_cert::der::Document::from_der(cert)?;
54let certificate = document.to_pem("CERTIFICATE", LineEnding::LF)?;
5556let client_id = WireQualifiedClientId::from_str(&i.client_id)?;
5758Ok(Self {
59 client_id: client_id.try_into()?,
60 status: i.status.into(),
61 thumbprint: i.thumbprint,
62 credential_type: MlsCredentialType::X509,
63 x509_identity: Some(X509Identity {
64 handle: i.handle.to_string(),
65 display_name: i.display_name,
66 domain: i.domain,
67 certificate,
68 serial_number: i.serial_number,
69 not_before: i.not_before,
70 not_after: i.not_after,
71 }),
72 })
73 }
74}