[][src]Struct sequoia_openpgp::packet::signature::SignatureBuilder

pub struct SignatureBuilder { /* fields omitted */ }

A Signature builder.

The SignatureBuilder is used to create Signatures. Although it can be used to generate a signature over a document (using SignatureBuilder::sign_message), it is usually better to use the streaming Signer for that.

Oftentimes, you won't want to create a new signature from scratch, but modify a copy of an existing signature. This is straightforward to do since SignatureBuilder implements From for Signature.

According to Section 5.2.3.4 of RFC 4880, Signatures must include a Signature Creation Time subpacket. Since this should usually be set to the current time, and is easy to forget to update, we remove any Signature Creation Time subpackets from both the hashed subpacket area and the unhashed subpacket area when converting a Signature to a SignatureBuilder, and when the SignatureBuilder is finalized, we automatically insert a Signature Creation Time subpacket into the hashed subpacket area unless the Signature Creation Time subpacket has been set using the set_signature_creation_time method or preserved using the preserve_signature_creation_time method or suppressed using the suppress_signature_creation_time method.

If the SignatureBuilder has been created from scratch, the current time is used as signature creation time. If it has been created from a template, we make sure that the generated signature is newer. If that is not possible (i.e. the generated signature would have a future creation time), the signing operation fails. This ensures that binding signatures can be updated by deriving a SignatureBuilder from the existing binding. To disable this, explicitly set a signature creation time, or preserve the original one, or suppress the insertion of a timestamp.

Similarly, most OpenPGP implementations cannot verify a signature if neither the Issuer subpacket nor the Issuer Fingerprint subpacket has been correctly set. To avoid subtle bugs due to the use of a stale Issuer subpacket or a stale Issuer Fingerprint subpacket, we remove any Issuer subpackets, and Issuer Fingerprint subpackets from both the hashed and unhashed areas when converting a Signature to a SigantureBuilder. Since the Signer passed to the finalization routine contains the required information, we also automatically add appropriate Issuer and Issuer Fingerprint subpackets to the unhashed subpacket area when the SignatureBuilder is finalized unless an Issuer subpacket or an IssuerFingerprint subpacket has been added to either of the subpacket areas (which can be done using the set_issuer method and the set_issuer_fingerprint method, respectively).

To finalize the builder, call sign_hash, sign_message, sign_direct_key, sign_subkey_binding, sign_primary_key_binding, sign_userid_binding, sign_user_attribute_binding, sign_standalone, or sign_timestamp, as appropriate. These functions turn the SignatureBuilder into a valid Signature.

This structure Derefs to its containing SignatureFields structure, which in turn Derefs to its subpacket areas (a SubpacketAreas).

Examples

Update a certificate's feature set by updating the Features subpacket on any direct key signature, and any User ID binding signatures. See the Preferences trait for how preferences like these are looked up.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
use openpgp::policy::StandardPolicy;
use openpgp::types::Features;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Derive a signer (the primary key is always certification capable).
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let mut sigs = Vec::new();

let vc = cert.with_policy(p, None)?;

if let Ok(sig) = vc.direct_key_signature() {
    sigs.push(SignatureBuilder::from(sig.clone())
        .modify_hashed_area(|mut a| {
            a.replace(Subpacket::new(
                SubpacketValue::Features(Features::sequoia().set(10)),
                false)?)?;
            Ok(a)
        })?
        // Update the direct key signature.
        .sign_direct_key(&mut signer, pk)?);
}

for ua in vc.userids() {
    sigs.push(SignatureBuilder::from(ua.binding_signature().clone())
        .modify_hashed_area(|mut a| {
            a.replace(Subpacket::new(
                SubpacketValue::Features(Features::sequoia().set(10)),
                false)?)?;
            Ok(a)
        })?
        // Update the binding signature.
        .sign_userid_binding(&mut signer, pk, ua.userid())?);
}

// Merge in the new signatures.
let cert = cert.insert_packets(sigs.into_iter().map(Packet::from))?;

Implementations

impl SignatureBuilder[src]

pub fn modify_unhashed_area<F>(self, f: F) -> Result<Self> where
    F: FnOnce(SubpacketArea) -> Result<SubpacketArea>, 
[src]

Modifies the unhashed subpacket area.

This method provides a builder-style interface for modifying the unhashed subpacket area.

Normally, to modify a subpacket area in a non-standard way (that is, when there are no subpacket-specific function like SignatureBuilder::set_signature_validity_period that implement the required functionality), you need to do something like the following:

let mut builder = SignatureBuilder::new(SignatureType::Binary)
    // Build up the signature.
    ;
builder.unhashed_area_mut().add(Subpacket::new(
        SubpacketValue::Unknown {
            tag: SubpacketTag::Private(61),
            body: [0x6D, 0x6F, 0x6F].to_vec(),
        },
        true)?)?;
let sig = builder.sign_message(&mut signer, msg)?;

This is necessary, because modifying the subpacket area doesn't follow the builder pattern like the surrounding code. Using this function, you can instead do:

let sig = SignatureBuilder::new(SignatureType::Binary)
    // Call some setters.
    .modify_unhashed_area(|mut a| {
        a.add(Subpacket::new(
            SubpacketValue::Unknown {
                tag: SubpacketTag::Private(61),
                body: [0x6D, 0x6F, 0x6F].to_vec(),
            },
            true)?);
        Ok(a)
    })?
   .sign_message(&mut signer, msg)?;

If you are only interested in modifying an existing signature's unhashed area, it may be better to simply modify the signature in place using Signature4::modify_unhashed_area rather than to create a new signature, because modifying the unhashed area doesn't invalidate any existing signature.

Examples

Create a signature with a custom, non-critical subpacket in the unhashed area:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::{
    Subpacket,
    SubpacketTag,
    SubpacketValue,
};
use openpgp::types::SignatureType;

let (cert, _) =
    CertBuilder::general_purpose(None, Some("alice@example.org"))
    .generate()?;
let mut signer = cert.primary_key().key().clone().parts_into_secret()?.into_keypair()?;

let msg = b"Hello, World";

let sig = SignatureBuilder::new(SignatureType::Binary)
    // Call some setters.
    .modify_unhashed_area(|mut a| {
        a.add(Subpacket::new(
            SubpacketValue::Unknown {
                tag: SubpacketTag::Private(61),
                body: [0x6D, 0x6F, 0x6F].to_vec(),
            },
            true)?);
        Ok(a)
    })?
   .sign_message(&mut signer, msg)?;

pub fn modify_hashed_area<F>(self, f: F) -> Result<Self> where
    F: FnOnce(SubpacketArea) -> Result<SubpacketArea>, 
[src]

Modifies the hashed subpacket area.

This method provides a builder-style interface for modifying the hashed subpacket area.

Normally, to modify a subpacket area in a non-standard way (that is, when there are no subpacket-specific function like SignatureBuilder::set_signature_validity_period that implement the required functionality), you need to do something like the following:

let mut builder = SignatureBuilder::new(SignatureType::Binary)
    // Build up the signature.
    ;
builder.hashed_area_mut().add(Subpacket::new(
        SubpacketValue::Unknown {
            tag: SubpacketTag::Private(61),
            body: [0x6D, 0x6F, 0x6F].to_vec(),
        },
        true)?)?;
let sig = builder.sign_message(&mut signer, msg)?;

This is necessary, because modifying the subpacket area doesn't follow the builder pattern like the surrounding code. Using this function, you can instead do:

let sig = SignatureBuilder::new(SignatureType::Binary)
    // Call some setters.
    .modify_hashed_area(|mut a| {
        a.add(Subpacket::new(
            SubpacketValue::Unknown {
                tag: SubpacketTag::Private(61),
                body: [0x6D, 0x6F, 0x6F].to_vec(),
            },
            true)?);
        Ok(a)
    })?
   .sign_message(&mut signer, msg)?;

Examples

Add a critical, custom subpacket to a certificate's direct key signature:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::{
    Subpacket,
    SubpacketTag,
    SubpacketValue,
};
use openpgp::policy::StandardPolicy;
use openpgp::types::Features;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Derive a signer (the primary key is always certification capable).
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let sig = vc.direct_key_signature().expect("direct key signature");
let sig = SignatureBuilder::from(sig.clone())
    .modify_hashed_area(|mut a| {
        a.add(Subpacket::new(
            SubpacketValue::Unknown {
                tag: SubpacketTag::Private(61),
                body: [0x6D, 0x6F, 0x6F].to_vec(),
            },
            true)?)?;
        Ok(a)
    })?
    .sign_direct_key(&mut signer, pk)?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

Update a certificate's feature set by updating the Features subpacket on any direct key signature, and any User ID binding signatures:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::{Subpacket, SubpacketValue};
use openpgp::policy::StandardPolicy;
use openpgp::types::Features;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Derive a signer (the primary key is always certification capable).
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let mut sigs = Vec::new();

let vc = cert.with_policy(p, None)?;

