diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-03-18 12:44:36 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-03-18 14:03:58 +0100 |
commit | 01db33b99244294702f0f58f06c6736becee28db (patch) | |
tree | 0cedce9f950866e1f355787be82a712bcf581ac4 | |
parent | fc387f5c290774a39feff97cde31ea78300d2b23 (diff) |
openpgp: Make hash algorithm configurable in streaming Signer.
- See #208.
-rw-r--r-- | guide/src/chapter_01.md | 8 | ||||
-rw-r--r-- | openpgp-ffi/include/sequoia/openpgp.h | 6 | ||||
-rw-r--r-- | openpgp-ffi/src/serialize.rs | 10 | ||||
-rw-r--r-- | openpgp/examples/generate-sign-verify.rs | 2 | ||||
-rw-r--r-- | openpgp/examples/notarize.rs | 3 | ||||
-rw-r--r-- | openpgp/examples/sign-detached.rs | 3 | ||||
-rw-r--r-- | openpgp/examples/sign.rs | 3 | ||||
-rw-r--r-- | openpgp/src/parse/stream.rs | 2 | ||||
-rw-r--r-- | openpgp/src/serialize/stream.rs | 63 | ||||
-rw-r--r-- | tool/src/commands/mod.rs | 3 | ||||
-rw-r--r-- | tool/src/commands/sign.rs | 6 | ||||
-rw-r--r-- | tool/tests/sq-sign.rs | 2 |
12 files changed, 67 insertions, 44 deletions
diff --git a/guide/src/chapter_01.md b/guide/src/chapter_01.md index ec980998..8e48a791 100644 --- a/guide/src/chapter_01.md +++ b/guide/src/chapter_01.md @@ -56,7 +56,7 @@ fn main() { # 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( @@ -186,7 +186,7 @@ fn generate() -> openpgp::Result<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( @@ -316,7 +316,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( @@ -457,7 +457,7 @@ Verified data can be read from this using [`io::Read`]. # 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-ffi/include/sequoia/openpgp.h b/openpgp-ffi/include/sequoia/openpgp.h index 169b3d7a..b00cce91 100644 --- a/openpgp-ffi/include/sequoia/openpgp.h +++ b/openpgp-ffi/include/sequoia/openpgp.h @@ -1351,7 +1351,8 @@ pgp_writer_stack_t pgp_arbitrary_writer_new (pgp_error_t *errp, /*/ pgp_writer_stack_t pgp_signer_new (pgp_error_t *errp, pgp_writer_stack_t inner, - pgp_signer_t *signers, size_t signers_len); + pgp_signer_t *signers, size_t signers_len, + uint8_t hash_algo); /*/ /// Creates a signer for a detached signature. @@ -1359,7 +1360,8 @@ pgp_writer_stack_t pgp_signer_new (pgp_error_t *errp, pgp_writer_stack_t pgp_signer_new_detached (pgp_error_t *errp, pgp_writer_stack_t inner, pgp_signer_t *signers, - size_t signers_len); + size_t signers_len, + uint8_t hash_algo); /*/ /// Writes a literal data packet. diff --git a/openpgp-ffi/src/serialize.rs b/openpgp-ffi/src/serialize.rs index 362d2aa6..61e69a98 100644 --- a/openpgp-ffi/src/serialize.rs +++ b/openpgp-ffi/src/serialize.rs @@ -145,7 +145,8 @@ pub extern "system" fn pgp_signer_new (errp: Option<&mut *mut ::error::Error>, inner: *mut writer::Stack<'static, Cookie>, signers: *const *mut Box<self::openpgp::crypto::Signer>, - signers_len: size_t) + signers_len: size_t, + hash_algo: uint8_t) -> *mut writer::Stack<'static, Cookie> { ffi_make_fry_from_errp!(errp); @@ -160,7 +161,7 @@ pub extern "system" fn pgp_signer_new ffi_param_ref_mut!(signer).as_mut() } ).collect(); - ffi_try_box!(Signer::new(*inner, signers)) + ffi_try_box!(Signer::new(*inner, signers, Some(hash_algo.into()))) } /// Creates a signer for a detached signature. @@ -169,7 +170,8 @@ pub extern "system" fn pgp_signer_new_detached (errp: Option<&mut *mut ::error::Error>, inner: *mut writer::Stack<'static, Cookie>, signers: *const *mut Box<self::openpgp::crypto::Signer>, - signers_len: size_t) + signers_len: size_t, + hash_algo: uint8_t) -> *mut writer::Stack<'static, Cookie> { ffi_make_fry_from_errp!(errp); @@ -184,7 +186,7 @@ pub extern "system" fn pgp_signer_new_detached ffi_param_ref_mut!(signer).as_mut() } ).collect(); - ffi_try_box!(Signer::detached(*inner, signers)) + ffi_try_box!(Signer::detached(*inner, signers, Some(hash_algo.into()))) } /// Writes a literal data packet. 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(); diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index 076bafbc..b5deb4a9 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -116,7 +116,8 @@ pub fn encrypt(store: &mut store::Store, sink, signers.iter_mut().map(|s| -> &mut dyn crypto::Signer { s }) .collect(), - &recipients)?; + &recipients, + None)?; } let mut literal_writer = LiteralWriter::new(sink, DataFormat::Binary, diff --git a/tool/src/commands/sign.rs b/tool/src/commands/sign.rs index 119e66e3..b9832035 100644 --- a/tool/src/commands/sign.rs +++ b/tool/src/commands/sign.rs @@ -97,9 +97,9 @@ fn sign_data(input: &mut io::Read, output_path: Option<&str>, let sink = Message::new(output); let signer = if detached { - Signer::detached(sink, signers) + Signer::detached(sink, signers, None) } else { - Signer::new(sink, signers) + Signer::new(sink, signers, None) }.context("Failed to create signer")?; let mut writer = if detached { @@ -215,7 +215,7 @@ fn sign_message(input: &mut io::Read, output_path: Option<&str>, // After the first signature group, we push the signer // onto the writer stack. let signers = signers.take().expect("only happens once"); - sink = Signer::new(sink, signers) + sink = Signer::new(sink, signers, None) .context("Failed to create signer")?; state = State::Signing { signature_count: 0, }; }, diff --git a/tool/tests/sq-sign.rs b/tool/tests/sq-sign.rs index 8a891f65..af499af3 100644 --- a/tool/tests/sq-sign.rs +++ b/tool/tests/sq-sign.rs @@ -215,7 +215,7 @@ fn sq_sign_append_on_compress_then_sign() { }; let mut keypair = KeyPair::new(key.clone(), sec.clone()).unwrap(); let signer = Signer::new(Message::new(File::create(&sig0).unwrap()), - vec![&mut keypair]) + vec![&mut keypair], None) .unwrap(); let compressor = Compressor::new(signer, CompressionAlgorithm::Uncompressed) .unwrap(); |