summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-04-25 14:21:45 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-04-26 16:26:25 +0200
commita1e226f8f1418de43e577fdaa1d087b68bbb09ae (patch)
treebc27b8a4f93fc7cd5ecd51a4650f4a3c48db8cdb
parent3d9712ad2244d93f6c0b93254464bd17fb71b2b2 (diff)
openpgp: Add interface to bind, certify, and revoke.
- This adds a flexible interface to create binding signatures, certificates, and revocation signatures for userids, user attributes, and subkeys.
-rw-r--r--openpgp/src/tpk/bindings.rs531
-rw-r--r--openpgp/src/tpk/mod.rs23
2 files changed, 536 insertions, 18 deletions
diff --git a/openpgp/src/tpk/bindings.rs b/openpgp/src/tpk/bindings.rs
new file mode 100644
index 00000000..eb355df0
--- /dev/null
+++ b/openpgp/src/tpk/bindings.rs
@@ -0,0 +1,531 @@
+use Error;
+use Result;
+use TPK;
+use constants::{HashAlgorithm, SignatureType, ReasonForRevocation};
+use crypto::Signer;
+use packet::{UserID, UserAttribute, Key, signature, Signature};
+
+impl Key {
+ /// Creates a binding signature.
+ ///
+ /// The signature binds this userid to `tpk`. `signer` will be used
+ /// to create a signature using `signature` as builder.
+ /// The`hash_algo` defaults to SHA512, `creation_time` to the
+ /// current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// This example demonstrates how to bind this key to a TPK. Note
+ /// that in general, the `TPKBuilder` is a better way to add
+ /// subkeys to a TPK.
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::prelude::*, constants::*, tpk::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (tpk, _) = TPKBuilder::default().generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ ///
+ /// // Let's add an encryption subkey.
+ /// let flags = KeyFlags::default().set_encrypt_at_rest(true);
+ /// assert_eq!(tpk.keys_valid().key_flags(flags.clone()).count(), 0);
+ ///
+ /// // Generate a subkey and a binding signature.
+ /// let subkey = Key::V4(Key4::generate_ecc(false, Curve::Cv25519)?);
+ /// let builder = signature::Builder::new(SignatureType::SubkeyBinding)
+ /// .set_key_flags(&flags)?;
+ /// let binding = subkey.bind(&mut keypair, &tpk, builder, None, None)?;
+ ///
+ /// // Now merge the key and binding signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![subkey.into_packet(Tag::SecretSubkey)?,
+ /// binding.into()])?;
+ ///
+ /// // Check that we have an encryption subkey.
+ /// assert_eq!(tpk.keys_valid().key_flags(flags).count(), 1);
+ /// # Ok(()) }
+ pub fn bind<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ signature: signature::Builder,
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ signature
+ .set_signature_creation_time(
+ creation_time.into().unwrap_or_else(time::now_utc))?
+ .set_issuer_fingerprint(signer.public().fingerprint())?
+ .set_issuer(signer.public().keyid())?
+ .sign_subkey_binding(
+ signer, tpk.primary(), self,
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512))
+ }
+
+ /// Returns a revocation certificate for the subkey.
+ ///
+ /// The revocation signature revokes the binding between this user
+ /// attribute and `tpk`. `signer` will be used to create a
+ /// signature with the given reason in `code` and `reason`.
+ /// `signature_type`. `hash_algo` defaults to SHA512,
+ /// `creation_time` to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::*, constants::*, tpk::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (tpk, _) = TPKBuilder::default()
+ /// .add_encryption_subkey()
+ /// .generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ ///
+ /// // Generate the revocation for the first and only Subkey.
+ /// let revocation =
+ /// tpk.subkeys().nth(0).unwrap().subkey()
+ /// .revoke(&mut keypair, &tpk,
+ /// ReasonForRevocation::KeyRetired,
+ /// b"Smells funny.", None, None)?;
+ /// assert_eq!(revocation.sigtype(), SignatureType::SubkeyRevocation);
+ ///
+ /// // Now merge the revocation signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![revocation.clone().into()])?;
+ ///
+ /// // Check that it is revoked.
+ /// let subkey = tpk.subkeys().nth(0).unwrap();
+ /// if let RevocationStatus::Revoked(revocations) = subkey.revoked(None) {
+ /// assert_eq!(revocations.len(), 1);
+ /// assert_eq!(revocations[0], revocation);
+ /// } else {
+ /// panic!("Subkey is not revoked.");
+ /// }
+ /// # Ok(()) }
+ /// ```
+ pub fn revoke<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ code: ReasonForRevocation, reason: &[u8],
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ self.bind(signer, tpk,
+ signature::Builder::new(SignatureType::SubkeyRevocation)
+ .set_reason_for_revocation(code, reason)?,
+ // Unwrap arguments to prevent further
+ // monomorphization of bind().
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512),
+ creation_time.into().unwrap_or_else(time::now_utc))
+ }
+}
+
+impl UserID {
+ /// Creates a binding signature.
+ ///
+ /// The signature binds this userid to `tpk`. `signer` will be used
+ /// to create a signature using `signature` as builder.
+ /// The`hash_algo` defaults to SHA512, `creation_time` to the
+ /// current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// This example demonstrates how to bind this userid to a TPK.
+ /// Note that in general, the `TPKBuilder` is a better way to add
+ /// userids to a TPK.
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::prelude::*, constants::*, tpk::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (tpk, _) = TPKBuilder::default().generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ /// assert_eq!(tpk.userids().len(), 0);
+ ///
+ /// // Generate a userid and a binding signature.
+ /// let userid = UserID::from("test@example.org");
+ /// let builder =
+ /// signature::Builder::new(SignatureType::PositiveCertificate);
+ /// let binding = userid.bind(&mut keypair, &tpk, builder, None, None)?;
+ ///
+ /// // Now merge the userid and binding signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![userid.into(), binding.into()])?;
+ ///
+ /// // Check that we have a userid.
+ /// assert_eq!(tpk.userids().len(), 1);
+ /// # Ok(()) }
+ pub fn bind<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ signature: signature::Builder,
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ signature
+ .set_signature_creation_time(
+ creation_time.into().unwrap_or_else(time::now_utc))?
+ .set_issuer_fingerprint(signer.public().fingerprint())?
+ .set_issuer(signer.public().keyid())?
+ .sign_userid_binding(
+ signer, tpk.primary(), self,
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512))
+ }
+
+ /// Returns a certificate for the user id.
+ ///
+ /// The signature binds this userid to `tpk`. `signer` will be
+ /// used to create a certification signature of type
+ /// `signature_type`. `signature_type` defaults to
+ /// `SignatureType::GenericCertificate`, `hash_algo` to SHA512,
+ /// `creation_time` to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Errors
+ ///
+ /// Returns `Error::InvalidArgument` if `signature_type` is not
+ /// one of `SignatureType::{Generic, Persona, Casual,
+ /// Positive}Certificate`
+ ///
+ /// # Example
+ ///
+ /// This example demonstrates how to certify a userid.
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::prelude::*, constants::*, tpk::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (alice, _) = TPKBuilder::default()
+ /// .primary_keyflags(KeyFlags::default().set_certify(true))
+ /// .add_userid("alice@example.org")
+ /// .generate()?;
+ /// let mut keypair = alice.primary().clone().into_keypair()?;
+ ///
+ /// // Generate a TPK for Bob.
+ /// let (bob, _) = TPKBuilder::default()
+ /// .primary_keyflags(KeyFlags::default().set_certify(true))
+ /// .add_userid("bob@example.org")
+ /// .generate()?;
+ ///
+ /// // Alice now certifies the binding between `bob@example.org` and `bob`.
+ /// let certificate =
+ /// bob.userids().nth(0).unwrap().userid()
+ /// .certify(&mut keypair, &bob, SignatureType::PositiveCertificate,
+ /// None, None)?;
+ ///
+ /// // `certificate` can now be used, e.g. by merging it into `bob`.
+ /// let bob = bob.merge_packets(vec![certificate.into()])?;
+ ///
+ /// // Check that we have a certification on the userid.
+ /// assert_eq!(bob.userids().nth(0).unwrap().certifications().len(), 1);
+ /// # Ok(()) }
+ pub fn certify<S, H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ signature_type: S,
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where S: Into<Option<SignatureType>>,
+ H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ let typ = signature_type.into();
+ let typ = match typ {
+ Some(SignatureType::GenericCertificate)
+ | Some(SignatureType::PersonaCertificate)
+ | Some(SignatureType::CasualCertificate)
+ | Some(SignatureType::PositiveCertificate) => typ.unwrap(),
+ Some(t) => return Err(Error::InvalidArgument(
+ format!("Invalid signature type: {}", t)).into()),
+ None => SignatureType::GenericCertificate,
+ };
+ self.bind(signer, tpk, signature::Builder::new(typ),
+ // Unwrap arguments to prevent further
+ // monomorphization of bind().
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512),
+ creation_time.into().unwrap_or_else(time::now_utc))
+ }
+
+ /// Returns a revocation certificate for the user id.
+ ///
+ /// The revocation signature revokes the binding between this user
+ /// attribute and `tpk`. `signer` will be used to create a
+ /// signature with the given reason in `code` and `reason`.
+ /// `signature_type`. `hash_algo` defaults to SHA512,
+ /// `creation_time` to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, constants::*, tpk::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (tpk, _) = TPKBuilder::default()
+ /// .add_userid("some@example.org")
+ /// .generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ ///
+ /// // Generate the revocation for the first and only UserID.
+ /// let revocation =
+ /// tpk.userids().nth(0).unwrap().userid()
+ /// .revoke(&mut keypair, &tpk,
+ /// ReasonForRevocation::UIDRetired,
+ /// b"Left example.org.", None, None)?;
+ /// assert_eq!(revocation.sigtype(), SignatureType::CertificateRevocation);
+ ///
+ /// // Now merge the revocation signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![revocation.clone().into()])?;
+ ///
+ /// // Check that it is revoked.
+ /// let uid = tpk.userids().nth(0).unwrap();
+ /// if let RevocationStatus::Revoked(revocations) = uid.revoked(None) {
+ /// assert_eq!(revocations.len(), 1);
+ /// assert_eq!(revocations[0], revocation);
+ /// } else {
+ /// panic!("UserID is not revoked.");
+ /// }
+ /// # Ok(()) }
+ /// ```
+ pub fn revoke<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ code: ReasonForRevocation, reason: &[u8],
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ self.bind(signer, tpk,
+ signature::Builder::new(SignatureType::CertificateRevocation)
+ .set_reason_for_revocation(code, reason)?,
+ // Unwrap arguments to prevent further
+ // monomorphization of bind().
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512),
+ creation_time.into().unwrap_or_else(time::now_utc))
+ }
+}
+
+impl UserAttribute {
+ /// Creates a binding signature.
+ ///
+ /// The signature binds this user attribute to `tpk`. `signer`
+ /// will be used to create a signature using `signature` as
+ /// builder. The`hash_algo` defaults to SHA512, `creation_time`
+ /// to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// This example demonstrates how to bind this user attribute to a
+ /// TPK. Note that in general, the `TPKBuilder` is a better way
+ /// to add userids to a TPK.
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::prelude::*, constants::*, tpk::*,
+ /// packet::user_attribute::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (tpk, _) = TPKBuilder::default()
+ /// .generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ /// assert_eq!(tpk.userids().len(), 0);
+ ///
+ /// // Generate a user attribute and a binding signature.
+ /// let user_attr = UserAttribute::new(&[
+ /// Subpacket::Image(
+ /// Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
+ /// ])?;
+ /// let builder =
+ /// signature::Builder::new(SignatureType::PositiveCertificate);
+ /// let binding = user_attr.bind(&mut keypair, &tpk, builder, None, None)?;
+ ///
+ /// // Now merge the user attribute and binding signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![user_attr.into(), binding.into()])?;
+ ///
+ /// // Check that we have a user attribute.
+ /// assert_eq!(tpk.user_attributes().len(), 1);
+ /// # Ok(()) }
+ pub fn bind<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ signature: signature::Builder,
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ signature
+ .set_signature_creation_time(
+ creation_time.into().unwrap_or_else(time::now_utc))?
+ .set_issuer_fingerprint(signer.public().fingerprint())?
+ .set_issuer(signer.public().keyid())?
+ .sign_user_attribute_binding(
+ signer, tpk.primary(), self,
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512))
+ }
+
+ /// Returns a certificate for the user attribute.
+ ///
+ /// The signature binds this user attribute to `tpk`. `signer` will be
+ /// used to create a certification signature of type
+ /// `signature_type`. `signature_type` defaults to
+ /// `SignatureType::GenericCertificate`, `hash_algo` to SHA512,
+ /// `creation_time` to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Errors
+ ///
+ /// Returns `Error::InvalidArgument` if `signature_type` is not
+ /// one of `SignatureType::{Generic, Persona, Casual,
+ /// Positive}Certificate`
+ ///
+ /// # Example
+ ///
+ /// This example demonstrates how to certify a userid.
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, packet::prelude::*, constants::*, tpk::*,
+ /// packet::user_attribute::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let (alice, _) = TPKBuilder::default()
+ /// .add_userid("alice@example.org")
+ /// .generate()?;
+ /// let mut keypair = alice.primary().clone().into_keypair()?;
+ ///
+ /// // Generate a TPK for Bob.
+ /// let user_attr = UserAttribute::new(&[
+ /// Subpacket::Image(
+ /// Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
+ /// ])?;
+ /// let (bob, _) = TPKBuilder::default()
+ /// .primary_keyflags(KeyFlags::default().set_certify(true))
+ /// .add_user_attribute(user_attr)
+ /// .generate()?;
+ ///
+ /// // Alice now certifies the binding between `bob@example.org` and `bob`.
+ /// let certificate =
+ /// bob.user_attributes().nth(0).unwrap().user_attribute()
+ /// .certify(&mut keypair, &bob, SignatureType::PositiveCertificate,
+ /// None, None)?;
+ ///
+ /// // `certificate` can now be used, e.g. by merging it into `bob`.
+ /// let bob = bob.merge_packets(vec![certificate.into()])?;
+ ///
+ /// // Check that we have a certification on the userid.
+ /// assert_eq!(bob.user_attributes().nth(0).unwrap().certifications().len(),
+ /// 1);
+ /// # Ok(()) }
+ pub fn certify<S, H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ signature_type: S,
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where S: Into<Option<SignatureType>>,
+ H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ let typ = signature_type.into();
+ let typ = match typ {
+ Some(SignatureType::GenericCertificate)
+ | Some(SignatureType::PersonaCertificate)
+ | Some(SignatureType::CasualCertificate)
+ | Some(SignatureType::PositiveCertificate) => typ.unwrap(),
+ Some(t) => return Err(Error::InvalidArgument(
+ format!("Invalid signature type: {}", t)).into()),
+ None => SignatureType::GenericCertificate,
+ };
+ self.bind(signer, tpk, signature::Builder::new(typ),
+ // Unwrap arguments to prevent further
+ // monomorphization of bind().
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512),
+ creation_time.into().unwrap_or_else(time::now_utc))
+ }
+
+ /// Returns a revocation certificate for the user attribute.
+ ///
+ /// The revocation signature revokes the binding between this user
+ /// attribute and `tpk`. `signer` will be used to create a
+ /// signature with the given reason in `code` and `reason`.
+ /// `signature_type`. `hash_algo` defaults to SHA512,
+ /// `creation_time` to the current time.
+ ///
+ /// This function adds a creation time subpacket, a issuer
+ /// fingerprint subpacket, and a issuer subpacket to the
+ /// signature.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use sequoia_openpgp::{*, constants::*, tpk::*,
+ /// packet::user_attribute::*};
+ /// # f().unwrap();
+ /// # fn f() -> Result<()> {
+ /// // Generate a TPK, and create a keypair from the primary key.
+ /// let user_attr = UserAttribute::new(&[
+ /// Subpacket::Image(
+ /// Image::Private(100, vec![0, 1, 2].into_boxed_slice())),
+ /// ])?;
+ /// let (tpk, _) = TPKBuilder::default()
+ /// .add_user_attribute(user_attr)
+ /// .generate()?;
+ /// let mut keypair = tpk.primary().clone().into_keypair()?;
+ ///
+ /// // Generate the revocation for the first and only UserAttribute.
+ /// let revocation =
+ /// tpk.user_attributes().nth(0).unwrap().user_attribute()
+ /// .revoke(&mut keypair, &tpk,
+ /// ReasonForRevocation::UIDRetired,
+ /// b"I look different now.", None, None)?;
+ /// assert_eq!(revocation.sigtype(), SignatureType::CertificateRevocation);
+ ///
+ /// // Now merge the revocation signature into the TPK.
+ /// let tpk = tpk.merge_packets(vec![revocation.clone().into()])?;
+ ///
+ /// // Check that it is revoked.
+ /// let ua = tpk.user_attributes().nth(0).unwrap();
+ /// if let RevocationStatus::Revoked(revocations) = ua.revoked(None) {
+ /// assert_eq!(revocations.len(), 1);
+ /// assert_eq!(revocations[0], revocation);
+ /// } else {
+ /// panic!("UserAttribute is not revoked.");
+ /// }
+ /// # Ok(()) }
+ /// ```
+ pub fn revoke<H, T>(&self, signer: &mut Signer, tpk: &TPK,
+ code: ReasonForRevocation, reason: &[u8],
+ hash_algo: H, creation_time: T)
+ -> Result<Signature>
+ where H: Into<Option<HashAlgorithm>>,
+ T: Into<Option<time::Tm>>
+ {
+ self.bind(signer, tpk,
+ signature::Builder::new(SignatureType::CertificateRevocation)
+ .set_reason_for_revocation(code, reason)?,
+ // Unwrap arguments to prevent further
+ // monomorphization of bind().
+ hash_algo.into().unwrap_or(HashAlgorithm::SHA512),
+ creation_time.into().unwrap_or_else(time::now_utc))
+ }
+}
diff --git a/openpgp/src/tpk/mod.rs b/openpgp/src/tpk/mod.rs
index 18254a78..fabc8082 100644
--- a/openpgp/src/tpk/mod.rs
+++ b/openpgp/src/tpk/mod.rs
@@ -41,6 +41,7 @@ use constants::ReasonForRevocation;
mod lexer;
mod grammar;
mod builder;
+mod bindings;
use self::lexer::Lexer;
pub use self::lexer::Token;
@@ -741,21 +742,6 @@ impl UserIDBinding {
RevocationStatus::NotAsFarAsWeKnow
}
}
-
- /// Returns a revocation certificate for the user id.
- pub fn revoke(&self, signer: &mut Signer,
- code: ReasonForRevocation, reason: &[u8])
- -> Result<Signature>
- {
- let key = signer.public().clone();
-
- signature::Builder::new(SignatureType::CertificateRevocation)
- .set_signature_creation_time(time::now_utc())?
- .set_issuer_fingerprint(signer.public().fingerprint())?
- .set_issuer(signer.public().keyid())?
- .set_reason_for_revocation(code, reason)?
- .sign_userid_binding(signer, &key, self.userid(), HashAlgorithm::SHA512)
- }
}
/// A User Attribute and any associated signatures.
@@ -3799,9 +3785,10 @@ mod test {
assert_eq!(RevocationStatus::NotAsFarAsWeKnow, uid.revoked(None));
let mut keypair = tpk.primary().clone().into_keypair().unwrap();
- uid.revoke(&mut keypair,
- ReasonForRevocation::UIDRetired,
- b"It was the maid :/").unwrap()
+ uid.userid()
+ .revoke(&mut keypair, &tpk,
+ ReasonForRevocation::UIDRetired,
+ b"It was the maid :/", None, None).unwrap()
};
assert_eq!(sig.sigtype(), SignatureType::CertificateRevocation);
let tpk = tpk.merge_packets(vec![sig.into()]).unwrap();