if let Ok(sig) = vc.direct_key_signature() {
    sigs.push(SignatureBuilder::from(sig.clone())
        .modify_hashed_area(|mut a| {
            a.replace(Subpacket::new(
                SubpacketValue::Features(Features::sequoia().set(10)),
                false)?)?;
            Ok(a)
        })?
        // Update the direct key signature.
        .sign_direct_key(&mut signer, pk)?);
}

for ua in vc.userids() {
    sigs.push(SignatureBuilder::from(ua.binding_signature().clone())
        .modify_hashed_area(|mut a| {
            a.replace(Subpacket::new(
                SubpacketValue::Features(Features::sequoia().set(10)),
                false)?)?;
            Ok(a)
        })?
        // Update the binding signature.
        .sign_userid_binding(&mut signer, pk, ua.userid())?);
}

// Merge in the new signatures.
let cert = cert.insert_packets(sigs)?;

pub fn set_signature_creation_time<T>(self, creation_time: T) -> Result<Self> where
    T: Into<SystemTime>, 
[src]

Sets the Signature Creation Time subpacket.

Adds a Signature Creation Time subpacket to the hashed subpacket area. This function first removes any Signature Creation Time subpacket from the hashed subpacket area.

The Signature Creation Time subpacket specifies when the signature was created. According to the standard, all signatures must include a Signature Creation Time subpacket in the signature's hashed area. This doesn't mean that the time stamp is correct: the issuer can always forge it.

When creating a signature using a SignatureBuilder or the streaming Signer, it is not necessary to explicitly set this subpacket: those functions automatically set both the [Issuer Fingerprint subpacket] and the Issuer subpacket, if they have not been set explicitly.

Examples

Create a backdated signature:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let msg = "hiermit kündige ich den mit Ihnen bestehenden Vertrag fristgerecht.";

let mut sig = SignatureBuilder::new(SignatureType::Binary)
    .set_signature_creation_time(
        std::time::SystemTime::now()
        - std::time::Duration::new(24 * 60 * 60, 0))?
    .sign_message(&mut signer, msg)?;

assert!(sig.verify_message(signer.public(), msg).is_ok());

pub fn preserve_signature_creation_time(self) -> Result<Self>[src]

Causes the builder to use an existing signature creation time subpacket.

When converting a Signature to a SignatureBuilder, the Signature Creation Time subpacket is removed from the hashed area, and saved internally. When creating the signature, a Signature Creation Time subpacket with the current time is normally added to the hashed area. Calling this function instead causes the signature generation code to use the cached Signature Creation Time subpacket.

This function returns an error if there is no cached Signature Creation Time subpacket.

Examples

Alice signs a message. Shortly thereafter, Bob signs the message using a nearly identical Signature packet:

use sequoia_openpgp as openpgp;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let msg = "Version 489 of Foo has the SHA256 sum e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";

let siga = SignatureBuilder::new(SignatureType::Binary)
    .sign_message(&mut alices_signer, msg)?;
let sigb = SignatureBuilder::from(siga.clone())
    .preserve_signature_creation_time()?
    .sign_message(&mut bobs_signer, msg)?;

pub fn suppress_signature_creation_time(self) -> Result<Self>[src]

Causes the builder to not output a Signature Creation Time subpacket.

When creating a signature, a Signature Creation Time subpacket is added to the hashed area if one hasn't been added already. This function suppresses that behavior.

Section 5.2.3.4 of RFC 4880 says that the Signature Creation Time subpacket must be present in the hashed area. This function clears any Signature Creation Time subpackets from both the hashed area and the unhashed area, and causes the various SignatureBuilder finalizers to not emit a Signature Creation Time subpacket. This function should only be used for generating test data.

Examples

Create a signature without a Signature Creation Time subpacket. As per the specification, Sequoia considers such signatures to be invalid:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let msg = "Some things are timeless.";

let mut sig = SignatureBuilder::new(SignatureType::Binary)
    .suppress_signature_creation_time()?
    .sign_message(&mut signer, msg)?;

assert!(sig.verify_message(signer.public(), msg).is_err());

pub fn set_signature_validity_period<D>(self, expires_in: D) -> Result<Self> where
    D: Into<Duration>, 
[src]

Sets the Signature Expiration Time subpacket.

Adds a Signature Expiration Time subpacket to the hashed subpacket area. This function first removes any Signature Expiration Time subpacket from the hashed subpacket area.

This function is called set_signature_validity_period and not set_signature_expiration_time, which would be more consistent with the subpacket's name, because the latter suggests an absolute time, but the time is actually relative to the signature's creation time, which is stored in the signature's Signature Creation Time subpacket and set using SignatureBuilder::set_signature_creation_time.

A Signature Expiration Time subpacket specifies when the signature expires. This is different from the Key Expiration Time subpacket, which is set using SignatureBuilder::set_key_validity_period, and used to specify when an associated key expires. The difference is that in the former case, the signature itself expires, but in the latter case, only the associated key expires. This difference is critical: if a binding signature expires, then an OpenPGP implementation will still consider the associated key to be valid if there is another valid binding signature, even if it is older than the expired signature; if the active binding signature indicates that the key has expired, then OpenPGP implementations will not fallback to an older binding signature.

There are several cases where having a signature expire is useful. Say Alice certifies Bob's certificate for bob@example.org. She can limit the lifetime of the certification to force her to reevaluate the certification shortly before it expires. For instance, is Bob still associated with example.org? Does she have reason to believe that his key has been compromised? Using an expiration is common in the X.509 ecosystem. For instance, Let's Encrypt issues certificates with 90-day lifetimes.

Having signatures expire can also be useful when deploying software. For instance, you might have a service that installs an update if it has been signed by a trusted certificate. To prevent an adversary from coercing the service to install an older version, you could limit the signature's lifetime to just a few minutes.

Examples

Create a signature that expires in 10 minutes:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let (cert, _) =
    CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let mut signer = cert.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let msg = "install e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";

let mut sig = SignatureBuilder::new(SignatureType::Binary)
    .set_signature_validity_period(
        std::time::Duration::new(10 * 60, 0))?
    .sign_message(&mut signer, msg)?;

assert!(sig.verify_message(signer.public(), msg).is_ok());

Create a certification that expires at the end of the year (give or take a few seconds) unless the new year is in a month, then have it expire at the end of the following year:

use std::time::{SystemTime, UNIX_EPOCH, Duration};
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let (cert, _) =
    CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let mut signer = cert.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let msg = "message.";

// Average number of seconds in a year.  See:
// https://en.wikipedia.org/wiki/Year .
const SECONDS_IN_YEAR: u64 = (365.2425 * 24. * 60. * 60.) as u64;

let now = SystemTime::now();
let since_epoch = now.duration_since(UNIX_EPOCH)?.as_secs();
let next_year
    = (since_epoch + SECONDS_IN_YEAR) - (since_epoch % SECONDS_IN_YEAR);
// Make sure the expiration is at least a month in the future.
let next_year = if next_year - since_epoch < SECONDS_IN_YEAR / 12 {
    next_year + SECONDS_IN_YEAR
} else {
    next_year
};
let next_year = UNIX_EPOCH + Duration::new(next_year, 0);
let next_year = next_year.duration_since(now)?;

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_signature_creation_time(now)?
    .set_signature_validity_period(next_year)?
    .sign_message(&mut signer, msg)?;

pub fn set_exportable_certification(self, exportable: bool) -> Result<Self>[src]

Sets the Exportable Certification subpacket.

Adds an Exportable Certification subpacket to the hashed subpacket area. This function first removes any Exportable Certification subpacket from the hashed subpacket area.

The Exportable Certification subpacket indicates whether the signature should be exported (e.g., published on a public key server) or not. When using Serialize::export to export a certificate, signatures that have this subpacket present and set to false are not serialized.

Examples

Alice certificates Bob's certificate, but because she doesn't want to publish it, she creates a so-called local signature by adding an Exportable Certification subpacket set to false to the signature:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (alice, _)
    = CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let mut alices_signer = alice.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let (bob, _)
    = CertBuilder::general_purpose(None, Some("bob@example.org"))
        .generate()?;
let bobs_userid
    = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();

let certification = SignatureBuilder::new(SignatureType::GenericCertification)
    .set_exportable_certification(false)?
    .sign_userid_binding(
        &mut alices_signer, &bob.primary_key(), bobs_userid)?;

// Merge in the new signature.
let bob = bob.insert_packets(certification)?;

pub fn set_trust_signature(self, level: u8, trust: u8) -> Result<Self>[src]

Sets the Trust Signature subpacket.

Adds a Trust Signature subpacket to the hashed subpacket area. This function first removes any Trust Signature subpacket from the hashed subpacket area.

The Trust Signature subpacket indicates to degree to which a certificate holder is trusted to certify other keys.

A level of 0 means that the certificate holder is not trusted to certificate other keys, a level of 1 means that the certificate holder is a trusted introducer (a certificate authority) and any certifications that they make should be considered valid. A level of 2 means the certificate holder can designate level 1 trusted introducers, etc.

The trust indicates the degree of confidence. A value of 120 means that a certification should be considered valid. A value of 60 means that a certification should only be considered partially valid. In the latter case, typically three such certifications are required for a binding to be considered authenticated.

Examples

