1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 use core::{
6     convert::Infallible,
7     fmt::{self, Debug},
8     ops::{Deref, DerefMut},
9 };
10 
11 use alloc::vec::Vec;
12 use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
13 
14 use super::{Credential, CredentialType, MlsCredential};
15 
16 #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsEncode, MlsDecode)]
17 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
18 #[cfg_attr(
19     all(feature = "ffi", not(test)),
20     safer_ffi_gen::ffi_type(clone, opaque)
21 )]
22 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23 /// X.509 certificate in DER format.
24 pub struct DerCertificate(
25     #[mls_codec(with = "mls_rs_codec::byte_vec")]
26     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
27     Vec<u8>,
28 );
29 
30 impl Debug for DerCertificate {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result31     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32         crate::debug::pretty_bytes(&self.0)
33             .named("DerCertificate")
34             .fmt(f)
35     }
36 }
37 
38 #[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen)]
39 impl DerCertificate {
40     /// Create a der certificate from raw bytes.
new(data: Vec<u8>) -> DerCertificate41     pub fn new(data: Vec<u8>) -> DerCertificate {
42         DerCertificate(data)
43     }
44 
45     /// Convert this certificate into raw bytes.
into_vec(self) -> Vec<u8>46     pub fn into_vec(self) -> Vec<u8> {
47         self.0
48     }
49 }
50 
51 impl From<Vec<u8>> for DerCertificate {
from(data: Vec<u8>) -> Self52     fn from(data: Vec<u8>) -> Self {
53         DerCertificate(data)
54     }
55 }
56 
57 impl Deref for DerCertificate {
58     type Target = [u8];
59 
deref(&self) -> &Self::Target60     fn deref(&self) -> &Self::Target {
61         &self.0
62     }
63 }
64 
65 impl AsRef<[u8]> for DerCertificate {
as_ref(&self) -> &[u8]66     fn as_ref(&self) -> &[u8] {
67         &self.0
68     }
69 }
70 
71 #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsEncode, MlsDecode)]
72 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
73 #[cfg_attr(
74     all(feature = "ffi", not(test)),
75     safer_ffi_gen::ffi_type(clone, opaque)
76 )]
77 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78 /// A chain of [`DerCertificate`] that is ordered from leaf to root.
79 ///
80 /// Certificate chains MAY leave out root CA's so long as they are
81 /// provided as input to whatever certificate validator ultimately is
82 /// verifying the chain.
83 pub struct CertificateChain(Vec<DerCertificate>);
84 
85 impl Deref for CertificateChain {
86     type Target = Vec<DerCertificate>;
87 
deref(&self) -> &Self::Target88     fn deref(&self) -> &Self::Target {
89         &self.0
90     }
91 }
92 
93 impl DerefMut for CertificateChain {
deref_mut(&mut self) -> &mut Self::Target94     fn deref_mut(&mut self) -> &mut Self::Target {
95         &mut self.0
96     }
97 }
98 
99 impl From<Vec<DerCertificate>> for CertificateChain {
from(cert_data: Vec<DerCertificate>) -> Self100     fn from(cert_data: Vec<DerCertificate>) -> Self {
101         CertificateChain(cert_data)
102     }
103 }
104 
105 impl From<Vec<Vec<u8>>> for CertificateChain {
from(value: Vec<Vec<u8>>) -> Self106     fn from(value: Vec<Vec<u8>>) -> Self {
107         CertificateChain(value.into_iter().map(DerCertificate).collect())
108     }
109 }
110 
111 impl FromIterator<DerCertificate> for CertificateChain {
from_iter<T: IntoIterator<Item = DerCertificate>>(iter: T) -> Self112     fn from_iter<T: IntoIterator<Item = DerCertificate>>(iter: T) -> Self {
113         CertificateChain::from(iter.into_iter().collect::<Vec<_>>())
114     }
115 }
116 
117 impl CertificateChain {
118     /// Get the leaf certificate, which is the first certificate in the chain.
leaf(&self) -> Option<&DerCertificate>119     pub fn leaf(&self) -> Option<&DerCertificate> {
120         self.0.first()
121     }
122 
123     /// Convert this certificate chain into a [`Credential`] enum.
into_credential(self) -> Credential124     pub fn into_credential(self) -> Credential {
125         Credential::X509(self)
126     }
127 }
128 
129 impl MlsCredential for CertificateChain {
130     type Error = Infallible;
131 
credential_type() -> CredentialType132     fn credential_type() -> CredentialType {
133         CredentialType::X509
134     }
135 
into_credential(self) -> Result<Credential, Self::Error>136     fn into_credential(self) -> Result<Credential, Self::Error> {
137         Ok(self.into_credential())
138     }
139 }
140