diff options
author | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-05-12 13:32:49 +0200 |
---|---|---|
committer | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-05-12 13:32:49 +0200 |
commit | a92061fac8cd9b694fed0ebe3c9c6e7b6ec4425e (patch) | |
tree | 8f539b3e8f8032c439cd94d30340951a9c9c9848 | |
parent | 6d3d83b26905add0b0f9a6aa40afdb0bb4832b05 (diff) |
openpgp: Implement TryFrom<SignatureBuilder> for more types.
- Add implementation of std::convert::TryFrom<SignatureBuilder> for
UserIDRevocationBuilder and UserAttributeRevocationBuilder.
- Add unit tests checking if proper signature types are passed there.
- Fixes #678.
-rw-r--r-- | openpgp/src/cert/revoke.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/openpgp/src/cert/revoke.rs b/openpgp/src/cert/revoke.rs index 738853cb..fbde622d 100644 --- a/openpgp/src/cert/revoke.rs +++ b/openpgp/src/cert/revoke.rs @@ -737,6 +737,22 @@ impl Deref for UserIDRevocationBuilder { } } +impl TryFrom<signature::SignatureBuilder> for UserIDRevocationBuilder { + type Error = anyhow::Error; + + fn try_from(builder: signature::SignatureBuilder) -> Result<Self> { + if builder.typ() != SignatureType::CertificationRevocation { + return Err( + crate::Error::InvalidArgument( + format!("Expected signature type to be CertificationRevocation but got {}", + builder.typ()).into()).into()); + } + Ok(Self { + builder + }) + } +} + /// A builder for revocation certificates for User Attributes. /// /// A revocation certificate for a [User Attribute] has three degrees of @@ -987,6 +1003,22 @@ impl Deref for UserAttributeRevocationBuilder { } } +impl TryFrom<signature::SignatureBuilder> for UserAttributeRevocationBuilder { + type Error = anyhow::Error; + + fn try_from(builder: signature::SignatureBuilder) -> Result<Self> { + if builder.typ() != SignatureType::CertificationRevocation { + return Err( + crate::Error::InvalidArgument( + format!("Expected signature type to be CertificationRevocation but got {}", + builder.typ()).into()).into()); + } + Ok(Self { + builder + }) + } +} + #[cfg(test)] mod tests { #[test] @@ -1063,4 +1095,84 @@ mod tests { Ok(()) } + #[test] + fn try_into_userid_revocation_builder_success() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::cert::prelude::*; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::cert::UserIDRevocationBuilder; + use openpgp::types::SignatureType; + + let (cert, _) = CertBuilder::new() + .add_userid("test@example.com") + .generate()?; + + // Create and sign a revocation certificate. + let mut signer = cert.primary_key().key().clone() + .parts_into_secret()?.into_keypair()?; + let user_id = cert.userids().next().unwrap(); + let builder = SignatureBuilder::new(SignatureType::CertificationRevocation); + let revocation_builder: UserIDRevocationBuilder = builder.try_into()?; + let sig = revocation_builder.build(&mut signer, &cert, &user_id, None)?; + assert_eq!(sig.typ(), SignatureType::CertificationRevocation); + Ok(()) + } + + #[test] + fn try_into_userid_revocation_builder_failure() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::cert::UserIDRevocationBuilder; + use openpgp::types::SignatureType; + + let builder = SignatureBuilder::new(SignatureType::Binary); + let result: openpgp::Result<UserIDRevocationBuilder> = builder.try_into(); + assert!(result.is_err()); + Ok(()) + } + + #[test] + fn try_into_userattribute_revocation_builder_success() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::cert::prelude::*; + use openpgp::packet::prelude::*; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::packet::user_attribute::Subpacket; + use openpgp::cert::UserAttributeRevocationBuilder; + use openpgp::types::SignatureType; + + let sp = Subpacket::Unknown(7, vec![7; 7].into_boxed_slice()); + let user_attribute = UserAttribute::new(&[sp])?; + + let (cert, _) = CertBuilder::new() + .add_user_attribute(user_attribute) + .generate()?; + + // Create and sign a revocation certificate. + let mut signer = cert.primary_key().key().clone() + .parts_into_secret()?.into_keypair()?; + let user_attribute = cert.user_attributes().next().unwrap(); + let builder = SignatureBuilder::new(SignatureType::CertificationRevocation); + let revocation_builder: UserAttributeRevocationBuilder = builder.try_into()?; + let sig = revocation_builder.build(&mut signer, &cert, &user_attribute, None)?; + assert_eq!(sig.typ(), SignatureType::CertificationRevocation); + Ok(()) + } + + #[test] + fn try_into_userattribute_revocation_builder_failure() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::cert::UserAttributeRevocationBuilder; + use openpgp::types::SignatureType; + + let builder = SignatureBuilder::new(SignatureType::Binary); + let result: openpgp::Result<UserAttributeRevocationBuilder> = builder.try_into(); + assert!(result.is_err()); + Ok(()) + } } |