Alice designates Bob as a fully trusted, trusted introducer:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (alice, _)
    = CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let mut alices_signer = alice.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let (bob, _)
    = CertBuilder::general_purpose(None, Some("bob@example.org"))
        .generate()?;
let bobs_userid
    = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();

let certification = SignatureBuilder::new(SignatureType::GenericCertification)
    .set_trust_signature(1, 120)?
    .sign_userid_binding(
        &mut alices_signer, &bob.primary_key(), bobs_userid)?;

// Merge in the new signature.
let bob = bob.insert_packets(certification)?;

pub fn set_regular_expression<R>(self, re: R) -> Result<Self> where
    R: AsRef<[u8]>, 
[src]

Sets the Regular Expression subpacket.

Adds a Regular Expression subpacket to the hashed subpacket area. This function first removes any Regular Expression subpacket from the hashed subpacket area.

The Regular Expression subpacket is used in conjunction with a Trust Signature subpacket, which is set using SignatureBuilder::set_trust_signature, to limit the scope of a trusted introducer. This is useful, for instance, when a company has a CA and you only want to trust them to certify their own employees.

GnuPG only supports a limited form of regular expressions.

Note: The serialized form includes a trailing NUL byte. Sequoia adds this NUL when serializing the signature. Adding it yourself will result in two trailing NUL bytes.

Examples

Alice designates openpgp-ca@example.com as a fully trusted, trusted introducer, but only for users from the example.com domain:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (alice, _)
    = CertBuilder::general_purpose(None, Some("Alice <alice@example.org>"))
        .generate()?;
let mut alices_signer = alice.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let (example_com, _)
    = CertBuilder::general_purpose(None, Some("OpenPGP CA <openpgp-ca@example.com>"))
        .generate()?;
let example_com_userid = example_com.with_policy(p, None)?
    .userids().nth(0).expect("Added a User ID").userid();

let certification = SignatureBuilder::new(SignatureType::GenericCertification)
    .set_trust_signature(1, 120)?
    .set_regular_expression("<[^>]+[@.]example\\.com>$")?
    .sign_userid_binding(
        &mut alices_signer,
        &example_com.primary_key(),
        example_com_userid)?;

// Merge in the new signature.
let example_com = example_com.insert_packets(certification)?;

pub fn add_regular_expression<R>(self, re: R) -> Result<Self> where
    R: AsRef<[u8]>, 
[src]

Sets a Regular Expression subpacket.

Adds a Regular Expression subpacket to the hashed subpacket area. Unlike SignatureBuilder::set_regular_expression, this function does not first remove any Regular Expression subpacket from the hashed subpacket area, but adds an additional Regular Expression subpacket to the hashed subpacket area.

The Regular Expression subpacket is used in conjunction with a Trust Signature subpacket, which is set using SignatureBuilder::set_trust_signature, to limit the scope of a trusted introducer. This is useful, for instance, when a company has a CA and you only want to trust them to certify their own employees.

GnuPG only supports a limited form of regular expressions.

Note: The serialized form includes a trailing NUL byte. Sequoia adds this NUL when serializing the signature. Adding it yourself will result in two trailing NUL bytes.

Examples

Alice designates openpgp-ca@example.com as a fully trusted, trusted introducer, but only for users from the example.com and example.net domains:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (alice, _)
    = CertBuilder::general_purpose(None, Some("Alice <alice@example.org>"))
        .generate()?;
let mut alices_signer = alice.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let (example_com, _)
    = CertBuilder::general_purpose(None, Some("OpenPGP CA <openpgp-ca@example.com>"))
        .generate()?;
let example_com_userid = example_com.with_policy(p, None)?
    .userids().nth(0).expect("Added a User ID").userid();

let certification = SignatureBuilder::new(SignatureType::GenericCertification)
    .set_trust_signature(1, 120)?
    .set_regular_expression("<[^>]+[@.]example\\.com>$")?
    .add_regular_expression("<[^>]+[@.]example\\.net>$")?
    .sign_userid_binding(
        &mut alices_signer,
        &example_com.primary_key(),
        example_com_userid)?;

// Merge in the new signature.
let example_com = example_com.insert_packets(certification)?;

pub fn set_revocable(self, revocable: bool) -> Result<Self>[src]

Sets the Revocable subpacket.

Adds a Revocable subpacket to the hashed subpacket area. This function first removes any Revocable subpacket from the hashed subpacket area.

The Revocable subpacket indicates whether a certification may be later revoked by creating a Certification revocation signature (0x30) that targets the signature using the Signature Target subpacket (set using the SignatureBuilder::set_signature_target method).

Examples

Alice certifies Bob's key and marks the certification as irrevocable. Since she can't revoke the signature, she limits the scope of misuse by setting the signature to expire in a year:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (alice, _)
    = CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let mut alices_signer = alice.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let (bob, _)
    = CertBuilder::general_purpose(None, Some("bob@example.org"))
        .generate()?;
let bobs_userid
    = bob.with_policy(p, None)?.userids().nth(0).expect("Added a User ID").userid();

// Average number of seconds in a year.  See:
// https://en.wikipedia.org/wiki/Year .
const SECONDS_IN_YEAR: u64 = (365.2425 * 24. * 60. * 60.) as u64;

let certification = SignatureBuilder::new(SignatureType::GenericCertification)
    .set_revocable(false)?
    .set_signature_validity_period(
        std::time::Duration::new(SECONDS_IN_YEAR, 0))?
    .sign_userid_binding(
        &mut alices_signer, &bob.primary_key(), bobs_userid)?;

// Merge in the new signature.
let bob = bob.insert_packets(certification)?;

pub fn set_key_validity_period<D>(self, expires_in: D) -> Result<Self> where
    D: Into<Option<Duration>>, 
[src]

Sets the Key Expiration Time subpacket.

Adds a Key Expiration Time subpacket to the hashed subpacket area. This function first removes any Key Expiration Time subpacket from the hashed subpacket area.

If None is given, any expiration subpacket is removed.

