diff options
author | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-04-20 09:42:57 +0200 |
---|---|---|
committer | Wiktor Kwapisiewicz <wiktor@metacode.biz> | 2021-05-10 09:29:46 +0200 |
commit | 6d3d83b26905add0b0f9a6aa40afdb0bb4832b05 (patch) | |
tree | d68366152adb622bc40657de2bf9d842ee2f97b9 /openpgp | |
parent | b656f4f9fb8706de1e0e470b0ca46cc581333331 (diff) |
openpgp: Implement TryFrom<SignatureBuilder> for cert::*RevocationBuilder.
- Add implementations of std::convert::TryFrom<SignatureBuilder> for
both: CertRevocationBuilder and SubkeyRevocationBuilder.
- Add unit tests checking that the conversion succeeds and fails,
based on the SignatureBuilder type.
- Fixes #678.
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/src/cert/revoke.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/openpgp/src/cert/revoke.rs b/openpgp/src/cert/revoke.rs index 7cc5ca60..738853cb 100644 --- a/openpgp/src/cert/revoke.rs +++ b/openpgp/src/cert/revoke.rs @@ -1,3 +1,4 @@ +use std::convert::TryFrom; use std::ops::Deref; use std::time; @@ -240,6 +241,21 @@ impl Deref for CertRevocationBuilder { } } +impl TryFrom<signature::SignatureBuilder> for CertRevocationBuilder { + type Error = anyhow::Error; + + fn try_from(builder: signature::SignatureBuilder) -> Result<Self> { + if builder.typ() != SignatureType::KeyRevocation { + return Err( + crate::Error::InvalidArgument( + format!("Expected signature type to be KeyRevocation but got {}", + builder.typ()).into()).into()); + } + Ok(Self { + builder + }) + } +} /// A builder for revocation certificates for subkeys. /// @@ -469,6 +485,22 @@ impl Deref for SubkeyRevocationBuilder { } } +impl TryFrom<signature::SignatureBuilder> for SubkeyRevocationBuilder { + type Error = anyhow::Error; + + fn try_from(builder: signature::SignatureBuilder) -> Result<Self> { + if builder.typ() != SignatureType::SubkeyRevocation { + return Err( + crate::Error::InvalidArgument( + format!("Expected signature type to be SubkeyRevocation but got {}", + builder.typ()).into()).into()); + } + Ok(Self { + builder + }) + } +} + /// A builder for revocation certificates for User ID. /// /// A revocation certificate for a [User ID] has three degrees of @@ -954,3 +986,81 @@ impl Deref for UserAttributeRevocationBuilder { &self.builder } } + +#[cfg(test)] +mod tests { + #[test] + fn try_into_cert_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::CertRevocationBuilder; + use openpgp::types::SignatureType; + + let (cert, _) = CertBuilder::new() + .generate()?; + + // Create and sign a revocation certificate. + let mut signer = cert.primary_key().key().clone() + .parts_into_secret()?.into_keypair()?; + let builder = SignatureBuilder::new(SignatureType::KeyRevocation); + let revocation_builder: CertRevocationBuilder = builder.try_into()?; + let sig = revocation_builder.build(&mut signer, &cert, None)?; + assert_eq!(sig.typ(), SignatureType::KeyRevocation); + Ok(()) + } + + #[test] + fn try_into_cert_revocation_builder_failure() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::cert::CertRevocationBuilder; + use openpgp::types::SignatureType; + + let builder = SignatureBuilder::new(SignatureType::Binary); + let result: openpgp::Result<CertRevocationBuilder> = builder.try_into(); + assert!(result.is_err()); + Ok(()) + } + + #[test] + fn try_into_subkey_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::SubkeyRevocationBuilder; + use openpgp::types::SignatureType; + + let (cert, _) = CertBuilder::new() + .add_transport_encryption_subkey() + .generate()?; + + // Create and sign a revocation certificate. + let mut signer = cert.primary_key().key().clone() + .parts_into_secret()?.into_keypair()?; + let subkey = cert.keys().subkeys().nth(0).unwrap(); + let builder = SignatureBuilder::new(SignatureType::SubkeyRevocation); + let revocation_builder: SubkeyRevocationBuilder = builder.try_into()?; + let sig = revocation_builder.build(&mut signer, &cert, subkey.key(), None)?; + assert_eq!(sig.typ(), SignatureType::SubkeyRevocation); + Ok(()) + } + + #[test] + fn try_into_subkey_revocation_builder_failure() -> crate::Result<()> { + use std::convert::TryInto; + use crate as openpgp; + use openpgp::packet::signature::SignatureBuilder; + use openpgp::cert::SubkeyRevocationBuilder; + use openpgp::types::SignatureType; + + let builder = SignatureBuilder::new(SignatureType::Binary); + let result: openpgp::Result<SubkeyRevocationBuilder> = builder.try_into(); + assert!(result.is_err()); + Ok(()) + } + +} |