summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-03-18 12:44:36 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-03-18 14:03:58 +0100
commit01db33b99244294702f0f58f06c6736becee28db (patch)
tree0cedce9f950866e1f355787be82a712bcf581ac4 /openpgp
parentfc387f5c290774a39feff97cde31ea78300d2b23 (diff)
openpgp: Make hash algorithm configurable in streaming Signer.
- See #208.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/examples/generate-sign-verify.rs2
-rw-r--r--openpgp/examples/notarize.rs3
-rw-r--r--openpgp/examples/sign-detached.rs3
-rw-r--r--openpgp/examples/sign.rs3
-rw-r--r--openpgp/src/parse/stream.rs2
-rw-r--r--openpgp/src/serialize/stream.rs63
6 files changed, 47 insertions, 29 deletions
diff --git a/openpgp/examples/generate-sign-verify.rs b/openpgp/examples/generate-sign-verify.rs
index 1a7c0579..44afaf36 100644
--- a/openpgp/examples/generate-sign-verify.rs
+++ b/openpgp/examples/generate-sign-verify.rs
@@ -47,7 +47,7 @@ fn sign(sink: &mut Write, plaintext: &str, tsk: &openpgp::TPK)
let message = Message::new(sink);
// We want to sign a literal data packet.
- let signer = Signer::new(message, vec![&mut keypair])?;
+ let signer = Signer::new(message, vec![&mut keypair], None)?;
// Emit a literal data packet.
let mut literal_writer = LiteralWriter::new(
diff --git a/openpgp/examples/notarize.rs b/openpgp/examples/notarize.rs
index 1b849376..55f47708 100644
--- a/openpgp/examples/notarize.rs
+++ b/openpgp/examples/notarize.rs
@@ -65,7 +65,8 @@ fn main() {
// Now, create a signer that emits a detached signature.
let mut signer = Signer::new(
message,
- keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect())
+ keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect(),
+ None)
.expect("Failed to create signer");
// Create a parser for the message to be notarized.
diff --git a/openpgp/examples/sign-detached.rs b/openpgp/examples/sign-detached.rs
index e558aa5e..98d35b5c 100644
--- a/openpgp/examples/sign-detached.rs
+++ b/openpgp/examples/sign-detached.rs
@@ -60,7 +60,8 @@ fn main() {
// Now, create a signer that emits a detached signature.
let mut signer = Signer::detached(
message,
- keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect())
+ keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect(),
+ None)
.expect("Failed to create signer");
// Copy all the data.
diff --git a/openpgp/examples/sign.rs b/openpgp/examples/sign.rs
index 33e7625e..706b2a20 100644
--- a/openpgp/examples/sign.rs
+++ b/openpgp/examples/sign.rs
@@ -60,7 +60,8 @@ fn main() {
// Now, create a signer that emits a signature.
let signer = Signer::new(
message,
- keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect())
+ keys.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }).collect(),
+ None)
.expect("Failed to create signer");
// Then, create a literal writer to wrap the data in a literal
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs
index fcea6038..0c842760 100644
--- a/openpgp/src/parse/stream.rs
+++ b/openpgp/src/parse/stream.rs
@@ -1498,7 +1498,7 @@ mod test {
let mut keypair = KeyPair::new(key.clone(), sec.clone()).unwrap();
let m = Message::new(&mut buf);
- let signer = Signer::new(m, vec![&mut keypair]).unwrap();
+ let signer = Signer::new(m, vec![&mut keypair], None).unwrap();
let mut ls = LiteralWriter::new(signer, DataFormat::Binary, None, None).unwrap();
ls.write_all(&mut vec![42u8; 30 * 1024 * 1024]).unwrap();
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index c808fd52..6c303054 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -193,6 +193,8 @@ impl<'a> writer::Stackable<'a, Cookie> for ArbitraryWriter<'a> {
/// For every signing key, a signer writes a one-pass-signature
/// packet, then hashes and emits the data stream, then for every key
/// writes a signature packet.
+///
+/// Unless otherwise specified, SHA512 is used as hash algorithm.
pub struct Signer<'a> {
// The underlying writer.
//
@@ -238,7 +240,7 @@ impl<'a> Signer<'a> {
/// let mut o = vec![];
/// {
/// let message = Message::new(&mut o);
- /// let signer = Signer::new(message, vec![&mut signing_keypair])?;
+ /// let signer = Signer::new(message, vec![&mut signing_keypair], None)?;
/// let mut ls = LiteralWriter::new(signer, DataFormat::Text, None, None)?;
/// ls.write_all(b"Make it so, number one!")?;
/// ls.finalize()?;
@@ -268,10 +270,13 @@ impl<'a> Signer<'a> {
/// # Ok(())
/// # }
/// ```
- pub fn new(inner: writer::Stack<'a, Cookie>,
- signers: Vec<&'a mut dyn crypto::Signer>)
- -> Result<writer::Stack<'a, Cookie>> {
- Self::make(inner, signers, None, false)
+ pub fn new<H>(inner: writer::Stack<'a, Cookie>,
+ signers: Vec<&'a mut dyn crypto::Signer>,
+ hash_algo: H)
+ -> Result<writer::Stack<'a, Cookie>>
+ where H: Into<Option<HashAlgorithm>>
+ {
+ Self::make(inner, signers, None, false, hash_algo)
}
/// Creates a signer with intended recipients.
@@ -280,13 +285,16 @@ impl<'a> Signer<'a> {
/// recipients of the encryption container containing the
/// signature. This prevents forwarding a signed message using a
/// different encryption context.
- pub fn with_intended_recipients(inner: writer::Stack<'a, Cookie>,
- signers: Vec<&'a mut dyn crypto::Signer>,
- recipients: &[&'a TPK])
- -> Result<writer::Stack<'a, Cookie>> {
+ pub fn with_intended_recipients<H>(inner: writer::Stack<'a, Cookie>,
+ signers: Vec<&'a mut dyn crypto::Signer>,
+ recipients: &[&'a TPK],
+ hash_algo: H)
+ -> Result<writer::Stack<'a, Cookie>>
+ where H: Into<Option<HashAlgorithm>>
+ {
Self::make(inner, signers,
Some(recipients.iter().map(|r| r.fingerprint()).collect()),
- false)
+ false, hash_algo)
}
/// Creates a signer for a detached signature.
@@ -314,7 +322,8 @@ impl<'a> Signer<'a> {
/// let mut o = vec![];
/// {
/// let message = Message::new(&mut o);
- /// let mut signer = Signer::detached(message, vec![&mut signing_keypair])?;
+ /// let mut signer =
+ /// Signer::detached(message, vec![&mut signing_keypair], None)?;
/// signer.write_all(b"Make it so, number one!")?;
/// // In reality, just io::copy() the file to be signed.
/// signer.finalize()?;
@@ -346,19 +355,24 @@ impl<'a> Signer<'a> {
/// # Ok(())
/// # }
/// ```
- pub fn detached(inner: writer::Stack<'a, Cookie>,
- signers: Vec<&'a mut dyn crypto::Signer>)
- -> Result<writer::Stack<'a, Cookie>> {
- Self::make(inner, signers, None, true)
- }
-
- fn make(inner: writer::Stack<'a, Cookie>,
- signers: Vec<&'a mut dyn crypto::Signer>,
- intended_recipients: Option<Vec<Fingerprint>>, detached: bool)
- -> Result<writer::Stack<'a, Cookie>> {
+ pub fn detached<H>(inner: writer::Stack<'a, Cookie>,
+ signers: Vec<&'a mut dyn crypto::Signer>,
+ hash_algo: H)
+ -> Result<writer::Stack<'a, Cookie>>
+ where H: Into<Option<HashAlgorithm>>
+ {
+ Self::make(inner, signers, None, true, hash_algo)
+ }
+
+ fn make<H>(inner: writer::Stack<'a, Cookie>,
+ signers: Vec<&'a mut dyn crypto::Signer>,
+ intended_recipients: Option<Vec<Fingerprint>>, detached: bool,
+ hash_algo: H)
+ -> Result<writer::Stack<'a, Cookie>>
+ where H: Into<Option<HashAlgorithm>>
+ {
let mut inner = writer::BoxStack::from(inner);
- // Just always use SHA512.
- let hash_algo = HashAlgorithm::SHA512;
+ let hash_algo = hash_algo.into().unwrap_or(HashAlgorithm::SHA512);
if signers.len() == 0 {
return Err(Error::InvalidArgument(
@@ -1355,7 +1369,8 @@ mod test {
m,
signers.iter_mut()
.map(|s| -> &mut dyn crypto::Signer {s})
- .collect())
+ .collect(),
+ None)
.unwrap();
let mut ls = LiteralWriter::new(signer, T, None, None).unwrap();
ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap();