summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorWiktor Kwapisiewicz <wiktor@metacode.biz>2021-04-20 09:42:57 +0200
committerWiktor Kwapisiewicz <wiktor@metacode.biz>2021-05-10 09:29:46 +0200
commit6d3d83b26905add0b0f9a6aa40afdb0bb4832b05 (patch)
treed68366152adb622bc40657de2bf9d842ee2f97b9 /openpgp
parentb656f4f9fb8706de1e0e470b0ca46cc581333331 (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.rs110
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(())
+ }
+
+}