This function is called set_key_validity_period and not set_key_expiration_time, which would be more consistent with the subpacket's name, because the latter suggests an absolute time, but the time is actually relative to the associated key's (not the signature's) creation time, which is stored in the Key.

There is a more convenient function SignatureBuilder::set_key_expiration_time that takes an absolute expiration time.

A Key Expiration Time subpacket specifies when the associated key expires. This is different from the Signature Expiration Time subpacket (set using SignatureBuilder::set_signature_validity_period), which is used to specify when the signature expires. That is, in the former case, the associated key expires, but in the latter case, the signature itself expires. This difference is critical: if a binding signature expires, then an OpenPGP implementation will still consider the associated key to be valid if there is another valid binding signature, even if it is older than the expired signature; if the active binding signature indicates that the key has expired, then OpenPGP implementations will not fallback to an older binding signature.

Examples

Change all subkeys to expire 10 minutes after their (not the new binding signature's) creation time.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) =
    CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

// Create the binding signatures.
let mut sigs = Vec::new();

for key in cert.with_policy(p, None)?.keys().subkeys() {
    // This reuses any existing backsignature.
    let sig = SignatureBuilder::from(key.binding_signature().clone())
        .set_key_validity_period(std::time::Duration::new(10 * 60, 0))?
        .sign_subkey_binding(&mut signer, &pk, &key)?;
    sigs.push(sig);
}

let cert = cert.insert_packets(sigs)?;

pub fn set_key_expiration_time<P, R, E>(
    self,
    key: &Key<P, R>,
    expiration: E
) -> Result<Self> where
    P: KeyParts,
    R: KeyRole,
    E: Into<Option<SystemTime>>, 
[src]

Sets the Key Expiration Time subpacket.

Adds a Key Expiration Time subpacket to the hashed subpacket area. This function first removes any Key Expiration Time subpacket from the hashed subpacket area.

If None is given, any expiration subpacket is removed.

This function is called set_key_expiration_time similar to the subpacket's name, but it takes an absolute time, whereas the subpacket stores a time relative to the associated key's (not the signature's) creation time, which is stored in the Key.

This is a more convenient function than SignatureBuilder::set_key_validity_period that takes a relative expiration time.

A Key Expiration Time subpacket specifies when the associated key expires. This is different from the Signature Expiration Time subpacket (set using SignatureBuilder::set_signature_validity_period), which is used to specify when the signature expires. That is, in the former case, the associated key expires, but in the latter case, the signature itself expires. This difference is critical: if a binding signature expires, then an OpenPGP implementation will still consider the associated key to be valid if there is another valid binding signature, even if it is older than the expired signature; if the active binding signature indicates that the key has expired, then OpenPGP implementations will not fallback to an older binding signature.

Examples

Change all subkeys to expire 10 minutes after their (not the new binding signature's) creation time.

use std::time;
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) =
    CertBuilder::general_purpose(None, Some("alice@example.org"))
        .generate()?;
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

// Create the binding signatures.
let mut sigs = Vec::new();

for key in cert.with_policy(p, None)?.keys().subkeys() {
    // This reuses any existing backsignature.
    let sig = SignatureBuilder::from(key.binding_signature().clone())
        .set_key_expiration_time(&key,
                                 time::SystemTime::now()
                                 + time::Duration::new(10 * 60, 0))?
        .sign_subkey_binding(&mut signer, &pk, &key)?;
    sigs.push(sig);
}

let cert = cert.insert_packets(sigs)?;

pub fn set_preferred_symmetric_algorithms(
    self,
    preferences: Vec<SymmetricAlgorithm>
) -> Result<Self>
[src]

Sets the Preferred Symmetric Algorithms subpacket.

Replaces any Preferred Symmetric Algorithms subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Preferred Symmetric Algorithms subpacket from the hashed subpacket area, and then adds a new one.

A Preferred Symmetric Algorithms subpacket lists what symmetric algorithms the user prefers. When encrypting a message for a recipient, the OpenPGP implementation should not use an algorithm that is not on this list.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SymmetricAlgorithm;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let template = vc.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig = SignatureBuilder::from(template.clone())
    .set_preferred_symmetric_algorithms(
        vec![ SymmetricAlgorithm::AES256,
              SymmetricAlgorithm::AES128,
        ])?
    .sign_direct_key(&mut signer, &cert.primary_key())?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_revocation_key(self, rk: Vec<RevocationKey>) -> Result<Self>[src]

Sets the Revocation Key subpacket.

Replaces any Revocation Key subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Revocation Key subpacket from the hashed subpacket area, and then adds a new one.

A Revocation Key subpacket indicates certificates (so-called designated revokers) that are allowed to revoke the signer's certificate. For instance, if Alice trusts Bob, she can set him as a designated revoker. This is useful if Alice loses access to her key, and therefore is unable to generate a revocation certificate on her own. In this case, she can still Bob to generate one on her behalf.

Due to the complexity of verifying such signatures, many OpenPGP implementations do not support this feature.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::RevocationKey;

let p = &StandardPolicy::new();

let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut alices_signer = alice.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let (bob, _) = CertBuilder::new().add_userid("Bob").generate()?;

let template = alice.with_policy(p, None)?.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig = SignatureBuilder::from(template.clone())
    .set_revocation_key(vec![
        RevocationKey::new(bob.primary_key().pk_algo(), bob.fingerprint(), false),
    ])?
    .sign_direct_key(&mut alices_signer, &alice.primary_key())?;

// Merge in the new signature.
let alice = alice.insert_packets(sig)?;

pub fn set_issuer(self, id: KeyID) -> Result<Self>[src]

Adds the Issuer subpacket.

Adds an Issuer subpacket to the hashed subpacket area. Unlike add_issuer, this function first removes any existing Issuer subpackets from the hashed and unhashed subpacket area.

The Issuer subpacket is used when processing a signature to identify which certificate created the signature. Even though this information is self-authenticating (the act of validating the signature authenticates the subpacket), it is stored in the hashed subpacket area. This has the advantage that the signer authenticates the set of issuers. Furthermore, it makes handling of the resulting signatures more robust: If there are two two signatures that are equal modulo the contents of the unhashed area, there is the question of how to merge the information in the unhashed areas. Storing issuer information in the hashed area avoids this problem.

When creating a signature using a SignatureBuilder or the streaming Signer, it is not necessary to explicitly set this subpacket: those functions automatically set both the Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint) and the Issuer subpacket, if they have not been set explicitly.

Examples

It is possible to use the same key material with different OpenPGP keys. This is useful when the OpenPGP format is upgraded, but not all deployed implementations support the new format. Here, Alice signs a message, and adds the fingerprint of her v4 key and her v5 key indicating that the recipient can use either key to verify the message:

use sequoia_openpgp as openpgp;
use openpgp::packet::prelude::*;
use openpgp::types::SignatureType;

let msg = b"Hi!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_issuer(alicev4.keyid())?
    .add_issuer(alicev5.keyid())?
    .sign_message(&mut alices_signer, msg)?;

pub fn add_issuer(self, id: KeyID) -> Result<Self>[src]

Adds an Issuer subpacket.

Adds an Issuer subpacket to the hashed subpacket area. Unlike set_issuer, this function does not first remove any existing Issuer subpacket from neither the hashed nor the unhashed subpacket area.

The Issuer subpacket is used when processing a signature to identify which certificate created the signature. Even though this information is self-authenticating (the act of validating the signature authenticates the subpacket), it is stored in the unhashed subpacket area. This has the advantage that the signer authenticates the set of issuers. Furthermore, it makes handling of the resulting signatures more robust: If there are two two signatures that are equal modulo the contents of the unhashed area, there is the question of how to merge the information in the unhashed areas. Storing issuer information in the hashed area avoids this problem.

When creating a signature using a SignatureBuilder or the streaming Signer, it is not necessary to explicitly set this subpacket: those functions automatically set both the Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint) and the Issuer subpacket, if they have not been set explicitly.

Examples

It is possible to use the same key material with different OpenPGP keys. This is useful when the OpenPGP format is upgraded, but not all deployed implementations support the new format. Here, Alice signs a message, and adds the fingerprint of her v4 key and her v5 key indicating that the recipient can use either key to verify the message:

use sequoia_openpgp as openpgp;
use openpgp::packet::prelude::*;
use openpgp::types::SignatureType;

let msg = b"Hi!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_issuer(alicev4.keyid())?
    .add_issuer(alicev5.keyid())?
    .sign_message(&mut alices_signer, msg)?;

pub fn set_notation<N, V, F>(
    self,
    name: N,
    value: V,
    flags: F,
    critical: bool
) -> Result<Self> where
    N: AsRef<str>,
    V: AsRef<[u8]>,
    F: Into<Option<NotationDataFlags>>, 
[src]

Sets a Notation Data subpacket.

Adds a Notation Data subpacket to the hashed subpacket area. Unlike the SignatureBuilder::add_notation method, this function first removes any existing Notation Data subpacket with the specified name from the hashed subpacket area.

Notations are key-value pairs. They can be used by applications to annotate signatures in a structured way. For instance, they can define additional, application-specific security requirements. Because they are functionally equivalent to subpackets, they can also be used for OpenPGP extensions. This is how the Intended Recipient subpacket started life.

Notation names are structured, and are divided into two namespaces: the user namespace and the IETF namespace. Names in the user namespace have the form name@example.org and their meaning is defined by the owner of the domain. The meaning of the notation name@example.org, for instance, is defined by whoever controls example.org. Names in the IETF namespace do not contain an @ and are managed by IANA. See Section 5.2.3.16 of RFC 4880 for details.

Examples

Adds two social proofs to a certificate's primary User ID. This first clears any social proofs.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::NotationDataFlags;
use openpgp::policy::StandardPolicy;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Wiktor").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;
let userid = vc.primary_userid().expect("Added a User ID");

let template = userid.binding_signature();
let sig = SignatureBuilder::from(template.clone())
    .set_notation("proof@metacode.biz", "https://metacode.biz/@wiktor",
                  NotationDataFlags::empty().set_human_readable(), false)?
    .add_notation("proof@metacode.biz", "https://news.ycombinator.com/user?id=wiktor-k",
                  NotationDataFlags::empty().set_human_readable(), false)?
    .sign_userid_binding(&mut signer, &cert.primary_key(), &userid)?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn add_notation<N, V, F>(
    self,
    name: N,
    value: V,
    flags: F,
    critical: bool
) -> Result<Self> where
    N: AsRef<str>,
    V: AsRef<[u8]>,
    F: Into<Option<NotationDataFlags>>, 
[src]

Adds a Notation Data subpacket.

Adds a Notation Data subpacket to the hashed subpacket area. Unlike the SignatureBuilder::set_notation method, this function does not first remove any existing Notation Data subpacket with the specified name from the hashed subpacket area.

Notations are key-value pairs. They can be used by applications to annotate signatures in a structured way. For instance, they can define additional, application-specific security requirements. Because they are functionally equivalent to subpackets, they can also be used for OpenPGP extensions. This is how the Intended Recipient subpacket started life.

Notation names are structured, and are divided into two namespaces: the user namespace and the IETF namespace. Names in the user namespace have the form name@example.org and their meaning is defined by the owner of the domain. The meaning of the notation name@example.org, for instance, is defined by whoever controls example.org. Names in the IETF namespace do not contain an @ and are managed by IANA. See Section 5.2.3.16 of RFC 4880 for details.

Examples

Adds two new social proofs to a certificate's primary User ID. A more sophisticated program will check that the new notations aren't already present.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::packet::signature::subpacket::NotationDataFlags;
use openpgp::policy::StandardPolicy;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Wiktor").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;
let userid = vc.primary_userid().expect("Added a User ID");

let template = userid.binding_signature();
let sig = SignatureBuilder::from(template.clone())
    .add_notation("proof@metacode.biz", "https://metacode.biz/@wiktor",
                  NotationDataFlags::empty().set_human_readable(), false)?
    .add_notation("proof@metacode.biz", "https://news.ycombinator.com/user?id=wiktor-k",
                  NotationDataFlags::empty().set_human_readable(), false)?
    .sign_userid_binding(&mut signer, &cert.primary_key(), &userid)?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_preferred_hash_algorithms(
    self,
    preferences: Vec<HashAlgorithm>
) -> Result<Self>
[src]

Sets the Preferred Hash Algorithms subpacket.

Replaces any Preferred Hash Algorithms subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Preferred Hash Algorithms subpacket from the hashed subpacket area, and then adds a new one.

A Preferred Hash Algorithms subpacket lists what hash algorithms the user prefers. When signing a message that should be verified by a particular recipient, the OpenPGP implementation should not use an algorithm that is not on this list.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::HashAlgorithm;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let template = vc.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig = SignatureBuilder::from(template.clone())
    .set_preferred_hash_algorithms(
        vec![ HashAlgorithm::SHA512,
              HashAlgorithm::SHA256,
        ])?
    .sign_direct_key(&mut signer, &cert.primary_key())?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_preferred_compression_algorithms(
    self,
    preferences: Vec<CompressionAlgorithm>
) -> Result<Self>
[src]

Sets the Preferred Compression Algorithms subpacket.

Replaces any Preferred Compression Algorithms subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Preferred Compression Algorithms subpacket from the hashed subpacket area, and then adds a new one.

A Preferred Compression Algorithms subpacket lists what compression algorithms the user prefers. When compressing a message for a recipient, the OpenPGP implementation should not use an algorithm that is not on the list.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::CompressionAlgorithm;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let template = vc.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig = SignatureBuilder::from(template.clone())
    .set_preferred_compression_algorithms(
        vec![ CompressionAlgorithm::Zlib,
              CompressionAlgorithm::Zip,
              CompressionAlgorithm::BZip2,
        ])?
    .sign_direct_key(&mut signer, &cert.primary_key())?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_key_server_preferences(
    self,
    preferences: KeyServerPreferences
) -> Result<Self>
[src]

Sets the Key Server Preferences subpacket.

Replaces any Key Server Preferences subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Key Server Preferences subpacket from the hashed subpacket area, and then adds a new one.

The Key Server Preferences subpacket indicates to key servers how they should handle the certificate.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::KeyServerPreferences;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let sig = vc.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig =
    SignatureBuilder::from(sig.clone())
        .set_key_server_preferences(
            KeyServerPreferences::empty().set_no_modify())?
        .sign_direct_key(&mut signer, &cert.primary_key())?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_preferred_key_server<U>(self, uri: U) -> Result<Self> where
    U: AsRef<[u8]>, 
[src]

Sets the Preferred Key Server subpacket.

Adds a Preferred Key Server subpacket to the hashed subpacket area. This function first removes any Preferred Key Server subpacket from the hashed subpacket area.

The Preferred Key Server subpacket contains a link to a key server where the certificate holder plans to publish updates to their certificate (e.g., extensions to the expiration time, new subkeys, revocation certificates).

The Preferred Key Server subpacket should be handled cautiously, because it can be used by a certificate holder to track communication partners.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;
let mut signer = cert.primary_key().key()
    .clone().parts_into_secret()?.into_keypair()?;

let vc = cert.with_policy(p, None)?;

let sig = vc.direct_key_signature()
    .expect("CertBuilder always includes a direct key signature");
let sig =
    SignatureBuilder::from(sig.clone())
        .set_preferred_key_server(&"https://keys.openpgp.org")?
        .sign_direct_key(&mut signer, &cert.primary_key())?;

// Merge in the new signature.
let cert = cert.insert_packets(sig)?;

pub fn set_primary_userid(self, primary: bool) -> Result<Self>[src]

Sets the Primary User ID subpacket.

Adds a Primary User ID subpacket to the hashed subpacket area. This function first removes any Primary User ID subpacket from the hashed subpacket area.

The Primary User ID subpacket indicates whether the associated User ID or User Attribute should be considered the primary User ID. It is possible that this is set on multiple User IDs. See the documentation for ValidCert::primary_userid for an explanation of how Sequoia resolves this ambiguity.

Examples

Change the primary User ID:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;

let p = &StandardPolicy::new();

let club = "Alice <alice@club.org>";
let home = "Alice <alice@home.org>";

// CertBuilder makes the first User ID (club) the primary User ID.
let (cert, _) = CertBuilder::new()
    .add_userid(club)
    .add_userid(home)
    .generate()?;
assert_eq!(cert.with_policy(p, None)?.primary_userid().unwrap().userid(),
           &UserID::from(club));

// Make the `home` User ID the primary User ID.

// Derive a signer.
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let mut sig = None;
for ua in cert.with_policy(p, None)?.userids() {
    if ua.userid() == &UserID::from(home) {
        sig = Some(SignatureBuilder::from(ua.binding_signature().clone())
            .set_primary_userid(true)?
            .sign_userid_binding(&mut signer, pk, ua.userid())?);
        break;
    }
}
assert!(sig.is_some());

let cert = cert.insert_packets(sig)?;

assert_eq!(cert.with_policy(p, None)?.primary_userid().unwrap().userid(),
           &UserID::from(home));

pub fn set_policy_uri<U>(self, uri: U) -> Result<Self> where
    U: AsRef<[u8]>, 
[src]

Sets the Policy URI subpacket.

Adds a Policy URI subpacket to the hashed subpacket area. This function first removes any Policy URI subpacket from the hashed subpacket area.

The Policy URI subpacket contains a link to a policy document, which contains information about the conditions under which the signature was made.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

Alice updates her direct key signature to include a Policy URI subpacket:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;

let p = &StandardPolicy::new();

let (alice, _) = CertBuilder::new().add_userid("Alice").generate()?;
let pk = alice.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let sig = SignatureBuilder::from(
    alice
        .with_policy(p, None)?
        .direct_key_signature().expect("Direct key signature")
        .clone()
    )
    .set_policy_uri("https://example.org/~alice/signing-policy.txt")?
    .sign_direct_key(&mut signer, pk)?;

// Merge it into the certificate.
let alice = alice.insert_packets(sig)?;

pub fn set_key_flags(self, flags: &KeyFlags) -> Result<Self>[src]

Sets the Key Flags subpacket.

Adds a Key Flags subpacket to the hashed subpacket area. This function first removes any Key Flags subpacket from the hashed subpacket area.

The Key Flags subpacket describes a key's capabilities (certification capable, signing capable, etc.). In the case of subkeys, the Key Flags are located on the subkey's binding signature. For primary keys, locating the correct Key Flags subpacket is more complex: First, the primary User ID is consulted. If the primary User ID contains a Key Flags subpacket, that is used. Otherwise, any direct key signature is considered. If that still doesn't contain a Key Flags packet, then the primary key should be assumed to be certification capable.

Examples

Adds a new subkey, which is intended for encrypting data at rest, to a certificate:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::{
    Curve,
    KeyFlags,
    SignatureType
};

let p = &StandardPolicy::new();

// Generate a Cert, and create a keypair from the primary key.
let (cert, _) = CertBuilder::new().generate()?;
let mut signer = cert.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

// Generate a subkey and a binding signature.
let subkey: Key<_, key::SubordinateRole>
    = Key4::generate_ecc(false, Curve::Cv25519)?
        .into();
let builder = signature::SignatureBuilder::new(SignatureType::SubkeyBinding)
    .set_key_flags(&KeyFlags::empty().set_storage_encryption())?;
let binding = subkey.bind(&mut signer, &cert, builder)?;

// Now merge the key and binding signature into the Cert.
let cert = cert.insert_packets(vec![Packet::from(subkey),
                                   binding.into()])?;

pub fn set_signers_user_id<U>(self, uid: U) -> Result<Self> where
    U: AsRef<[u8]>, 
[src]

Sets the Signer's User ID subpacket.

Adds a Signer's User ID subpacket to the hashed subpacket area. This function first removes any Signer's User ID subpacket from the hashed subpacket area.

The Signer's User ID subpacket indicates, which User ID made the signature. This is useful when a key has multiple User IDs, which correspond to different roles. For instance, it is not uncommon to use the same certificate in private as well as for a club.

Examples

Sign a message being careful to set the Signer's User ID subpacket to the user's private identity and not their club identity:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::types::SignatureType;

let (cert, _) = CertBuilder::new()
    .add_userid("Alice <alice@home.org>")
    .add_userid("Alice (President) <alice@club.org>")
    .generate()?;
let mut signer = cert.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;

let msg = "Speaking for myself, I agree.";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_signers_user_id(&b"Alice <alice@home.org>"[..])?
    .sign_message(&mut signer, msg)?;

pub fn set_reason_for_revocation<R>(
    self,
    code: ReasonForRevocation,
    reason: R
) -> Result<Self> where
    R: AsRef<[u8]>, 
[src]

Sets the value of the Reason for Revocation subpacket.

Adds a Reason For Revocation subpacket to the hashed subpacket area. This function first removes any Reason For Revocation subpacket from the hashed subpacket area.

The Reason For Revocation subpacket indicates why a key, User ID, or User Attribute is being revoked. It includes both a machine readable code, and a human-readable string. The code is essential as it indicates to the OpenPGP implementation that reads the certificate whether the key was compromised (a hard revocation), or is no longer used (a soft revocation). In the former case, the OpenPGP implementation must conservatively consider all past signatures as suspect whereas in the latter case, past signatures can still be considered valid.

Examples

Revoke a certificate whose private key material has been compromised:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::ReasonForRevocation;
use openpgp::types::RevocationStatus;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;
assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
           cert.revocation_status(p, None));

