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