Struct sequoia_openpgp::serialize::stream::Signer
source · pub struct Signer<'a> { /* private fields */ }
Expand description
Signs a message.
Signs a message with every crypto::Signer
added to the
streaming signer.
Implementations§
source§impl<'a> Signer<'a>
impl<'a> Signer<'a>
sourcepub fn new<S>(inner: Message<'a>, signer: S) -> Self
pub fn new<S>(inner: Message<'a>, signer: S) -> Self
Creates a signer.
Signs the message with the given crypto::Signer
. To
create more than one signature, add more crypto::Signer
s
using Signer::add_signer
. Properties of the signatures
can be tweaked using the methods of this type. Notably, to
generate a detached signature (see Section 11.4 of RFC
4880), use Signer::detached
. For even more control over
the generated signatures, use Signer::with_template
.
§Examples
use std::io::{Read, Write};
use sequoia_openpgp as openpgp;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
use openpgp::policy::StandardPolicy;
let p = &StandardPolicy::new();
let cert: Cert = // ...
let signing_keypair = cert.keys().secret()
.with_policy(p, None).supported().alive().revoked(false).for_signing()
.nth(0).unwrap()
.key().clone().into_keypair()?;
let mut sink = vec![];
{
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
// Customize the `Signer` here.
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
}
// Now check the signature.
struct Helper<'a>(&'a openpgp::Cert);
impl<'a> VerificationHelper for Helper<'a> {
fn get_certs(&mut self, _: &[openpgp::KeyHandle])
-> openpgp::Result<Vec<openpgp::Cert>> {
Ok(vec![self.0.clone()])
}
fn check(&mut self, structure: MessageStructure)
-> openpgp::Result<()> {
if let MessageLayer::SignatureGroup { ref results } =
structure.iter().nth(0).unwrap()
{
results.get(0).unwrap().as_ref().unwrap();
Ok(())
} else { panic!() }
}
}
let mut verifier = VerifierBuilder::from_bytes(&sink)?
.with_policy(p, None, Helper(&cert))?;
let mut message = String::new();
verifier.read_to_string(&mut message)?;
assert_eq!(&message, "Make it so, number one!");
sourcepub fn with_template<S, T>(inner: Message<'a>, signer: S, template: T) -> Self
pub fn with_template<S, T>(inner: Message<'a>, signer: S, template: T) -> Self
Creates a signer with a given signature template.
Signs the message with the given crypto::Signer
like
Signer::new
, but allows more control over the generated
signatures. The given signature::SignatureBuilder
is used to
create all the signatures.
For every signature, the creation time is set to the current
time or the one specified using Signer::creation_time
, the
intended recipients are added (see
Signer::add_intended_recipient
), the issuer and issuer
fingerprint subpackets are set according to the signing key,
and the hash algorithm set using Signer::hash_algo
is used
to create the signature.
§Examples
use std::io::{Read, Write};
use sequoia_openpgp as openpgp;
use openpgp::types::SignatureType;
use openpgp::packet::signature;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
let message = Message::new(&mut sink);
let message = Signer::with_template(
message, signing_keypair,
signature::SignatureBuilder::new(SignatureType::Text)
.add_notation("issuer@starfleet.command", "Jean-Luc Picard",
None, true)?)
// Further customize the `Signer` here.
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
sourcepub fn detached(self) -> Self
pub fn detached(self) -> Self
Creates a signer for a detached signature.
Changes the Signer
to create a detached signature (see
Section 11.4 of RFC 4880). Note that the literal data must
not be wrapped using the LiteralWriter
.
This overrides any prior call to Signer::cleartext
.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::serialize::stream::{Message, Signer};
use openpgp::policy::StandardPolicy;
let p = &StandardPolicy::new();
let mut sink = vec![];
{
let message = Message::new(&mut sink);
let mut signer = Signer::new(message, signing_keypair)
.detached()
// Customize the `Signer` here.
.build()?;
// Write the data directly to the `Signer`.
signer.write_all(b"Make it so, number one!")?;
// In reality, just io::copy() the file to be signed.
signer.finalize()?;
}
// Now check the signature.
struct Helper<'a>(&'a openpgp::Cert);
impl<'a> VerificationHelper for Helper<'a> {
fn get_certs(&mut self, _: &[openpgp::KeyHandle])
-> openpgp::Result<Vec<openpgp::Cert>> {
Ok(vec![self.0.clone()])
}
fn check(&mut self, structure: MessageStructure)
-> openpgp::Result<()> {
if let MessageLayer::SignatureGroup { ref results } =
structure.iter().nth(0).unwrap()
{
results.get(0).unwrap().as_ref().unwrap();
Ok(())
} else { panic!() }
}
}
let mut verifier = DetachedVerifierBuilder::from_bytes(&sink)?
.with_policy(p, None, Helper(&cert))?;
verifier.verify_bytes(b"Make it so, number one!")?;
sourcepub fn cleartext(self) -> Self
pub fn cleartext(self) -> Self
Creates a signer for a cleartext signed message.
Changes the Signer
to create a cleartext signed message (see
Section 7 of RFC 4880). Note that the literal data must
not be wrapped using the LiteralWriter
. This implies
ASCII armored output, do not add an Armorer
to the
stack.
Note:
-
The cleartext signature framework does not hash trailing whitespace (in this case, space and tab, see Section 7.1 of RFC 4880 for more information). We align what we emit and what is being signed by trimming whitespace off of line endings.
-
That means that you can not recover a byte-accurate copy of the signed message if your message contains either a line with trailing whitespace, or no final newline. This is a limitation of the Cleartext Signature Framework, which is not designed to be reversible (see Section 7 of RFC 4880).
This overrides any prior call to Signer::detached
.
§Examples
use std::io::{Write, Read};
use sequoia_openpgp as openpgp;
use openpgp::serialize::stream::{Message, Signer};
use openpgp::policy::StandardPolicy;
let p = &StandardPolicy::new();
let mut sink = vec![];
{
let message = Message::new(&mut sink);
let mut signer = Signer::new(message, signing_keypair)
.cleartext()
// Customize the `Signer` here.
.build()?;
// Write the data directly to the `Signer`.
signer.write_all(b"Make it so, number one!")?;
// In reality, just io::copy() the file to be signed.
signer.finalize()?;
}
// Now check the signature.
struct Helper<'a>(&'a openpgp::Cert);
impl<'a> VerificationHelper for Helper<'a> {
fn get_certs(&mut self, _: &[openpgp::KeyHandle])
-> openpgp::Result<Vec<openpgp::Cert>> {
Ok(vec![self.0.clone()])
}
fn check(&mut self, structure: MessageStructure)
-> openpgp::Result<()> {
if let MessageLayer::SignatureGroup { ref results } =
structure.iter().nth(0).unwrap()
{
results.get(0).unwrap().as_ref().unwrap();
Ok(())
} else { panic!() }
}
}
let mut verifier = VerifierBuilder::from_bytes(&sink)?
.with_policy(p, None, Helper(&cert))?;
let mut content = Vec::new();
verifier.read_to_end(&mut content)?;
assert_eq!(content, b"Make it so, number one!");
sourcepub fn add_signer<S>(self, signer: S) -> Self
pub fn add_signer<S>(self, signer: S) -> Self
Adds an additional signer.
Can be used multiple times.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
.add_signer(additional_signing_keypair)
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
sourcepub fn add_intended_recipient(self, recipient: &Cert) -> Self
pub fn add_intended_recipient(self, recipient: &Cert) -> Self
Adds an intended recipient.
Indicates that the given certificate is an intended recipient of this message. Can be used multiple times. This prevents Surreptitious Forwarding of encrypted and signed messages, i.e. forwarding a signed message using a different encryption context.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
let recipient: Cert = // ...
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
.add_intended_recipient(&recipient)
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
sourcepub fn hash_algo(self, algo: HashAlgorithm) -> Result<Self>
pub fn hash_algo(self, algo: HashAlgorithm) -> Result<Self>
Sets the preferred hash algorithm to use for the signatures.
Note that some signers only support a subset of hash
algorithms, see [crate::crypto::Signer.acceptable_hashes
].
If the hash selected using this method is not supported by a
signer, a hash supported by the signer is selected instead.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::types::HashAlgorithm;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
.hash_algo(HashAlgorithm::SHA384)?
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
sourcepub fn creation_time<T: Into<SystemTime>>(self, creation_time: T) -> Self
pub fn creation_time<T: Into<SystemTime>>(self, creation_time: T) -> Self
Sets the signature’s creation time to time
.
Note: it is up to the caller to make sure the signing keys are
actually valid as of time
.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::types::Timestamp;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
use openpgp::policy::StandardPolicy;
let p = &StandardPolicy::new();
let cert: Cert = // ...
let signing_key = cert.keys().secret()
.with_policy(p, None).supported().alive().revoked(false).for_signing()
.nth(0).unwrap()
.key();
let signing_keypair = signing_key.clone().into_keypair()?;
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
.creation_time(Timestamp::now()
.round_down(None, signing_key.creation_time())?)
.build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"Make it so, number one!")?;
message.finalize()?;
sourcepub fn build(self) -> Result<Message<'a>>
pub fn build(self) -> Result<Message<'a>>
Builds the signer, returning the writer stack.
The most useful filter to push to the writer stack next is the
LiteralWriter
. Note, if you are creating a signed OpenPGP
message (see Section 11.3 of RFC 4880), literal data must
be wrapped using the LiteralWriter
. On the other hand, if
you are creating a detached signature (see Section 11.4 of
RFC 4880), the literal data must not be wrapped using the
LiteralWriter
.
§Examples
use std::io::Write;
use sequoia_openpgp as openpgp;
use openpgp::types::Timestamp;
use openpgp::serialize::stream::{Message, Signer};
let message = Message::new(&mut sink);
let message = Signer::new(message, signing_keypair)
// Customize the `Signer` here.
.build()?;
Trait Implementations§
source§impl<'a> Write for Signer<'a>
impl<'a> Write for Signer<'a>
source§fn write(&mut self, buf: &[u8]) -> Result<usize>
fn write(&mut self, buf: &[u8]) -> Result<usize>
source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector
)1.0.0 · source§fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored
)