// Create and sign a revocation certificate.
let mut signer = cert.primary_key().key().clone()
    .parts_into_secret()?.into_keypair()?;
let sig = CertRevocationBuilder::new()
    .set_reason_for_revocation(ReasonForRevocation::KeyCompromised,
                               b"It was the maid :/")?
    .build(&mut signer, &cert, None)?;

// Merge it into the certificate.
let cert = cert.insert_packets(sig.clone())?;

// Now it's revoked.
assert_eq!(RevocationStatus::Revoked(vec![ &sig ]),
           cert.revocation_status(p, None));

pub fn set_features(self, features: &Features) -> Result<Self>[src]

Sets the Features subpacket.

Adds a Feature subpacket to the hashed subpacket area. This function first removes any Feature subpacket from the hashed subpacket area.

A Feature subpacket lists what OpenPGP features the user wants to use. When creating a message, features that the intended recipients do not support should not be used. However, because this information is rarely held up to date in practice, this information is only advisory, and implementations are allowed to infer what features the recipients support from contextual clues, e.g., their past behavior.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

Update a certificate's binding signatures to indicate support for AEAD:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::{AEADAlgorithm, Features};

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Derive a signer (the primary key is always certification capable).
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let mut sigs = Vec::new();

let vc = cert.with_policy(p, None)?;

