aboutsummaryrefslogtreecommitdiff
path: root/src/ext/pkix/keyusage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/pkix/keyusage.rs')
-rw-r--r--src/ext/pkix/keyusage.rs119
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());
+ }
+}