1 //! Macros used by this crate 2 3 /// Implements the following traits for a newtype of a `der` decodable/encodable type: 4 /// 5 /// - `From` conversions to/from the inner type 6 /// - `AsRef` and `AsMut` 7 /// - `DecodeValue` and `EncodeValue` 8 /// - `FixedTag` mapping to the inner value's `FixedTag::TAG` 9 /// 10 /// The main case is simplifying newtypes which need an `AssociatedOid` 11 #[macro_export] 12 macro_rules! impl_newtype { 13 ($newtype:ty, $inner:ty) => { 14 #[allow(unused_lifetimes)] 15 impl<'a> From<$inner> for $newtype { 16 #[inline] 17 fn from(value: $inner) -> Self { 18 Self(value) 19 } 20 } 21 22 #[allow(unused_lifetimes)] 23 impl<'a> From<$newtype> for $inner { 24 #[inline] 25 fn from(value: $newtype) -> Self { 26 value.0 27 } 28 } 29 30 #[allow(unused_lifetimes)] 31 impl<'a> AsRef<$inner> for $newtype { 32 #[inline] 33 fn as_ref(&self) -> &$inner { 34 &self.0 35 } 36 } 37 38 #[allow(unused_lifetimes)] 39 impl<'a> AsMut<$inner> for $newtype { 40 #[inline] 41 fn as_mut(&mut self) -> &mut $inner { 42 &mut self.0 43 } 44 } 45 46 #[allow(unused_lifetimes)] 47 impl<'a> ::der::FixedTag for $newtype { 48 const TAG: ::der::Tag = <$inner as ::der::FixedTag>::TAG; 49 } 50 51 impl<'a> ::der::DecodeValue<'a> for $newtype { 52 fn decode_value<R: ::der::Reader<'a>>( 53 decoder: &mut R, 54 header: ::der::Header, 55 ) -> ::der::Result<Self> { 56 Ok(Self(<$inner as ::der::DecodeValue>::decode_value( 57 decoder, header, 58 )?)) 59 } 60 } 61 62 #[allow(unused_lifetimes)] 63 impl<'a> ::der::EncodeValue for $newtype { 64 fn encode_value(&self, encoder: &mut impl ::der::Writer) -> ::der::Result<()> { 65 self.0.encode_value(encoder) 66 } 67 68 fn value_len(&self) -> ::der::Result<::der::Length> { 69 self.0.value_len() 70 } 71 } 72 73 #[allow(unused_lifetimes)] 74 impl<'a> ::der::ValueOrd for $newtype { 75 fn value_cmp(&self, other: &Self) -> ::der::Result<::core::cmp::Ordering> { 76 self.0.value_cmp(&other.0) 77 } 78 } 79 }; 80 } 81 82 /// Implements the AsExtension traits for every defined Extension paylooad 83 macro_rules! impl_extension { 84 ($newtype:ty) => { 85 impl_extension!($newtype, critical = false); 86 }; 87 ($newtype:ty, critical = $critical:expr) => { 88 impl crate::ext::AsExtension for $newtype { 89 fn critical( 90 &self, 91 _subject: &crate::name::Name, 92 _extensions: &[crate::ext::Extension], 93 ) -> bool { 94 $critical 95 } 96 } 97 }; 98 } 99 100 /// Implements conversions between [`spki::SubjectPublicKeyInfo`] and [`SubjectKeyIdentifier`] or [`AuthorityKeyIdentifier`] 101 macro_rules! impl_key_identifier { 102 ($newtype:ty, $out:expr) => { 103 #[cfg(feature = "builder")] 104 mod builder_key_identifier { 105 use super::*; 106 use der::asn1::OctetString; 107 use sha1::{Digest, Sha1}; 108 use spki::SubjectPublicKeyInfoRef; 109 110 impl<'a> TryFrom<SubjectPublicKeyInfoRef<'a>> for $newtype { 111 type Error = der::Error; 112 113 fn try_from(issuer: SubjectPublicKeyInfoRef<'a>) -> Result<Self, Self::Error> { 114 // https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2 115 // 116 // For CA certificates, subject key identifiers SHOULD be derived from 117 // the public key or a method that generates unique values. Two common 118 // methods for generating key identifiers from the public key are: 119 120 // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the 121 // value of the BIT STRING subjectPublicKey (excluding the tag, 122 // length, and number of unused bits). 123 124 // (2) The keyIdentifier is composed of a four-bit type field with 125 // the value 0100 followed by the least significant 60 bits of 126 // the SHA-1 hash of the value of the BIT STRING 127 // subjectPublicKey (excluding the tag, length, and number of 128 // unused bits). 129 130 // Here we're using the first method 131 132 let result = Sha1::digest(issuer.subject_public_key.raw_bytes()); 133 $out(result.as_slice()) 134 } 135 } 136 } 137 }; 138 } 139