if let Ok(sig) = vc.direct_key_signature() {
    sigs.push(
        SignatureBuilder::from(sig.clone())
            .set_preferred_aead_algorithms(vec![ AEADAlgorithm::EAX ])?
            .set_features(
                &sig.features().unwrap_or_else(Features::sequoia)
                    .set_aead())?
            .sign_direct_key(&mut signer, pk)?);
}

for ua in vc.userids() {
    let sig = ua.binding_signature();
    sigs.push(
        SignatureBuilder::from(sig.clone())
            .set_preferred_aead_algorithms(vec![ AEADAlgorithm::EAX ])?
            .set_features(
                &sig.features().unwrap_or_else(Features::sequoia)
                    .set_aead())?
            .sign_userid_binding(&mut signer, pk, ua.userid())?);
}

// Merge in the new signatures.
let cert = cert.insert_packets(sigs)?;

pub fn set_signature_target<D>(
    self,
    pk_algo: PublicKeyAlgorithm,
    hash_algo: HashAlgorithm,
    digest: D
) -> Result<Self> where
    D: AsRef<[u8]>, 
[src]

Sets the Signature Target subpacket.

Adds a Signature Target subpacket to the hashed subpacket area. This function first removes any Signature Target subpacket from the hashed subpacket area.

The Signature Target subpacket is used to identify the target of a signature. This is used when revoking a signature, and by timestamp signatures. It contains a hash of the target signature.

pub fn set_embedded_signature(self, signature: Signature) -> Result<Self>[src]

Sets the value of the Embedded Signature subpacket.

Adds an Embedded Signature subpacket to the hashed subpacket area. This function first removes any Embedded Signature subpacket from both the hashed and the unhashed subpacket area.

The Embedded Signature subpacket is normally used to hold a Primary Key Binding signature, which binds a signing-capable, authentication-capable, or certification-capable subkey to the primary key. Since this information is self-authenticating, it is usually stored in the unhashed subpacket area.

Examples

Add a new signing-capable subkey to a certificate:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::KeyFlags;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;

let pk = cert.primary_key().key().clone().parts_into_secret()?;
// Derive a signer.
let mut pk_signer = pk.clone().into_keypair()?;

// Generate a new signing subkey.
let mut subkey: Key<_, _> = Key4::generate_rsa(3072)?.into();
// Derive a signer.
let mut sk_signer = subkey.clone().into_keypair()?;

// Create the binding signature.
let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
    .set_key_flags(&KeyFlags::empty().set_signing())?
    // And, the backsig.  This is essential for subkeys that create signatures!
    .set_embedded_signature(
        SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
            .sign_primary_key_binding(&mut sk_signer, &pk, &subkey)?)?
    .sign_subkey_binding(&mut pk_signer, &pk, &subkey)?;

let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
                                   sig.into()])?;

assert_eq!(cert.keys().count(), 2);

pub fn set_issuer_fingerprint(self, fp: Fingerprint) -> Result<Self>[src]

Sets the Issuer Fingerprint subpacket.

Adds an Issuer Fingerprint subpacket to the hashed subpacket area. Unlike add_issuer_fingerprint, this function first removes any existing Issuer Fingerprint subpackets from the hashed and unhashed subpacket area.

The Issuer Fingerprint subpacket is used when processing a signature to identify which certificate created the signature. Even though this information is self-authenticating (the act of validating the signature authenticates the subpacket), it is stored in the unhashed subpacket area. This has the advantage that the signer authenticates the set of issuers. Furthermore, it makes handling of the resulting signatures more robust: If there are two two signatures that are equal modulo the contents of the unhashed area, there is the question of how to merge the information in the unhashed areas. Storing issuer information in the hashed area avoids this problem.

When creating a signature using a SignatureBuilder or the streaming Signer, it is not necessary to explicitly set this subpacket: those functions automatically set both the Issuer Fingerprint subpacket, and the Issuer subpacket (set using SignatureBuilder::set_issuer), if they have not been set explicitly.

Examples

It is possible to use the same key material with different OpenPGP keys. This is useful when the OpenPGP format is upgraded, but not all deployed implementations support the new format. Here, Alice signs a message, and adds the fingerprint of her v4 key and her v5 key indicating that the recipient can use either key to verify the message:

use sequoia_openpgp as openpgp;
use openpgp::packet::prelude::*;
use openpgp::types::SignatureType;

let msg = b"Hi!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_issuer_fingerprint(alicev4.fingerprint())?
    .add_issuer_fingerprint(alicev5.fingerprint())?
    .sign_message(&mut alices_signer, msg)?;

pub fn add_issuer_fingerprint(self, fp: Fingerprint) -> Result<Self>[src]

Adds an Issuer Fingerprint subpacket.

Adds an Issuer Fingerprint subpacket to the hashed subpacket area. Unlike set_issuer_fingerprint, this function does not first remove any existing Issuer Fingerprint subpacket from neither the hashed nor the unhashed subpacket area.

The Issuer Fingerprint subpacket is used when processing a signature to identify which certificate created the signature. Even though this information is self-authenticating (the act of validating the signature authenticates the subpacket), it is stored in the unhashed subpacket area. This has the advantage that the signer authenticates the set of issuers. Furthermore, it makes handling of the resulting signatures more robust: If there are two two signatures that are equal modulo the contents of the unhashed area, there is the question of how to merge the information in the unhashed areas. Storing issuer information in the hashed area avoids this problem.

When creating a signature using a SignatureBuilder or the streaming Signer, it is not necessary to explicitly set this subpacket: those functions automatically set both the Issuer Fingerprint subpacket, and the Issuer subpacket (set using SignatureBuilder::set_issuer), if they have not been set explicitly.

Examples

It is possible to use the same key material with different OpenPGP keys. This is useful when the OpenPGP format is upgraded, but not all deployed implementations support the new format. Here, Alice signs a message, and adds the fingerprint of her v4 key and her v5 key indicating that the recipient can use either key to verify the message:

use sequoia_openpgp as openpgp;
use openpgp::packet::prelude::*;
use openpgp::types::SignatureType;

let msg = b"Hi!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_issuer_fingerprint(alicev4.fingerprint())?
    .add_issuer_fingerprint(alicev5.fingerprint())?
    .sign_message(&mut alices_signer, msg)?;

pub fn set_preferred_aead_algorithms(
    self,
    preferences: Vec<AEADAlgorithm>
) -> Result<Self>
[src]

Sets the Preferred AEAD Algorithms subpacket.

Replaces any Preferred AEAD Algorithms subpacket in the hashed subpacket area with a new subpacket containing the specified value. That is, this function first removes any Preferred AEAD Algorithms subpacket from the hashed subpacket area, and then adds a Preferred AEAD Algorithms subpacket.

The Preferred AEAD Algorithms subpacket indicates what AEAD algorithms the key holder prefers ordered by preference. If this is set, then the AEAD feature flag should in the Features subpacket should also be set.

Note: because support for AEAD has not yet been standardized, we recommend not yet advertising support for it.

This subpacket is a type of preference. When looking up a preference, an OpenPGP implementation should first look for the subpacket on the binding signature of the User ID or the User Attribute used to locate the certificate (or the primary User ID, if it was addressed by Key ID or fingerprint). If the binding signature doesn't contain the subpacket, then the direct key signature should be checked. See the Preferences trait for details.

Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.

Examples

Update a certificate's binding signatures to indicate support for AEAD:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::{AEADAlgorithm, Features};

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Derive a signer (the primary key is always certification capable).
let pk = cert.primary_key().key();
let mut signer = pk.clone().parts_into_secret()?.into_keypair()?;

