192f3ab15Sopenharmony_ci//! Add extensions to an `X509` certificate or certificate request. 292f3ab15Sopenharmony_ci//! 392f3ab15Sopenharmony_ci//! The extensions defined for X.509 v3 certificates provide methods for 492f3ab15Sopenharmony_ci//! associating additional attributes with users or public keys and for 592f3ab15Sopenharmony_ci//! managing relationships between CAs. The extensions created using this 692f3ab15Sopenharmony_ci//! module can be used with `X509v3Context` objects. 792f3ab15Sopenharmony_ci//! 892f3ab15Sopenharmony_ci//! # Example 992f3ab15Sopenharmony_ci//! 1092f3ab15Sopenharmony_ci//! ```rust 1192f3ab15Sopenharmony_ci//! use openssl::x509::extension::BasicConstraints; 1292f3ab15Sopenharmony_ci//! use openssl::x509::X509Extension; 1392f3ab15Sopenharmony_ci//! 1492f3ab15Sopenharmony_ci//! let mut bc = BasicConstraints::new(); 1592f3ab15Sopenharmony_ci//! let bc = bc.critical().ca().pathlen(1); 1692f3ab15Sopenharmony_ci//! 1792f3ab15Sopenharmony_ci//! let extension: X509Extension = bc.build().unwrap(); 1892f3ab15Sopenharmony_ci//! ``` 1992f3ab15Sopenharmony_ciuse std::fmt::Write; 2092f3ab15Sopenharmony_ci 2192f3ab15Sopenharmony_ciuse crate::asn1::Asn1Object; 2292f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 2392f3ab15Sopenharmony_ciuse crate::nid::Nid; 2492f3ab15Sopenharmony_ciuse crate::x509::{GeneralName, Stack, X509Extension, X509v3Context}; 2592f3ab15Sopenharmony_ciuse foreign_types::ForeignType; 2692f3ab15Sopenharmony_ci 2792f3ab15Sopenharmony_ci/// An extension which indicates whether a certificate is a CA certificate. 2892f3ab15Sopenharmony_cipub struct BasicConstraints { 2992f3ab15Sopenharmony_ci critical: bool, 3092f3ab15Sopenharmony_ci ca: bool, 3192f3ab15Sopenharmony_ci pathlen: Option<u32>, 3292f3ab15Sopenharmony_ci} 3392f3ab15Sopenharmony_ci 3492f3ab15Sopenharmony_ciimpl Default for BasicConstraints { 3592f3ab15Sopenharmony_ci fn default() -> BasicConstraints { 3692f3ab15Sopenharmony_ci BasicConstraints::new() 3792f3ab15Sopenharmony_ci } 3892f3ab15Sopenharmony_ci} 3992f3ab15Sopenharmony_ci 4092f3ab15Sopenharmony_ciimpl BasicConstraints { 4192f3ab15Sopenharmony_ci /// Construct a new `BasicConstraints` extension. 4292f3ab15Sopenharmony_ci pub fn new() -> BasicConstraints { 4392f3ab15Sopenharmony_ci BasicConstraints { 4492f3ab15Sopenharmony_ci critical: false, 4592f3ab15Sopenharmony_ci ca: false, 4692f3ab15Sopenharmony_ci pathlen: None, 4792f3ab15Sopenharmony_ci } 4892f3ab15Sopenharmony_ci } 4992f3ab15Sopenharmony_ci 5092f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 5192f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut BasicConstraints { 5292f3ab15Sopenharmony_ci self.critical = true; 5392f3ab15Sopenharmony_ci self 5492f3ab15Sopenharmony_ci } 5592f3ab15Sopenharmony_ci 5692f3ab15Sopenharmony_ci /// Sets the `ca` flag to `true`. 5792f3ab15Sopenharmony_ci pub fn ca(&mut self) -> &mut BasicConstraints { 5892f3ab15Sopenharmony_ci self.ca = true; 5992f3ab15Sopenharmony_ci self 6092f3ab15Sopenharmony_ci } 6192f3ab15Sopenharmony_ci 6292f3ab15Sopenharmony_ci /// Sets the `pathlen` to an optional non-negative value. The `pathlen` is the 6392f3ab15Sopenharmony_ci /// maximum number of CAs that can appear below this one in a chain. 6492f3ab15Sopenharmony_ci pub fn pathlen(&mut self, pathlen: u32) -> &mut BasicConstraints { 6592f3ab15Sopenharmony_ci self.pathlen = Some(pathlen); 6692f3ab15Sopenharmony_ci self 6792f3ab15Sopenharmony_ci } 6892f3ab15Sopenharmony_ci 6992f3ab15Sopenharmony_ci /// Return the `BasicConstraints` extension as an `X509Extension`. 7092f3ab15Sopenharmony_ci // Temporarily silence the deprecation warning - this should be ported to 7192f3ab15Sopenharmony_ci // `X509Extension::new_internal`. 7292f3ab15Sopenharmony_ci #[allow(deprecated)] 7392f3ab15Sopenharmony_ci pub fn build(&self) -> Result<X509Extension, ErrorStack> { 7492f3ab15Sopenharmony_ci let mut value = String::new(); 7592f3ab15Sopenharmony_ci if self.critical { 7692f3ab15Sopenharmony_ci value.push_str("critical,"); 7792f3ab15Sopenharmony_ci } 7892f3ab15Sopenharmony_ci value.push_str("CA:"); 7992f3ab15Sopenharmony_ci if self.ca { 8092f3ab15Sopenharmony_ci value.push_str("TRUE"); 8192f3ab15Sopenharmony_ci } else { 8292f3ab15Sopenharmony_ci value.push_str("FALSE"); 8392f3ab15Sopenharmony_ci } 8492f3ab15Sopenharmony_ci if let Some(pathlen) = self.pathlen { 8592f3ab15Sopenharmony_ci write!(value, ",pathlen:{}", pathlen).unwrap(); 8692f3ab15Sopenharmony_ci } 8792f3ab15Sopenharmony_ci X509Extension::new_nid(None, None, Nid::BASIC_CONSTRAINTS, &value) 8892f3ab15Sopenharmony_ci } 8992f3ab15Sopenharmony_ci} 9092f3ab15Sopenharmony_ci 9192f3ab15Sopenharmony_ci/// An extension consisting of a list of names of the permitted key usages. 9292f3ab15Sopenharmony_cipub struct KeyUsage { 9392f3ab15Sopenharmony_ci critical: bool, 9492f3ab15Sopenharmony_ci digital_signature: bool, 9592f3ab15Sopenharmony_ci non_repudiation: bool, 9692f3ab15Sopenharmony_ci key_encipherment: bool, 9792f3ab15Sopenharmony_ci data_encipherment: bool, 9892f3ab15Sopenharmony_ci key_agreement: bool, 9992f3ab15Sopenharmony_ci key_cert_sign: bool, 10092f3ab15Sopenharmony_ci crl_sign: bool, 10192f3ab15Sopenharmony_ci encipher_only: bool, 10292f3ab15Sopenharmony_ci decipher_only: bool, 10392f3ab15Sopenharmony_ci} 10492f3ab15Sopenharmony_ci 10592f3ab15Sopenharmony_ciimpl Default for KeyUsage { 10692f3ab15Sopenharmony_ci fn default() -> KeyUsage { 10792f3ab15Sopenharmony_ci KeyUsage::new() 10892f3ab15Sopenharmony_ci } 10992f3ab15Sopenharmony_ci} 11092f3ab15Sopenharmony_ci 11192f3ab15Sopenharmony_ciimpl KeyUsage { 11292f3ab15Sopenharmony_ci /// Construct a new `KeyUsage` extension. 11392f3ab15Sopenharmony_ci pub fn new() -> KeyUsage { 11492f3ab15Sopenharmony_ci KeyUsage { 11592f3ab15Sopenharmony_ci critical: false, 11692f3ab15Sopenharmony_ci digital_signature: false, 11792f3ab15Sopenharmony_ci non_repudiation: false, 11892f3ab15Sopenharmony_ci key_encipherment: false, 11992f3ab15Sopenharmony_ci data_encipherment: false, 12092f3ab15Sopenharmony_ci key_agreement: false, 12192f3ab15Sopenharmony_ci key_cert_sign: false, 12292f3ab15Sopenharmony_ci crl_sign: false, 12392f3ab15Sopenharmony_ci encipher_only: false, 12492f3ab15Sopenharmony_ci decipher_only: false, 12592f3ab15Sopenharmony_ci } 12692f3ab15Sopenharmony_ci } 12792f3ab15Sopenharmony_ci 12892f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 12992f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut KeyUsage { 13092f3ab15Sopenharmony_ci self.critical = true; 13192f3ab15Sopenharmony_ci self 13292f3ab15Sopenharmony_ci } 13392f3ab15Sopenharmony_ci 13492f3ab15Sopenharmony_ci /// Sets the `digitalSignature` flag to `true`. 13592f3ab15Sopenharmony_ci pub fn digital_signature(&mut self) -> &mut KeyUsage { 13692f3ab15Sopenharmony_ci self.digital_signature = true; 13792f3ab15Sopenharmony_ci self 13892f3ab15Sopenharmony_ci } 13992f3ab15Sopenharmony_ci 14092f3ab15Sopenharmony_ci /// Sets the `nonRepudiation` flag to `true`. 14192f3ab15Sopenharmony_ci pub fn non_repudiation(&mut self) -> &mut KeyUsage { 14292f3ab15Sopenharmony_ci self.non_repudiation = true; 14392f3ab15Sopenharmony_ci self 14492f3ab15Sopenharmony_ci } 14592f3ab15Sopenharmony_ci 14692f3ab15Sopenharmony_ci /// Sets the `keyEncipherment` flag to `true`. 14792f3ab15Sopenharmony_ci pub fn key_encipherment(&mut self) -> &mut KeyUsage { 14892f3ab15Sopenharmony_ci self.key_encipherment = true; 14992f3ab15Sopenharmony_ci self 15092f3ab15Sopenharmony_ci } 15192f3ab15Sopenharmony_ci 15292f3ab15Sopenharmony_ci /// Sets the `dataEncipherment` flag to `true`. 15392f3ab15Sopenharmony_ci pub fn data_encipherment(&mut self) -> &mut KeyUsage { 15492f3ab15Sopenharmony_ci self.data_encipherment = true; 15592f3ab15Sopenharmony_ci self 15692f3ab15Sopenharmony_ci } 15792f3ab15Sopenharmony_ci 15892f3ab15Sopenharmony_ci /// Sets the `keyAgreement` flag to `true`. 15992f3ab15Sopenharmony_ci pub fn key_agreement(&mut self) -> &mut KeyUsage { 16092f3ab15Sopenharmony_ci self.key_agreement = true; 16192f3ab15Sopenharmony_ci self 16292f3ab15Sopenharmony_ci } 16392f3ab15Sopenharmony_ci 16492f3ab15Sopenharmony_ci /// Sets the `keyCertSign` flag to `true`. 16592f3ab15Sopenharmony_ci pub fn key_cert_sign(&mut self) -> &mut KeyUsage { 16692f3ab15Sopenharmony_ci self.key_cert_sign = true; 16792f3ab15Sopenharmony_ci self 16892f3ab15Sopenharmony_ci } 16992f3ab15Sopenharmony_ci 17092f3ab15Sopenharmony_ci /// Sets the `cRLSign` flag to `true`. 17192f3ab15Sopenharmony_ci pub fn crl_sign(&mut self) -> &mut KeyUsage { 17292f3ab15Sopenharmony_ci self.crl_sign = true; 17392f3ab15Sopenharmony_ci self 17492f3ab15Sopenharmony_ci } 17592f3ab15Sopenharmony_ci 17692f3ab15Sopenharmony_ci /// Sets the `encipherOnly` flag to `true`. 17792f3ab15Sopenharmony_ci pub fn encipher_only(&mut self) -> &mut KeyUsage { 17892f3ab15Sopenharmony_ci self.encipher_only = true; 17992f3ab15Sopenharmony_ci self 18092f3ab15Sopenharmony_ci } 18192f3ab15Sopenharmony_ci 18292f3ab15Sopenharmony_ci /// Sets the `decipherOnly` flag to `true`. 18392f3ab15Sopenharmony_ci pub fn decipher_only(&mut self) -> &mut KeyUsage { 18492f3ab15Sopenharmony_ci self.decipher_only = true; 18592f3ab15Sopenharmony_ci self 18692f3ab15Sopenharmony_ci } 18792f3ab15Sopenharmony_ci 18892f3ab15Sopenharmony_ci /// Return the `KeyUsage` extension as an `X509Extension`. 18992f3ab15Sopenharmony_ci // Temporarily silence the deprecation warning - this should be ported to 19092f3ab15Sopenharmony_ci // `X509Extension::new_internal`. 19192f3ab15Sopenharmony_ci #[allow(deprecated)] 19292f3ab15Sopenharmony_ci pub fn build(&self) -> Result<X509Extension, ErrorStack> { 19392f3ab15Sopenharmony_ci let mut value = String::new(); 19492f3ab15Sopenharmony_ci let mut first = true; 19592f3ab15Sopenharmony_ci append(&mut value, &mut first, self.critical, "critical"); 19692f3ab15Sopenharmony_ci append( 19792f3ab15Sopenharmony_ci &mut value, 19892f3ab15Sopenharmony_ci &mut first, 19992f3ab15Sopenharmony_ci self.digital_signature, 20092f3ab15Sopenharmony_ci "digitalSignature", 20192f3ab15Sopenharmony_ci ); 20292f3ab15Sopenharmony_ci append( 20392f3ab15Sopenharmony_ci &mut value, 20492f3ab15Sopenharmony_ci &mut first, 20592f3ab15Sopenharmony_ci self.non_repudiation, 20692f3ab15Sopenharmony_ci "nonRepudiation", 20792f3ab15Sopenharmony_ci ); 20892f3ab15Sopenharmony_ci append( 20992f3ab15Sopenharmony_ci &mut value, 21092f3ab15Sopenharmony_ci &mut first, 21192f3ab15Sopenharmony_ci self.key_encipherment, 21292f3ab15Sopenharmony_ci "keyEncipherment", 21392f3ab15Sopenharmony_ci ); 21492f3ab15Sopenharmony_ci append( 21592f3ab15Sopenharmony_ci &mut value, 21692f3ab15Sopenharmony_ci &mut first, 21792f3ab15Sopenharmony_ci self.data_encipherment, 21892f3ab15Sopenharmony_ci "dataEncipherment", 21992f3ab15Sopenharmony_ci ); 22092f3ab15Sopenharmony_ci append(&mut value, &mut first, self.key_agreement, "keyAgreement"); 22192f3ab15Sopenharmony_ci append(&mut value, &mut first, self.key_cert_sign, "keyCertSign"); 22292f3ab15Sopenharmony_ci append(&mut value, &mut first, self.crl_sign, "cRLSign"); 22392f3ab15Sopenharmony_ci append(&mut value, &mut first, self.encipher_only, "encipherOnly"); 22492f3ab15Sopenharmony_ci append(&mut value, &mut first, self.decipher_only, "decipherOnly"); 22592f3ab15Sopenharmony_ci X509Extension::new_nid(None, None, Nid::KEY_USAGE, &value) 22692f3ab15Sopenharmony_ci } 22792f3ab15Sopenharmony_ci} 22892f3ab15Sopenharmony_ci 22992f3ab15Sopenharmony_ci/// An extension consisting of a list of usages indicating purposes 23092f3ab15Sopenharmony_ci/// for which the certificate public key can be used for. 23192f3ab15Sopenharmony_cipub struct ExtendedKeyUsage { 23292f3ab15Sopenharmony_ci critical: bool, 23392f3ab15Sopenharmony_ci items: Vec<String>, 23492f3ab15Sopenharmony_ci} 23592f3ab15Sopenharmony_ci 23692f3ab15Sopenharmony_ciimpl Default for ExtendedKeyUsage { 23792f3ab15Sopenharmony_ci fn default() -> ExtendedKeyUsage { 23892f3ab15Sopenharmony_ci ExtendedKeyUsage::new() 23992f3ab15Sopenharmony_ci } 24092f3ab15Sopenharmony_ci} 24192f3ab15Sopenharmony_ci 24292f3ab15Sopenharmony_ciimpl ExtendedKeyUsage { 24392f3ab15Sopenharmony_ci /// Construct a new `ExtendedKeyUsage` extension. 24492f3ab15Sopenharmony_ci pub fn new() -> ExtendedKeyUsage { 24592f3ab15Sopenharmony_ci ExtendedKeyUsage { 24692f3ab15Sopenharmony_ci critical: false, 24792f3ab15Sopenharmony_ci items: vec![], 24892f3ab15Sopenharmony_ci } 24992f3ab15Sopenharmony_ci } 25092f3ab15Sopenharmony_ci 25192f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 25292f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut ExtendedKeyUsage { 25392f3ab15Sopenharmony_ci self.critical = true; 25492f3ab15Sopenharmony_ci self 25592f3ab15Sopenharmony_ci } 25692f3ab15Sopenharmony_ci 25792f3ab15Sopenharmony_ci /// Sets the `serverAuth` flag to `true`. 25892f3ab15Sopenharmony_ci pub fn server_auth(&mut self) -> &mut ExtendedKeyUsage { 25992f3ab15Sopenharmony_ci self.other("serverAuth") 26092f3ab15Sopenharmony_ci } 26192f3ab15Sopenharmony_ci 26292f3ab15Sopenharmony_ci /// Sets the `clientAuth` flag to `true`. 26392f3ab15Sopenharmony_ci pub fn client_auth(&mut self) -> &mut ExtendedKeyUsage { 26492f3ab15Sopenharmony_ci self.other("clientAuth") 26592f3ab15Sopenharmony_ci } 26692f3ab15Sopenharmony_ci 26792f3ab15Sopenharmony_ci /// Sets the `codeSigning` flag to `true`. 26892f3ab15Sopenharmony_ci pub fn code_signing(&mut self) -> &mut ExtendedKeyUsage { 26992f3ab15Sopenharmony_ci self.other("codeSigning") 27092f3ab15Sopenharmony_ci } 27192f3ab15Sopenharmony_ci 27292f3ab15Sopenharmony_ci /// Sets the `emailProtection` flag to `true`. 27392f3ab15Sopenharmony_ci pub fn email_protection(&mut self) -> &mut ExtendedKeyUsage { 27492f3ab15Sopenharmony_ci self.other("emailProtection") 27592f3ab15Sopenharmony_ci } 27692f3ab15Sopenharmony_ci 27792f3ab15Sopenharmony_ci /// Sets the `timeStamping` flag to `true`. 27892f3ab15Sopenharmony_ci pub fn time_stamping(&mut self) -> &mut ExtendedKeyUsage { 27992f3ab15Sopenharmony_ci self.other("timeStamping") 28092f3ab15Sopenharmony_ci } 28192f3ab15Sopenharmony_ci 28292f3ab15Sopenharmony_ci /// Sets the `msCodeInd` flag to `true`. 28392f3ab15Sopenharmony_ci pub fn ms_code_ind(&mut self) -> &mut ExtendedKeyUsage { 28492f3ab15Sopenharmony_ci self.other("msCodeInd") 28592f3ab15Sopenharmony_ci } 28692f3ab15Sopenharmony_ci 28792f3ab15Sopenharmony_ci /// Sets the `msCodeCom` flag to `true`. 28892f3ab15Sopenharmony_ci pub fn ms_code_com(&mut self) -> &mut ExtendedKeyUsage { 28992f3ab15Sopenharmony_ci self.other("msCodeCom") 29092f3ab15Sopenharmony_ci } 29192f3ab15Sopenharmony_ci 29292f3ab15Sopenharmony_ci /// Sets the `msCTLSign` flag to `true`. 29392f3ab15Sopenharmony_ci pub fn ms_ctl_sign(&mut self) -> &mut ExtendedKeyUsage { 29492f3ab15Sopenharmony_ci self.other("msCTLSign") 29592f3ab15Sopenharmony_ci } 29692f3ab15Sopenharmony_ci 29792f3ab15Sopenharmony_ci /// Sets the `msSGC` flag to `true`. 29892f3ab15Sopenharmony_ci pub fn ms_sgc(&mut self) -> &mut ExtendedKeyUsage { 29992f3ab15Sopenharmony_ci self.other("msSGC") 30092f3ab15Sopenharmony_ci } 30192f3ab15Sopenharmony_ci 30292f3ab15Sopenharmony_ci /// Sets the `msEFS` flag to `true`. 30392f3ab15Sopenharmony_ci pub fn ms_efs(&mut self) -> &mut ExtendedKeyUsage { 30492f3ab15Sopenharmony_ci self.other("msEFS") 30592f3ab15Sopenharmony_ci } 30692f3ab15Sopenharmony_ci 30792f3ab15Sopenharmony_ci /// Sets the `nsSGC` flag to `true`. 30892f3ab15Sopenharmony_ci pub fn ns_sgc(&mut self) -> &mut ExtendedKeyUsage { 30992f3ab15Sopenharmony_ci self.other("nsSGC") 31092f3ab15Sopenharmony_ci } 31192f3ab15Sopenharmony_ci 31292f3ab15Sopenharmony_ci /// Sets a flag not already defined. 31392f3ab15Sopenharmony_ci pub fn other(&mut self, other: &str) -> &mut ExtendedKeyUsage { 31492f3ab15Sopenharmony_ci self.items.push(other.to_string()); 31592f3ab15Sopenharmony_ci self 31692f3ab15Sopenharmony_ci } 31792f3ab15Sopenharmony_ci 31892f3ab15Sopenharmony_ci /// Return the `ExtendedKeyUsage` extension as an `X509Extension`. 31992f3ab15Sopenharmony_ci pub fn build(&self) -> Result<X509Extension, ErrorStack> { 32092f3ab15Sopenharmony_ci let mut stack = Stack::new()?; 32192f3ab15Sopenharmony_ci for item in &self.items { 32292f3ab15Sopenharmony_ci stack.push(Asn1Object::from_str(item)?)?; 32392f3ab15Sopenharmony_ci } 32492f3ab15Sopenharmony_ci unsafe { 32592f3ab15Sopenharmony_ci X509Extension::new_internal(Nid::EXT_KEY_USAGE, self.critical, stack.as_ptr().cast()) 32692f3ab15Sopenharmony_ci } 32792f3ab15Sopenharmony_ci } 32892f3ab15Sopenharmony_ci} 32992f3ab15Sopenharmony_ci 33092f3ab15Sopenharmony_ci/// An extension that provides a means of identifying certificates that contain a 33192f3ab15Sopenharmony_ci/// particular public key. 33292f3ab15Sopenharmony_cipub struct SubjectKeyIdentifier { 33392f3ab15Sopenharmony_ci critical: bool, 33492f3ab15Sopenharmony_ci} 33592f3ab15Sopenharmony_ci 33692f3ab15Sopenharmony_ciimpl Default for SubjectKeyIdentifier { 33792f3ab15Sopenharmony_ci fn default() -> SubjectKeyIdentifier { 33892f3ab15Sopenharmony_ci SubjectKeyIdentifier::new() 33992f3ab15Sopenharmony_ci } 34092f3ab15Sopenharmony_ci} 34192f3ab15Sopenharmony_ci 34292f3ab15Sopenharmony_ciimpl SubjectKeyIdentifier { 34392f3ab15Sopenharmony_ci /// Construct a new `SubjectKeyIdentifier` extension. 34492f3ab15Sopenharmony_ci pub fn new() -> SubjectKeyIdentifier { 34592f3ab15Sopenharmony_ci SubjectKeyIdentifier { critical: false } 34692f3ab15Sopenharmony_ci } 34792f3ab15Sopenharmony_ci 34892f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 34992f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut SubjectKeyIdentifier { 35092f3ab15Sopenharmony_ci self.critical = true; 35192f3ab15Sopenharmony_ci self 35292f3ab15Sopenharmony_ci } 35392f3ab15Sopenharmony_ci 35492f3ab15Sopenharmony_ci /// Return a `SubjectKeyIdentifier` extension as an `X509Extension`. 35592f3ab15Sopenharmony_ci // Temporarily silence the deprecation warning - this should be ported to 35692f3ab15Sopenharmony_ci // `X509Extension::new_internal`. 35792f3ab15Sopenharmony_ci #[allow(deprecated)] 35892f3ab15Sopenharmony_ci pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> { 35992f3ab15Sopenharmony_ci let mut value = String::new(); 36092f3ab15Sopenharmony_ci let mut first = true; 36192f3ab15Sopenharmony_ci append(&mut value, &mut first, self.critical, "critical"); 36292f3ab15Sopenharmony_ci append(&mut value, &mut first, true, "hash"); 36392f3ab15Sopenharmony_ci X509Extension::new_nid(None, Some(ctx), Nid::SUBJECT_KEY_IDENTIFIER, &value) 36492f3ab15Sopenharmony_ci } 36592f3ab15Sopenharmony_ci} 36692f3ab15Sopenharmony_ci 36792f3ab15Sopenharmony_ci/// An extension that provides a means of identifying the public key corresponding 36892f3ab15Sopenharmony_ci/// to the private key used to sign a CRL. 36992f3ab15Sopenharmony_cipub struct AuthorityKeyIdentifier { 37092f3ab15Sopenharmony_ci critical: bool, 37192f3ab15Sopenharmony_ci keyid: Option<bool>, 37292f3ab15Sopenharmony_ci issuer: Option<bool>, 37392f3ab15Sopenharmony_ci} 37492f3ab15Sopenharmony_ci 37592f3ab15Sopenharmony_ciimpl Default for AuthorityKeyIdentifier { 37692f3ab15Sopenharmony_ci fn default() -> AuthorityKeyIdentifier { 37792f3ab15Sopenharmony_ci AuthorityKeyIdentifier::new() 37892f3ab15Sopenharmony_ci } 37992f3ab15Sopenharmony_ci} 38092f3ab15Sopenharmony_ci 38192f3ab15Sopenharmony_ciimpl AuthorityKeyIdentifier { 38292f3ab15Sopenharmony_ci /// Construct a new `AuthorityKeyIdentifier` extension. 38392f3ab15Sopenharmony_ci pub fn new() -> AuthorityKeyIdentifier { 38492f3ab15Sopenharmony_ci AuthorityKeyIdentifier { 38592f3ab15Sopenharmony_ci critical: false, 38692f3ab15Sopenharmony_ci keyid: None, 38792f3ab15Sopenharmony_ci issuer: None, 38892f3ab15Sopenharmony_ci } 38992f3ab15Sopenharmony_ci } 39092f3ab15Sopenharmony_ci 39192f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 39292f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut AuthorityKeyIdentifier { 39392f3ab15Sopenharmony_ci self.critical = true; 39492f3ab15Sopenharmony_ci self 39592f3ab15Sopenharmony_ci } 39692f3ab15Sopenharmony_ci 39792f3ab15Sopenharmony_ci /// Sets the `keyid` flag. 39892f3ab15Sopenharmony_ci pub fn keyid(&mut self, always: bool) -> &mut AuthorityKeyIdentifier { 39992f3ab15Sopenharmony_ci self.keyid = Some(always); 40092f3ab15Sopenharmony_ci self 40192f3ab15Sopenharmony_ci } 40292f3ab15Sopenharmony_ci 40392f3ab15Sopenharmony_ci /// Sets the `issuer` flag. 40492f3ab15Sopenharmony_ci pub fn issuer(&mut self, always: bool) -> &mut AuthorityKeyIdentifier { 40592f3ab15Sopenharmony_ci self.issuer = Some(always); 40692f3ab15Sopenharmony_ci self 40792f3ab15Sopenharmony_ci } 40892f3ab15Sopenharmony_ci 40992f3ab15Sopenharmony_ci /// Return a `AuthorityKeyIdentifier` extension as an `X509Extension`. 41092f3ab15Sopenharmony_ci // Temporarily silence the deprecation warning - this should be ported to 41192f3ab15Sopenharmony_ci // `X509Extension::new_internal`. 41292f3ab15Sopenharmony_ci #[allow(deprecated)] 41392f3ab15Sopenharmony_ci pub fn build(&self, ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> { 41492f3ab15Sopenharmony_ci let mut value = String::new(); 41592f3ab15Sopenharmony_ci let mut first = true; 41692f3ab15Sopenharmony_ci append(&mut value, &mut first, self.critical, "critical"); 41792f3ab15Sopenharmony_ci match self.keyid { 41892f3ab15Sopenharmony_ci Some(true) => append(&mut value, &mut first, true, "keyid:always"), 41992f3ab15Sopenharmony_ci Some(false) => append(&mut value, &mut first, true, "keyid"), 42092f3ab15Sopenharmony_ci None => {} 42192f3ab15Sopenharmony_ci } 42292f3ab15Sopenharmony_ci match self.issuer { 42392f3ab15Sopenharmony_ci Some(true) => append(&mut value, &mut first, true, "issuer:always"), 42492f3ab15Sopenharmony_ci Some(false) => append(&mut value, &mut first, true, "issuer"), 42592f3ab15Sopenharmony_ci None => {} 42692f3ab15Sopenharmony_ci } 42792f3ab15Sopenharmony_ci X509Extension::new_nid(None, Some(ctx), Nid::AUTHORITY_KEY_IDENTIFIER, &value) 42892f3ab15Sopenharmony_ci } 42992f3ab15Sopenharmony_ci} 43092f3ab15Sopenharmony_ci 43192f3ab15Sopenharmony_cienum RustGeneralName { 43292f3ab15Sopenharmony_ci Dns(String), 43392f3ab15Sopenharmony_ci Email(String), 43492f3ab15Sopenharmony_ci Uri(String), 43592f3ab15Sopenharmony_ci Ip(String), 43692f3ab15Sopenharmony_ci Rid(String), 43792f3ab15Sopenharmony_ci OtherName(Asn1Object, Vec<u8>), 43892f3ab15Sopenharmony_ci} 43992f3ab15Sopenharmony_ci 44092f3ab15Sopenharmony_ci/// An extension that allows additional identities to be bound to the subject 44192f3ab15Sopenharmony_ci/// of the certificate. 44292f3ab15Sopenharmony_cipub struct SubjectAlternativeName { 44392f3ab15Sopenharmony_ci critical: bool, 44492f3ab15Sopenharmony_ci items: Vec<RustGeneralName>, 44592f3ab15Sopenharmony_ci} 44692f3ab15Sopenharmony_ci 44792f3ab15Sopenharmony_ciimpl Default for SubjectAlternativeName { 44892f3ab15Sopenharmony_ci fn default() -> SubjectAlternativeName { 44992f3ab15Sopenharmony_ci SubjectAlternativeName::new() 45092f3ab15Sopenharmony_ci } 45192f3ab15Sopenharmony_ci} 45292f3ab15Sopenharmony_ci 45392f3ab15Sopenharmony_ciimpl SubjectAlternativeName { 45492f3ab15Sopenharmony_ci /// Construct a new `SubjectAlternativeName` extension. 45592f3ab15Sopenharmony_ci pub fn new() -> SubjectAlternativeName { 45692f3ab15Sopenharmony_ci SubjectAlternativeName { 45792f3ab15Sopenharmony_ci critical: false, 45892f3ab15Sopenharmony_ci items: vec![], 45992f3ab15Sopenharmony_ci } 46092f3ab15Sopenharmony_ci } 46192f3ab15Sopenharmony_ci 46292f3ab15Sopenharmony_ci /// Sets the `critical` flag to `true`. The extension will be critical. 46392f3ab15Sopenharmony_ci pub fn critical(&mut self) -> &mut SubjectAlternativeName { 46492f3ab15Sopenharmony_ci self.critical = true; 46592f3ab15Sopenharmony_ci self 46692f3ab15Sopenharmony_ci } 46792f3ab15Sopenharmony_ci 46892f3ab15Sopenharmony_ci /// Sets the `email` flag. 46992f3ab15Sopenharmony_ci pub fn email(&mut self, email: &str) -> &mut SubjectAlternativeName { 47092f3ab15Sopenharmony_ci self.items.push(RustGeneralName::Email(email.to_string())); 47192f3ab15Sopenharmony_ci self 47292f3ab15Sopenharmony_ci } 47392f3ab15Sopenharmony_ci 47492f3ab15Sopenharmony_ci /// Sets the `uri` flag. 47592f3ab15Sopenharmony_ci pub fn uri(&mut self, uri: &str) -> &mut SubjectAlternativeName { 47692f3ab15Sopenharmony_ci self.items.push(RustGeneralName::Uri(uri.to_string())); 47792f3ab15Sopenharmony_ci self 47892f3ab15Sopenharmony_ci } 47992f3ab15Sopenharmony_ci 48092f3ab15Sopenharmony_ci /// Sets the `dns` flag. 48192f3ab15Sopenharmony_ci pub fn dns(&mut self, dns: &str) -> &mut SubjectAlternativeName { 48292f3ab15Sopenharmony_ci self.items.push(RustGeneralName::Dns(dns.to_string())); 48392f3ab15Sopenharmony_ci self 48492f3ab15Sopenharmony_ci } 48592f3ab15Sopenharmony_ci 48692f3ab15Sopenharmony_ci /// Sets the `rid` flag. 48792f3ab15Sopenharmony_ci pub fn rid(&mut self, rid: &str) -> &mut SubjectAlternativeName { 48892f3ab15Sopenharmony_ci self.items.push(RustGeneralName::Rid(rid.to_string())); 48992f3ab15Sopenharmony_ci self 49092f3ab15Sopenharmony_ci } 49192f3ab15Sopenharmony_ci 49292f3ab15Sopenharmony_ci /// Sets the `ip` flag. 49392f3ab15Sopenharmony_ci pub fn ip(&mut self, ip: &str) -> &mut SubjectAlternativeName { 49492f3ab15Sopenharmony_ci self.items.push(RustGeneralName::Ip(ip.to_string())); 49592f3ab15Sopenharmony_ci self 49692f3ab15Sopenharmony_ci } 49792f3ab15Sopenharmony_ci 49892f3ab15Sopenharmony_ci /// Sets the `dirName` flag. 49992f3ab15Sopenharmony_ci /// 50092f3ab15Sopenharmony_ci /// Not currently actually supported, always panics. 50192f3ab15Sopenharmony_ci #[deprecated = "dir_name is deprecated and always panics. Please file a bug if you have a use case for this."] 50292f3ab15Sopenharmony_ci pub fn dir_name(&mut self, _dir_name: &str) -> &mut SubjectAlternativeName { 50392f3ab15Sopenharmony_ci unimplemented!( 50492f3ab15Sopenharmony_ci "This has not yet been adapted for the new internals. File a bug if you need this." 50592f3ab15Sopenharmony_ci ); 50692f3ab15Sopenharmony_ci } 50792f3ab15Sopenharmony_ci 50892f3ab15Sopenharmony_ci /// Sets the `otherName` flag. 50992f3ab15Sopenharmony_ci /// 51092f3ab15Sopenharmony_ci /// Not currently actually supported, always panics. Please use other_name2 51192f3ab15Sopenharmony_ci #[deprecated = "other_name is deprecated and always panics. Please use other_name2."] 51292f3ab15Sopenharmony_ci pub fn other_name(&mut self, _other_name: &str) -> &mut SubjectAlternativeName { 51392f3ab15Sopenharmony_ci unimplemented!("This has not yet been adapted for the new internals. Use other_name2."); 51492f3ab15Sopenharmony_ci } 51592f3ab15Sopenharmony_ci 51692f3ab15Sopenharmony_ci /// Sets the `otherName` flag. 51792f3ab15Sopenharmony_ci /// 51892f3ab15Sopenharmony_ci /// `content` must be a valid der encoded ASN1_TYPE 51992f3ab15Sopenharmony_ci /// 52092f3ab15Sopenharmony_ci /// If you want to add just a ia5string use `other_name_ia5string` 52192f3ab15Sopenharmony_ci pub fn other_name2(&mut self, oid: Asn1Object, content: &[u8]) -> &mut SubjectAlternativeName { 52292f3ab15Sopenharmony_ci self.items 52392f3ab15Sopenharmony_ci .push(RustGeneralName::OtherName(oid, content.into())); 52492f3ab15Sopenharmony_ci self 52592f3ab15Sopenharmony_ci } 52692f3ab15Sopenharmony_ci 52792f3ab15Sopenharmony_ci /// Return a `SubjectAlternativeName` extension as an `X509Extension`. 52892f3ab15Sopenharmony_ci pub fn build(&self, _ctx: &X509v3Context<'_>) -> Result<X509Extension, ErrorStack> { 52992f3ab15Sopenharmony_ci let mut stack = Stack::new()?; 53092f3ab15Sopenharmony_ci for item in &self.items { 53192f3ab15Sopenharmony_ci let gn = match item { 53292f3ab15Sopenharmony_ci RustGeneralName::Dns(s) => GeneralName::new_dns(s.as_bytes())?, 53392f3ab15Sopenharmony_ci RustGeneralName::Email(s) => GeneralName::new_email(s.as_bytes())?, 53492f3ab15Sopenharmony_ci RustGeneralName::Uri(s) => GeneralName::new_uri(s.as_bytes())?, 53592f3ab15Sopenharmony_ci RustGeneralName::Ip(s) => { 53692f3ab15Sopenharmony_ci GeneralName::new_ip(s.parse().map_err(|_| ErrorStack::get())?)? 53792f3ab15Sopenharmony_ci } 53892f3ab15Sopenharmony_ci RustGeneralName::Rid(s) => GeneralName::new_rid(Asn1Object::from_str(s)?)?, 53992f3ab15Sopenharmony_ci RustGeneralName::OtherName(oid, content) => { 54092f3ab15Sopenharmony_ci GeneralName::new_other_name(oid.clone(), content)? 54192f3ab15Sopenharmony_ci } 54292f3ab15Sopenharmony_ci }; 54392f3ab15Sopenharmony_ci stack.push(gn)?; 54492f3ab15Sopenharmony_ci } 54592f3ab15Sopenharmony_ci 54692f3ab15Sopenharmony_ci unsafe { 54792f3ab15Sopenharmony_ci X509Extension::new_internal(Nid::SUBJECT_ALT_NAME, self.critical, stack.as_ptr().cast()) 54892f3ab15Sopenharmony_ci } 54992f3ab15Sopenharmony_ci } 55092f3ab15Sopenharmony_ci} 55192f3ab15Sopenharmony_ci 55292f3ab15Sopenharmony_cifn append(value: &mut String, first: &mut bool, should: bool, element: &str) { 55392f3ab15Sopenharmony_ci if !should { 55492f3ab15Sopenharmony_ci return; 55592f3ab15Sopenharmony_ci } 55692f3ab15Sopenharmony_ci 55792f3ab15Sopenharmony_ci if !*first { 55892f3ab15Sopenharmony_ci value.push(','); 55992f3ab15Sopenharmony_ci } 56092f3ab15Sopenharmony_ci *first = false; 56192f3ab15Sopenharmony_ci value.push_str(element); 56292f3ab15Sopenharmony_ci} 563