diff options
Diffstat (limited to 'src/ext/pkix/keyusage.rs')
-rw-r--r-- | src/ext/pkix/keyusage.rs | 119 |
1 files changed, 117 insertions, 2 deletions
diff --git a/src/ext/pkix/keyusage.rs b/src/ext/pkix/keyusage.rs index cd051fe..833db69 100644 --- a/src/ext/pkix/keyusage.rs +++ b/src/ext/pkix/keyusage.rs @@ -1,12 +1,12 @@ use alloc::vec::Vec; use const_oid::db::rfc5280::{ - ID_CE_EXT_KEY_USAGE, ID_CE_KEY_USAGE, ID_CE_PRIVATE_KEY_USAGE_PERIOD, + ANY_EXTENDED_KEY_USAGE, ID_CE_EXT_KEY_USAGE, ID_CE_KEY_USAGE, ID_CE_PRIVATE_KEY_USAGE_PERIOD, }; use const_oid::AssociatedOid; use der::asn1::{GeneralizedTime, ObjectIdentifier}; +use der::flagset::{flags, FlagSet}; use der::Sequence; -use flagset::{flags, FlagSet}; flags! { /// Key usage flags as defined in [RFC 5280 Section 4.2.1.3]. @@ -52,6 +52,66 @@ impl AssociatedOid for KeyUsage { } impl_newtype!(KeyUsage, FlagSet<KeyUsages>); +impl_extension!(KeyUsage, critical = true); + +impl KeyUsage { + /// The subject public key is used for verifying digital signatures + pub fn digital_signature(&self) -> bool { + self.0.contains(KeyUsages::DigitalSignature) + } + + /// When the subject public key is used to verify digital signatures, + /// it is asserted as non-repudiation. + pub fn non_repudiation(&self) -> bool { + self.0.contains(KeyUsages::NonRepudiation) + } + + /// The subject public key is used for enciphering private or + /// secret keys, i.e., for key transport. + pub fn key_encipherment(&self) -> bool { + self.0.contains(KeyUsages::KeyEncipherment) + } + + /// The subject public key is used for directly enciphering + /// raw user data without the use of an intermediate symmetric cipher. + pub fn data_encipherment(&self) -> bool { + self.0.contains(KeyUsages::DataEncipherment) + } + + /// The subject public key is used for key agreement + pub fn key_agreement(&self) -> bool { + self.0.contains(KeyUsages::KeyAgreement) + } + + /// The subject public key is used for enciphering private or + /// secret keys, i.e., for key transport. + pub fn key_cert_sign(&self) -> bool { + self.0.contains(KeyUsages::KeyCertSign) + } + + /// The subject public key is used for verifying signatures + /// on certificate revocation lists (e.g., CRLs, delta CRLs, + /// or ARLs). + pub fn crl_sign(&self) -> bool { + self.0.contains(KeyUsages::CRLSign) + } + + /// The meaning of the `encipher_only` is undefined when `key_agreement` + /// returns false. When `encipher_only` returns true and + /// `key_agreement` also returns true, the subject public key may be + /// used only for enciphering data while performing key agreement. + pub fn encipher_only(&self) -> bool { + self.0.contains(KeyUsages::EncipherOnly) + } + + /// The meaning of the `decipher_only` is undefined when `key_agreement` + /// returns false. When `encipher_only` returns true and + /// `key_agreement` also returns true, the subject public key may be + /// used only for deciphering data while performing key agreement. + pub fn decipher_only(&self) -> bool { + self.0.contains(KeyUsages::DecipherOnly) + } +} /// ExtKeyUsageSyntax as defined in [RFC 5280 Section 4.2.1.12]. /// @@ -78,6 +138,30 @@ impl AssociatedOid for ExtendedKeyUsage { impl_newtype!(ExtendedKeyUsage, Vec<ObjectIdentifier>); +impl crate::ext::AsExtension for ExtendedKeyUsage { + fn critical( + &self, + _subject: &crate::name::Name, + _extensions: &[crate::ext::Extension], + ) -> bool { + // https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.12 + // This extension MAY, at the option of the certificate issuer, be + // either critical or non-critical. + // + // If a CA includes extended key usages to satisfy such applications, + // but does not wish to restrict usages of the key, the CA can include + // the special KeyPurposeId anyExtendedKeyUsage in addition to the + // particular key purposes required by the applications. Conforming CAs + // SHOULD NOT mark this extension as critical if the anyExtendedKeyUsage + // KeyPurposeId is present. Applications that require the presence of a + // particular purpose MAY reject certificates that include the + // anyExtendedKeyUsage OID but not the particular OID expected for the + // application. + + !self.0.iter().any(|el| *el == ANY_EXTENDED_KEY_USAGE) + } +} + /// PrivateKeyUsagePeriod as defined in [RFC 3280 Section 4.2.1.4]. /// /// RFC 5280 states "use of this ISO standard extension is neither deprecated nor recommended for use in the Internet PKI." @@ -103,3 +187,34 @@ pub struct PrivateKeyUsagePeriod { impl AssociatedOid for PrivateKeyUsagePeriod { const OID: ObjectIdentifier = ID_CE_PRIVATE_KEY_USAGE_PERIOD; } + +impl_extension!(PrivateKeyUsagePeriod, critical = false); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn digital_signature_contains_digital_signature() { + let key_usage = KeyUsage(KeyUsages::DigitalSignature.into()); + assert!(key_usage.digital_signature()); + } + + #[test] + fn all_contains_digital_signature() { + let key_usage = KeyUsage(FlagSet::full()); + assert!(key_usage.digital_signature()); + } + + #[test] + fn key_encipherment_not_contains_digital_signature() { + let key_usage = KeyUsage(KeyUsages::KeyEncipherment.into()); + assert!(!key_usage.digital_signature()); + } + + #[test] + fn empty_not_contains_digital_signature() { + let key_usage = KeyUsage(None.into()); + assert!(!key_usage.digital_signature()); + } +} |