let mut sigs = Vec::new();

let vc = cert.with_policy(p, None)?;

if let Ok(sig) = vc.direct_key_signature() {
    sigs.push(
        SignatureBuilder::from(sig.clone())
            .set_preferred_aead_algorithms(vec![ AEADAlgorithm::EAX ])?
            .set_features(
                &sig.features().unwrap_or_else(Features::sequoia)
                    .set_aead())?
            .sign_direct_key(&mut signer, pk)?);
}

for ua in vc.userids() {
    let sig = ua.binding_signature();
    sigs.push(
        SignatureBuilder::from(sig.clone())
            .set_preferred_aead_algorithms(vec![ AEADAlgorithm::EAX ])?
            .set_features(
                &sig.features().unwrap_or_else(Features::sequoia)
                    .set_aead())?
            .sign_userid_binding(&mut signer, pk, ua.userid())?);
}

// Merge in the new signatures.
let cert = cert.insert_packets(sigs)?;

pub fn set_intended_recipients<T>(self, recipients: T) -> Result<Self> where
    T: AsRef<[Fingerprint]>, 
[src]

Sets the Intended Recipient subpacket.

Replaces any Intended Recipient subpacket in the hashed subpacket area with one new subpacket for each of the specified values. That is, unlike SignatureBuilder::add_intended_recipient, this function first removes any Intended Recipient subpackets from the hashed subpacket area, and then adds new ones.

The Intended Recipient subpacket holds the fingerprint of a certificate.

When signing a message, the message should include one such subpacket for each intended recipient. Note: not all messages have intended recipients. For instance, when signing an open letter, or a software release, the message is intended for anyone.

When processing a signature, the application should ensure that if there are any such subpackets, then one of the subpackets identifies the recipient's certificate (or user signed the message). If this is not the case, then an attacker may have taken the message out of its original context. For instance, if Alice sends a signed email to Bob, with the content: "I agree to the contract", and Bob forwards that message to Carol, then Carol may think that Alice agreed to a contract with her if the signature appears to be valid! By adding an intended recipient, it is possible for Carol's mail client to warn her that although Alice signed the message, the content was intended for Bob and not for her.

Examples

To create a signed message intended for both Bob and Carol, Alice adds an intended recipient subpacket for each of their certificates. Because this function first removes any existing Intended Recipient subpackets both recipients must be added at once (cf. SignatureBuilder::add_intended_recipient):

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let msg = b"Let's do it!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .set_intended_recipients(&[ bob.fingerprint(), carol.fingerprint() ])?
    .sign_message(&mut alices_signer, msg)?;

pub fn add_intended_recipient(self, recipient: Fingerprint) -> Result<Self>[src]

Adds an Intended Recipient subpacket.

Adds an Intended Recipient subpacket to the hashed subpacket area. Unlike SignatureBuilder::set_intended_recipients, this function does not first remove any Intended Recipient subpackets from the hashed subpacket area.

The Intended Recipient subpacket holds the fingerprint of a certificate.

When signing a message, the message should include one such subpacket for each intended recipient. Note: not all messages have intended recipients. For instance, when signing an open letter, or a software release, the message is intended for anyone.

When processing a signature, the application should ensure that if there are any such subpackets, then one of the subpackets identifies the recipient's certificate (or user signed the message). If this is not the case, then an attacker may have taken the message out of its original context. For instance, if Alice sends a signed email to Bob, with the content: "I agree to the contract", and Bob forwards that message to Carol, then Carol may think that Alice agreed to a contract with her if the signature appears to be valid! By adding an intended recipient, it is possible for Carol's mail client to warn her that although Alice signed the message, the content was intended for Bob and not for her.

Examples

To create a signed message intended for both Bob and Carol, Alice adds an Intended Recipient subpacket for each of their certificates. Unlike SignatureBuilder::set_intended_recipients, which first removes any existing Intended Recipient subpackets, with this function we can add one recipient after the other:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;

let msg = b"Let's do it!";

let sig = SignatureBuilder::new(SignatureType::Binary)
    .add_intended_recipient(bob.fingerprint())?
    .add_intended_recipient(carol.fingerprint())?
    .sign_message(&mut alices_signer, msg)?;

impl SignatureBuilder[src]

pub fn new(typ: SignatureType) -> Self[src]

Returns a new SignatureBuilder object.

pub fn set_type(self, t: SignatureType) -> Self[src]

Sets the signature type.

pub fn set_hash_algo(self, h: HashAlgorithm) -> Self[src]

Sets the hash algorithm.

pub fn sign_standalone(self, signer: &mut dyn Signer) -> Result<Signature>[src]

Generates a standalone signature.

A Standalone Signature (SignatureType::Standalone) is a self-contained signature, which is only over the signature packet.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is SignatureType::Standalone or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;

// Get a usable (alive, non-revoked) signing key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_signing().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

let mut sig = SignatureBuilder::new(SignatureType::Standalone)
    .sign_standalone(&mut signer)?;

// Verify it.
sig.verify_standalone(signer.public())?;

pub fn sign_timestamp(self, signer: &mut dyn Signer) -> Result<Signature>[src]

Generates a Timestamp Signature.

Like a Standalone Signature (created using SignatureBuilder::sign_standalone), a Timestamp Signature is a self-contained signature, but its emphasis in on the contained timestamp, specifically, the timestamp stored in the Signature Creation Time subpacket. This type of signature is primarily used by timestamping services. To timestamp a signature, you can include either a Signature Target subpacket (set using SignatureBuilder::set_signature_target), or an Embedded Signature (set using SignatureBuilder::set_embedded_signature) in the hashed area.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is SignatureType::Timestamp or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Create a timestamp signature:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;

// Get a usable (alive, non-revoked) signing key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_signing().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

let mut sig = SignatureBuilder::new(SignatureType::Timestamp)
    .sign_timestamp(&mut signer)?;

// Verify it.
sig.verify_timestamp(signer.public())?;

pub fn sign_direct_key<P>(
    self,
    signer: &mut dyn Signer,
    pk: &Key<P, PrimaryRole>
) -> Result<Signature> where
    P: KeyParts
[src]

Generates a Direct Key Signature.

A Direct Key Signature is a signature over the primary key. It is primarily used to hold fallback preferences. For instance, when addressing the Certificate by a User ID, the OpenPGP implementation is supposed to look for preferences like the Preferred Symmetric Algorithms on the User ID, and only if there is no such packet, look on the direct key signature.

This function is also used to create a Key Revocation Signature, which revokes the certificate.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is SignatureType::DirectKey, SignatureType::KeyRevocation, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Set the default value for the Preferred Symmetric Algorithms subpacket:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;
use openpgp::types::SymmetricAlgorithm;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?;

// Get a usable (alive, non-revoked) certification key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_certification().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

// A direct key signature is always over the primary key.
let pk = cert.primary_key().key();

// Modify the existing direct key signature.
let mut sig = SignatureBuilder::from(
        cert.with_policy(p, None)?.direct_key_signature()?.clone())
    .set_preferred_symmetric_algorithms(
        vec![ SymmetricAlgorithm::AES256,
              SymmetricAlgorithm::AES128,
        ])?
    .sign_direct_key(&mut signer, pk)?;

// Verify it.
sig.verify_direct_key(signer.public(), pk)?;

pub fn sign_userid_binding<P>(
    self,
    signer: &mut dyn Signer,
    key: &Key<P, PrimaryRole>,
    userid: &UserID
) -> Result<Signature> where
    P: KeyParts
[src]

Generates a User ID binding signature.

A User ID binding signature (a self signature) or a User ID certification (a third-party signature) is a signature over a User ID and a Primary Key made by a certification-capable key. It asserts that the signer is convinced that the User ID should be associated with the Certificate, i.e., that the binding is authentic.

OpenPGP has four types of User ID certifications. They are intended to express the degree of the signer's conviction, i.e., how well the signer authenticated the binding. In practice, the Positive Certification type is used for self-signatures, and the Generic Certification is used for third-party certifications; the other types are not normally used.

This function is also used to create Certification Revocations.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is GenericCertification, PersonaCertification, CasualCertification, PositiveCertification, CertificationRevocation, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Set the Preferred Symmetric Algorithms subpacket, which will be used when addressing the certificate via the associated User ID:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SymmetricAlgorithm;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().add_userid("Alice").generate()?;

// Get a usable (alive, non-revoked) certification key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_certification().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

let pk = cert.primary_key().key();

// Update the User ID's binding signature.
let ua = cert.with_policy(p, None)?.userids().nth(0).unwrap();
let mut new_sig = SignatureBuilder::from(
        ua.binding_signature().clone())
    .set_preferred_symmetric_algorithms(
        vec![ SymmetricAlgorithm::AES256,
              SymmetricAlgorithm::AES128,
        ])?
    .sign_userid_binding(&mut signer, pk, ua.userid())?;

// Verify it.
new_sig.verify_userid_binding(signer.public(), pk, ua.userid())?;

