1 //! Standardized X.509 Certificate Extensions 2 3 use const_oid::AssociatedOid; 4 use der::{asn1::OctetString, Sequence, ValueOrd}; 5 use spki::ObjectIdentifier; 6 7 pub mod pkix; 8 9 /// Extension as defined in [RFC 5280 Section 4.1.2.9]. 10 /// 11 /// The ASN.1 definition for Extension objects is below. The extnValue type 12 /// may be further parsed using a decoder corresponding to the extnID value. 13 /// 14 /// ```text 15 /// Extension ::= SEQUENCE { 16 /// extnID OBJECT IDENTIFIER, 17 /// critical BOOLEAN DEFAULT FALSE, 18 /// extnValue OCTET STRING 19 /// -- contains the DER encoding of an ASN.1 value 20 /// -- corresponding to the extension type identified 21 /// -- by extnID 22 /// } 23 /// ``` 24 /// 25 /// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9 26 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] 27 #[derive(Clone, Debug, Eq, PartialEq, Sequence, ValueOrd)] 28 #[allow(missing_docs)] 29 pub struct Extension { 30 pub extn_id: ObjectIdentifier, 31 32 #[asn1(default = "Default::default")] 33 pub critical: bool, 34 35 pub extn_value: OctetString, 36 } 37 38 /// Extensions as defined in [RFC 5280 Section 4.1.2.9]. 39 /// 40 /// ```text 41 /// Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 42 /// ``` 43 /// 44 /// [RFC 5280 Section 4.1.2.9]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.9 45 pub type Extensions = alloc::vec::Vec<Extension>; 46 47 /// Trait to be implemented by extensions to allow them to be formated as x509 v3 extensions by 48 /// builder. 49 pub trait AsExtension: AssociatedOid + der::Encode { 50 /// Should the extension be marked critical critical(&self, subject: &crate::name::Name, extensions: &[Extension]) -> bool51 fn critical(&self, subject: &crate::name::Name, extensions: &[Extension]) -> bool; 52 53 /// Returns the Extension with the content encoded. to_extension( &self, subject: &crate::name::Name, extensions: &[Extension], ) -> Result<Extension, der::Error>54 fn to_extension( 55 &self, 56 subject: &crate::name::Name, 57 extensions: &[Extension], 58 ) -> Result<Extension, der::Error> { 59 let content = OctetString::new(<Self as der::Encode>::to_der(self)?)?; 60 61 Ok(Extension { 62 extn_id: <Self as AssociatedOid>::OID, 63 critical: self.critical(subject, extensions), 64 extn_value: content, 65 }) 66 } 67 } 68