summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWiktor Kwapisiewicz <wiktor@metacode.biz>2021-05-12 13:32:49 +0200
committerWiktor Kwapisiewicz <wiktor@metacode.biz>2021-05-12 13:32:49 +0200
commita92061fac8cd9b694fed0ebe3c9c6e7b6ec4425e (patch)
tree8f539b3e8f8032c439cd94d30340951a9c9c9848
parent6d3d83b26905add0b0f9a6aa40afdb0bb4832b05 (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.rs112
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(())
+ }
}