pub fn sign_subkey_binding<P, Q>(
    self,
    signer: &mut dyn Signer,
    primary: &Key<P, PrimaryRole>,
    subkey: &Key<Q, SubordinateRole>
) -> Result<Signature> where
    P: KeyParts,
    Q: KeyParts
[src]

Generates a subkey binding signature.

A subkey binding signature is a signature over the primary key and a subkey, which is made by the primary key. It is an assertion by the certificate that the subkey really belongs to the certificate. That is, it binds the subkey to the certificate.

Note: this function does not create a back signature, which is needed by certification-capable, signing-capable, and authentication-capable subkeys. A back signature can be created using SignatureBuilder::sign_primary_key_binding.

This function is also used to create subkey revocations.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is SignatureType::SubkeyBinding, SignatureType::SubkeyRevocation, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Add a new subkey intended for encrypting data in motion to an existing certificate:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::KeyFlags;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;

let pk = cert.primary_key().key().clone().parts_into_secret()?;
// Derive a signer.
let mut pk_signer = pk.clone().into_keypair()?;

// Generate an encryption subkey.
let mut subkey: Key<_, _> = Key4::generate_rsa(3072)?.into();
// Derive a signer.
let mut sk_signer = subkey.clone().into_keypair()?;

let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
    .set_key_flags(&KeyFlags::empty().set_transport_encryption())?
    .sign_subkey_binding(&mut pk_signer, &pk, &subkey)?;

let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
                                   sig.into()])?;

assert_eq!(cert.with_policy(p, None)?.keys().count(), 2);

pub fn sign_primary_key_binding<P, Q>(
    self,
    subkey_signer: &mut dyn Signer,
    primary: &Key<P, PrimaryRole>,
    subkey: &Key<Q, SubordinateRole>
) -> Result<Signature> where
    P: KeyParts,
    Q: KeyParts
[src]

Generates a primary key binding signature.

A primary key binding signature, also referred to as a back signature or backsig, is a signature over the primary key and a subkey, which is made by the subkey. This signature is a statement by the subkey that it belongs to the primary key. That is, it binds the certificate to the subkey. It is normally stored in the subkey binding signature (see SignatureBuilder::sign_subkey_binding) in the Embedded Signature subpacket (set using SignatureBuilder::set_embedded_signature).

All subkeys that make signatures of any sort (signature subkeys, certification subkeys, and authentication subkeys) must include this signature in their binding signature. This signature ensures that an attacker (Mallory) can't claim someone else's (Alice's) signing key by just creating a subkey binding signature. If that were the case, anyone who has Mallory's certificate could be tricked into thinking that Mallory made signatures that were actually made by Alice. This signature prevents this attack, because it proves that the person who controls the private key for the primary key also controls the private key for the subkey and therefore intended that the subkey be associated with the primary key. Thus, although Mallory controls his own primary key and can issue a subkey binding signature for Alice's signing key, he doesn't control her signing key, and therefore can't create a valid backsig.

A primary key binding signature is not needed for encryption-capable subkeys. This is firstly because encryption-capable keys cannot make signatures. But also because an attacker doesn't gain anything by adopting an encryption-capable subkey: without the private key material, they still can't read the message's content.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is SignatureType::PrimaryKeyBinding, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Add a new signing-capable subkey to an existing certificate. Because we are adding a signing-capable subkey, the binding signature needs to include a backsig.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::KeyFlags;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;

let pk = cert.primary_key().key().clone().parts_into_secret()?;
// Derive a signer.
let mut pk_signer = pk.clone().into_keypair()?;

// Generate a signing subkey.
let mut subkey: Key<_, _> = Key4::generate_rsa(3072)?.into();
// Derive a signer.
let mut sk_signer = subkey.clone().into_keypair()?;

let sig = SignatureBuilder::new(SignatureType::SubkeyBinding)
    .set_key_flags(&KeyFlags::empty().set_signing())?
    // The backsig.  This is essential for subkeys that create signatures!
    .set_embedded_signature(
        SignatureBuilder::new(SignatureType::PrimaryKeyBinding)
            .sign_primary_key_binding(&mut sk_signer, &pk, &subkey)?)?
    .sign_subkey_binding(&mut pk_signer, &pk, &subkey)?;

let cert = cert.insert_packets(vec![Packet::SecretSubkey(subkey),
                                   sig.into()])?;

assert_eq!(cert.with_policy(p, None)?.keys().count(), 2);

pub fn sign_user_attribute_binding<P>(
    self,
    signer: &mut dyn Signer,
    key: &Key<P, PrimaryRole>,
    ua: &UserAttribute
) -> Result<Signature> where
    P: KeyParts
[src]

Generates a User Attribute binding signature.

A User Attribute binding signature or certification, a type of User ID certification, is a signature over a User Attribute and a Primary Key. It asserts that the signer is convinced that the User Attribute should be associated with the Certificate, i.e., that the binding is authentic.

OpenPGP has four types of User Attribute certifications. They are intended to express the degree of the signer's conviction. In practice, the Positive Certification type is used for self-signatures, and the Generic Certification is used for third-party certifications; the other types are not normally used.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is GenericCertification, PersonaCertification, CasualCertification, PositiveCertification, CertificationRevocation, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Add a new User Attribute to an existing certificate:

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;

// Add a user attribute.

// Get a usable (alive, non-revoked) certification key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_certification().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

let pk = cert.primary_key().key();

let mut sig =
    SignatureBuilder::new(SignatureType::PositiveCertification)
    .sign_user_attribute_binding(&mut signer, pk, &ua)?;

// Verify it.
sig.verify_user_attribute_binding(signer.public(), pk, &ua)?;

let cert = cert.insert_packets(vec![Packet::from(ua), sig.into()])?;
assert_eq!(cert.with_policy(p, None)?.user_attributes().count(), 1);

pub fn sign_hash(
    self,
    signer: &mut dyn Signer,
    hash: Context
) -> Result<Signature>
[src]

Generates a signature.

This is a low-level function. Normally, you'll want to use one of the higher-level functions, like SignatureBuilder::sign_userid_binding. But, this function is useful if you want to create a Signature for an unsupported signature type.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

pub fn sign_message<M>(
    self,
    signer: &mut dyn Signer,
    msg: M
) -> Result<Signature> where
    M: AsRef<[u8]>, 
[src]

Signs a message.

Normally, you'll want to use the streaming Signer to sign a message.

OpenPGP supports two types of signatures over messages: binary and text. The text version normalizes line endings. But, since nearly all software today can deal with both Unix and DOS line endings, it is better to just use the binary version even when dealing with text. This avoids any possible ambiguity.

This function checks that the signature type (passed to SignatureBuilder::new, set via SignatureBuilder::set_type, or copied when using SignatureBuilder::From) is Binary, Text, or SignatureType::Unknown.

The Signature's public-key algorithm field is set to the algorithm used by signer.

If neither an Issuer subpacket (set using SignatureBuilder::set_issuer, for instance) nor an Issuer Fingerprint subpacket (set using SignatureBuilder::set_issuer_fingerprint, for instance) is set, they are both added to the new Signature's unhashed subpacket area and set to the signer's KeyID and Fingerprint, respectively.

Likewise, a Signature Creation Time subpacket set to the current time is added to the hashed area if the Signature Creation Time subpacket hasn't been set using, for instance, the set_signature_creation_time method or the preserve_signature_creation_time method.

Examples

Signs a document. For large messages, you should use the streaming Signer, which streams the message's content.

use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::SignatureType;

let p = &StandardPolicy::new();

let (cert, _) = CertBuilder::new().generate()?;

// Get a usable (alive, non-revoked) certification key.
let key : &Key<_, _> = cert
    .keys().with_policy(p, None)
    .for_certification().alive().revoked(false).nth(0).unwrap().key();
// Derive a signer.
let mut signer = key.clone().parts_into_secret()?.into_keypair()?;

// For large messages, you should use openpgp::serialize::stream::Signer,
// which streams the message's content.
let msg = b"Hello, world!";
let mut sig = SignatureBuilder::new(SignatureType::Binary)
    .sign_message(&mut signer, msg)?;

// Verify it.
sig.verify_message(signer.public(), msg)?;

Methods from Deref<Target = SignatureFields>

pub fn version(&self) -> u8[src]

Gets the version.

pub fn typ(&self) -> SignatureType[src]

Gets the signature type.

This function is called typ and not type, because type is a reserved word.

pub fn hash_algo(&self) -> HashAlgorithm[src]

Gets the hash algorithm.

Trait Implementations

impl Clone for SignatureBuilder[src]

impl Deref for SignatureBuilder[src]

type Target = SignatureFields

The resulting type after dereferencing.

impl DerefMut for SignatureBuilder[src]

impl Eq for SignatureBuilder[src]

impl From<Signature> for SignatureBuilder[src]

impl From<Signature4> for SignatureBuilder[src]

impl Hash for SignatureBuilder[src]

impl PartialEq<SignatureBuilder> for SignatureBuilder[src]

impl StructuralEq for SignatureBuilder[src]

impl StructuralPartialEq for SignatureBuilder[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> DynClone for T where
    T: Clone
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.