diff options
author | Kai Michaelis <kai@sequoia-pgp.org> | 2018-04-23 18:29:30 +0200 |
---|---|---|
committer | Kai Michaelis <kai@sequoia-pgp.org> | 2018-04-23 18:32:22 +0200 |
commit | d1345c3ffbf460f3007f063a989c795cdb50318b (patch) | |
tree | 2fedaabe45e4bf1c4e384aeeb2b65509dcd3d258 /openpgp | |
parent | d6918cb480869e8ef911cf57dec63edbacf2ca94 (diff) |
openpgp: Enums for various alogrithms
Adds enums for cryptographic and compression algorithms. Functions that
operate on algo identifiers are now member functions (hash_context ->
HashAlgo::context()).
The identifiers support convertions from and to u8 as well as Display.
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/Cargo.toml | 1 | ||||
-rw-r--r-- | openpgp/src/constants.rs | 209 | ||||
-rw-r--r-- | openpgp/src/hash.rs | 210 | ||||
-rw-r--r-- | openpgp/src/lib.rs | 126 | ||||
-rw-r--r-- | openpgp/src/one_pass_sig.rs | 5 | ||||
-rw-r--r-- | openpgp/src/parse/hashed_reader.rs | 5 | ||||
-rw-r--r-- | openpgp/src/parse/parse.rs | 29 | ||||
-rw-r--r-- | openpgp/src/s2k.rs | 32 | ||||
-rw-r--r-- | openpgp/src/serialize/serialize.rs | 10 | ||||
-rw-r--r-- | openpgp/src/signature.rs | 5 | ||||
-rw-r--r-- | openpgp/src/skesk.rs | 11 | ||||
-rw-r--r-- | openpgp/src/symmetric.rs | 221 |
12 files changed, 633 insertions, 231 deletions
diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index 31ceabd8..d117c0d7 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -11,6 +11,7 @@ failure = "0.1.1" flate2 = "1.0.1" nettle = { git = "https://gitlab.com/sequoia-pgp/nettle-rs.git" } num-derive = "0.1.41" +quickcheck = "0.6" [dependencies.num] version = "0.1.40" diff --git a/openpgp/src/constants.rs b/openpgp/src/constants.rs new file mode 100644 index 00000000..ef4d8b09 --- /dev/null +++ b/openpgp/src/constants.rs @@ -0,0 +1,209 @@ +use std::fmt; + +use quickcheck::{Arbitrary, Gen}; + +/* + * 9.1. Public-Key Algorithms + * + * ID Algorithm + * -- --------- + * 1 - RSA (Encrypt or Sign) [HAC] + * 2 - RSA Encrypt-Only [HAC] + * 3 - RSA Sign-Only [HAC] + * 16 - Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + * 17 - DSA (Digital Signature Algorithm) [FIPS186] [HAC] + * 18 - Reserved for Elliptic Curve + * 19 - Reserved for ECDSA + * 20 - Reserved (formerly Elgamal Encrypt or Sign) + * 21 - Reserved for Diffie-Hellman (X9.42, + * as defined for IETF-S/MIME) + * 100 to 110 - Private/Experimental algorithm + */ +#[derive(Clone,Copy,PartialEq,Eq,Debug)] +pub enum PublicKeyAlgorithm { + RsaEncryptSign, + RsaEncrypt, + RsaSign, + Elgamal, + Dsa, + Private(u8), + Unknown(u8), +} + +impl From<u8> for PublicKeyAlgorithm { + fn from(u: u8) -> Self { + match u { + 1 => PublicKeyAlgorithm::RsaEncryptSign, + 2 => PublicKeyAlgorithm::RsaEncrypt, + 3 => PublicKeyAlgorithm::RsaSign, + 16 => PublicKeyAlgorithm::Elgamal, + 17 => PublicKeyAlgorithm::Dsa, + 100...110 => PublicKeyAlgorithm::Private(u), + u => PublicKeyAlgorithm::Unknown(u), + } + } +} + +impl Into<u8> for PublicKeyAlgorithm { + fn into(self) -> u8 { + match self { + PublicKeyAlgorithm::RsaEncryptSign => 1, + PublicKeyAlgorithm::RsaEncrypt => 2, + PublicKeyAlgorithm::RsaSign => 3, + PublicKeyAlgorithm::Elgamal => 16, + PublicKeyAlgorithm::Dsa => 17, + PublicKeyAlgorithm::Private(u) => u, + PublicKeyAlgorithm::Unknown(u) => u, + } + } +} + +impl fmt::Display for PublicKeyAlgorithm { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + PublicKeyAlgorithm::RsaEncryptSign => + f.write_str("RSA (Encrypt or Sign)"), + PublicKeyAlgorithm::RsaEncrypt => + f.write_str("RSA Encrypt-Only"), + PublicKeyAlgorithm::RsaSign => + f.write_str("RSA Sign-Only"), + PublicKeyAlgorithm::Elgamal => + f.write_str("Elgamal (Encrypt-Only)"), + PublicKeyAlgorithm::Dsa => + f.write_str("DSA (Digital Signature Algorithm)"), + PublicKeyAlgorithm::Private(u) => + f.write_fmt(format_args!("Private/Experimental public key algorithm {}",u)), + PublicKeyAlgorithm::Unknown(u) => + f.write_fmt(format_args!("Unknown public key algorithm {}",u)), + } + } +} + +impl Arbitrary for PublicKeyAlgorithm { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + u8::arbitrary(g).into() + } +} + + +/* + * 9.3. Compression Algorithms + * + * ID Algorithm + * -- --------- + * 0 - Uncompressed + * 1 - ZIP [RFC1951] + * 2 - ZLIB [RFC1950] + * 3 - BZip2 [BZ2] + * 100 to 110 - Private/Experimental algorithm + */ +#[derive(Clone,Copy,PartialEq,Eq,Debug)] +pub enum CompressionAlgorithm { + Uncompressed, + Zip, + Zlib, + BZip2, + Private(u8), + Unknown(u8), +} + +impl From<u8> for CompressionAlgorithm { + fn from(u: u8) -> Self { + match u { + 0 => CompressionAlgorithm::Uncompressed, + 1 => CompressionAlgorithm::Zip, + 2 => CompressionAlgorithm::Zlib, + 3 => CompressionAlgorithm::BZip2, + 100...110 => CompressionAlgorithm::Private(u), + u => CompressionAlgorithm::Unknown(u), + } + } +} + +impl Into<u8> for CompressionAlgorithm { + fn into(self) -> u8 { + match self { + CompressionAlgorithm::Uncompressed => 0, + CompressionAlgorithm::Zip => 1, + CompressionAlgorithm::Zlib => 2, + CompressionAlgorithm::BZip2 => 3, + CompressionAlgorithm::Private(u) => u, + CompressionAlgorithm::Unknown(u) => u, + } + } +} + +impl fmt::Display for CompressionAlgorithm { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + CompressionAlgorithm::Uncompressed => f.write_str("Uncompressed"), + CompressionAlgorithm::Zip => f.write_str("ZIP"), + CompressionAlgorithm::Zlib => f.write_str("ZLIB"), + CompressionAlgorithm::BZip2 => f.write_str("BZip2"), + CompressionAlgorithm::Private(u) => + f.write_fmt(format_args!("Private/Experimental compression algorithm {}",u)), + CompressionAlgorithm::Unknown(u) => + f.write_fmt(format_args!("Unknown comppression algorithm {}",u)), + } + } +} + +impl Arbitrary for CompressionAlgorithm { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + u8::arbitrary(g).into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + quickcheck! { + fn comp_roundtrip(comp: CompressionAlgorithm) -> bool { + let val: u8 = comp.clone().into(); + comp == CompressionAlgorithm::from(val) + } + } + + quickcheck! { + fn comp_display(comp: CompressionAlgorithm) -> bool { + let s = format!("{}",comp); + !s.is_empty() + } + } + + quickcheck! { + fn comp_parse(comp: CompressionAlgorithm) -> bool { + match comp { + CompressionAlgorithm::Unknown(u) => u > 110 || (u > 3 && u < 100), + CompressionAlgorithm::Private(u) => u >= 100 && u <= 110, + _ => true + } + } + } + + quickcheck! { + fn pk_roundtrip(pk: PublicKeyAlgorithm) -> bool { + let val: u8 = pk.clone().into(); + pk == PublicKeyAlgorithm::from(val) + } + } + + quickcheck! { + fn pk_display(pk: PublicKeyAlgorithm) -> bool { + let s = format!("{}",pk); + !s.is_empty() + } + } + + quickcheck! { + fn pk_parse(pk: PublicKeyAlgorithm) -> bool { + match pk { + PublicKeyAlgorithm::Unknown(u) => + u == 0 || u > 110 || (u >= 4 && u <= 15) || (u >= 18 && u < 100), + PublicKeyAlgorithm::Private(u) => u >= 100 && u <= 110, + _ => true + } + } + } +} diff --git a/openpgp/src/hash.rs b/openpgp/src/hash.rs index 01a25a40..8bfe4953 100644 --- a/openpgp/src/hash.rs +++ b/openpgp/src/hash.rs @@ -1,31 +1,151 @@ //! Functionality to hash packets, and generate hashes. -use HashAlgo; - use UserID; use UserAttribute; use Key; use Signature; +use Error; +use Result; + +use std::str::FromStr; +use std::result; +use std::fmt; use nettle::Hash; -use nettle::hash::insecure_do_not_use::Sha1; -use nettle::hash::{Sha224, Sha256, Sha384, Sha512}; - -// Returns a fresh hash context. -pub fn hash_context(hash_algo: HashAlgo) -> Box<Hash> { - match hash_algo { - HashAlgo::SHA1 => Box::new(Sha1::default()), - HashAlgo::SHA224 => Box::new(Sha224::default()), - HashAlgo::SHA256 => Box::new(Sha256::default()), - HashAlgo::SHA384 => Box::new(Sha384::default()), - HashAlgo::SHA512 => Box::new(Sha512::default()), - algo => { - eprintln!("algo {:?} not implemented", algo); - unimplemented!(); - }, +use quickcheck::{Arbitrary, Gen}; + +/// The OpenPGP hash algorithms as defined in [Section 9.4 of RFC 4880]. +/// +/// [Section 9.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-9.4 +/// +/// The values correspond to the serialized format. +#[derive(Clone,Copy,PartialEq,Eq,Debug)] +pub enum HashAlgo { + MD5, + SHA1, + RipeMD, + SHA256, + SHA384, + SHA512, + SHA224, + Private(u8), + Unknown(u8), +} + +impl From<u8> for HashAlgo { + fn from(u: u8) -> Self { + match u { + 1 => HashAlgo::MD5, + 2 => HashAlgo::SHA1, + 3 => HashAlgo::RipeMD, + 8 => HashAlgo::SHA256, + 9 => HashAlgo::SHA384, + 10 => HashAlgo::SHA512, + 11 => HashAlgo::SHA224, + 100...110 => HashAlgo::Private(u), + u => HashAlgo::Unknown(u), + } + } +} + +impl Into<u8> for HashAlgo { + fn into(self) -> u8 { + match self { + HashAlgo::MD5 => 1, + HashAlgo::SHA1 => 2, + HashAlgo::RipeMD => 3, + HashAlgo::SHA256 => 8, + HashAlgo::SHA384 => 9, + HashAlgo::SHA512 => 10, + HashAlgo::SHA224 => 11, + HashAlgo::Private(u) => u, + HashAlgo::Unknown(u) => u, + } + } +} + +impl FromStr for HashAlgo { + type Err = (); + + fn from_str(s: &str) -> result::Result<Self, ()> { + if s == "MD5" { + Ok(HashAlgo::MD5) + } else if s == "SHA1" { + Ok(HashAlgo::SHA1) + } else if s == "RipeMD160" { + Ok(HashAlgo::RipeMD) + } else if s == "SHA256" { + Ok(HashAlgo::SHA256) + } else if s == "SHA384" { + Ok(HashAlgo::SHA384) + } else if s == "SHA512" { + Ok(HashAlgo::SHA512) + } else if s == "SHA224" { + Ok(HashAlgo::SHA224) + } else { + Err(()) + } + } +} + +impl fmt::Display for HashAlgo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + HashAlgo::MD5 => f.write_str("MD5"), + HashAlgo::SHA1 => f.write_str("SHA1"), + HashAlgo::RipeMD => f.write_str("RipeMD160"), + HashAlgo::SHA256 => f.write_str("SHA256"), + HashAlgo::SHA384 => f.write_str("SHA384"), + HashAlgo::SHA512 => f.write_str("SHA512"), + HashAlgo::SHA224 => f.write_str("SHA224"), + HashAlgo::Private(u) => + f.write_fmt(format_args!("Private/Experimental hash algorithm {}",u)), + HashAlgo::Unknown(u) => + f.write_fmt(format_args!("Unknown hash algorithm {}",u)), + } } } +impl HashAlgo { + pub fn is_supported(self) -> bool { + match self { + HashAlgo::SHA1 => true, + HashAlgo::SHA224 => true, + HashAlgo::SHA256 => true, + HashAlgo::SHA384 => true, + HashAlgo::SHA512 => true, + HashAlgo::RipeMD => false, + HashAlgo::MD5 => false, + HashAlgo::Private(_) => false, + HashAlgo::Unknown(_) => false, + } + } + + pub fn context(self) -> Result<Box<Hash>> { + use nettle::hash::*; + use nettle::hash::insecure_do_not_use::Sha1; + + match self { + HashAlgo::SHA1 => Ok(Box::new(Sha1::default())), + HashAlgo::SHA224 => Ok(Box::new(Sha224::default())), + HashAlgo::SHA256 => Ok(Box::new(Sha256::default())), + HashAlgo::SHA384 => Ok(Box::new(Sha384::default())), + HashAlgo::SHA512 => Ok(Box::new(Sha512::default())), + HashAlgo::MD5 | HashAlgo::RipeMD => + Err(Error::UnknownHashAlgorithm(self.into()).into()), + HashAlgo::Private(x) | HashAlgo::Unknown(x) => + Err(Error::UnknownHashAlgorithm(x).into()), + } + } +} + +impl Arbitrary for HashAlgo { + fn arbitrary<G: Gen>(g: &mut G) -> Self { + u8::arbitrary(g).into() + } +} + + impl UserID { // Update the Hash with a hash of the key. pub fn hash<H: Hash>(&self, hash: &mut H) { @@ -104,7 +224,7 @@ impl Signature { header[0] = 4; header[1] = self.sigtype; header[2] = self.pk_algo; - header[3] = self.hash_algo; + header[3] = self.hash_algo.into(); // The length of the hashed area, as a 16-bit endian number. let len = self.hashed_area.data.len(); @@ -136,8 +256,8 @@ impl Signature { // Return the message digest of the primary key binding over the // specified primary key, subkey, and signature. pub fn primary_key_binding_hash(&self, key: &Key) -> Vec<u8> { - let mut h - = hash_context(HashAlgo::from_numeric(self.hash_algo).unwrap()); + let h: HashAlgo = self.hash_algo.into(); + let mut h: Box<Hash> = h.context().unwrap(); key.hash(&mut h); self.hash(&mut h); @@ -151,8 +271,8 @@ impl Signature { // specified primary key, subkey, and signature. pub fn subkey_binding_hash(&self, key: &Key, subkey: &Key) -> Vec<u8> { - let mut h - = hash_context(HashAlgo::from_numeric(self.hash_algo).unwrap()); + let h: HashAlgo = self.hash_algo.into(); + let mut h: Box<Hash> = h.context().unwrap(); key.hash(&mut h); subkey.hash(&mut h); @@ -167,8 +287,8 @@ impl Signature { // specified primary key, user ID, and signature. pub fn userid_binding_hash(&self, key: &Key, userid: &UserID) -> Vec<u8> { - let mut h - = hash_context(HashAlgo::from_numeric(self.hash_algo).unwrap()); + let h: HashAlgo = self.hash_algo.into(); + let mut h: Box<Hash> = h.context().unwrap(); key.hash(&mut h); userid.hash(&mut h); @@ -183,8 +303,8 @@ impl Signature { // the specified primary key, user attribute, and signature. pub fn user_attribute_binding_hash(&self, key: &Key, ua: &UserAttribute) -> Vec<u8> { - let mut h - = hash_context(HashAlgo::from_numeric(self.hash_algo).unwrap()); + let h: HashAlgo = self.hash_algo.into(); + let mut h: Box<Hash> = h.context().unwrap(); key.hash(&mut h); ua.hash(&mut h); @@ -198,6 +318,7 @@ impl Signature { #[cfg(test)] mod test { + use super::*; use TPK; macro_rules! bytes { @@ -265,4 +386,41 @@ mod test { = check(TPK::from_bytes(bytes!("dkg.gpg")).unwrap()); assert!(ua_sigs > 0); } + + quickcheck! { + fn hash_roundtrip(hash: HashAlgo) -> bool { + let val: u8 = hash.clone().into(); + hash == HashAlgo::from(val) + } + } + + quickcheck! { + fn hash_roundtrip_str(hash: HashAlgo) -> bool { + match hash { + HashAlgo::Private(_) | HashAlgo::Unknown(_) => true, + hash => { + let s = format!("{}",hash); + hash == HashAlgo::from_str(&s).unwrap() + } + } + } + } + + quickcheck! { + fn hash_display(hash: HashAlgo) -> bool { + let s = format!("{}",hash); + !s.is_empty() + } + } + + quickcheck! { + fn hash_parse(hash: HashAlgo) -> bool { + match hash { + HashAlgo::Unknown(u) => u == 0 || (u > 11 && u < 100) || + u > 110 || (u >= 4 && u <= 7) || u == 0, + HashAlgo::Private(u) => u >= 100 && u <= 110, + _ => true + } + } + } } diff --git a/openpgp/src/lib.rs b/openpgp/src/lib.rs index de9d4954..180197ed 100644 --- a/openpgp/src/lib.rs +++ b/openpgp/src/lib.rs @@ -52,6 +52,13 @@ extern crate nettle; extern crate flate2; extern crate bzip2; +#[cfg(test)] +#[macro_use] +extern crate quickcheck; + +#[cfg(not(test))] +extern crate quickcheck; + use std::fmt; use std::io; use std::cell::RefCell; @@ -71,8 +78,10 @@ use parse::SubpacketArea; pub mod tpk; pub mod serialize; -pub mod hash; +mod hash; +pub use hash::HashAlgo; pub mod symmetric; +pub use symmetric::SymmetricAlgo; mod s2k; mod unknown; @@ -85,6 +94,7 @@ mod literal; mod compressed_data; mod skesk; mod message; +mod constants; pub type Result<T> = ::std::result::Result<T, failure::Error>; @@ -308,115 +318,9 @@ impl Tag { } } -/// The OpenPGP hash algorithms as defined in [Section 9.4 of RFC 4880]. -/// -/// [Section 9.4 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-9.4 -/// -/// The values correspond to the serialized format. -/// -/// Use [`HashAlgo::from_numeric`] to translate a numeric value to a symbolic -/// one. -/// -/// [`HashAlgo::from_numeric`]: enum.HashAlgo.html#method.from_numeric -#[derive(Debug)] -#[derive(FromPrimitive)] -#[derive(ToPrimitive)] -// We need PartialEq so that assert_eq! works. -#[derive(PartialEq)] -#[derive(Clone, Copy)] -pub enum HashAlgo { - MD5 = 1, - SHA1 = 2, - RIPEMD = 3, - SHA256 = 8, - SHA384 = 9, - SHA512 = 10, - SHA224 = 11, -} - -impl HashAlgo { - /// Converts a numeric value to an `Option<HashAlgo>`. - /// - /// Returns None, if the value is out of range. - /// - /// # Examples - /// - /// ```rust - /// use openpgp::HashAlgo; - /// - /// assert_eq!(HashAlgo::from_numeric(2).unwrap(), HashAlgo::SHA1); - /// ``` - pub fn from_numeric(value: u8) -> Result<Self> { - if let Some(algo) = num::FromPrimitive::from_u8(value) { - Ok(algo) - } else { - Err(Error::UnknownHashAlgorithm(value).into()) - } - } - /// Converts a `HashAlgo` to its corresponding numeric value. - pub fn to_numeric(self) -> u8 { - num::ToPrimitive::to_u8(&self).unwrap() - } -} - -/// The symmetric-key algorithms as defined in [Section 9.2 of RFC 4880]. -/// -/// [Section 9.2 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-9.2 -/// -/// The values correspond to the serialized format. -/// -/// Use [`SymmetricAlgo::from_numeric`] to translate a numeric value -/// to a symbolic one. -/// -/// [`SymmetricAlgo::from_numeric`]: enum.SymmetricAlgo.html#method.from_numeric -#[derive(Debug)] -#[derive(FromPrimitive)] -#[derive(ToPrimitive)] -// We need PartialEq so that assert_eq! works. -#[derive(PartialEq)] -#[derive(Clone, Copy)] -pub enum SymmetricAlgo { - Unencrypted = 0, - IDEA = 1, - TripleDES = 2, - CAST5 = 3, - Blowfish = 4, - AES128 = 7, - AES192 = 8, - AES256 = 9, - Twofish = 10, -} - -impl SymmetricAlgo { - /// Converts a numeric value to an `Option<SymmetricAlgo>`. - /// - /// Returns None, if the value is out of range. - /// - /// # Examples - /// - /// ```rust - /// use openpgp::SymmetricAlgo; - /// - /// assert_eq!(SymmetricAlgo::from_numeric(9).unwrap(), - /// SymmetricAlgo::AES256); - /// ``` - pub fn from_numeric(value: u8) -> Result<Self> { - if let Some(algo) = num::FromPrimitive::from_u8(value) { - Ok(algo) - } else { - Err(Error::UnknownSymmetricAlgorithm(value).into()) - } - } - - /// Converts a `SymmetricAlgo` to its corresponding numeric value. - pub fn to_numeric(self) -> u8 { - num::ToPrimitive::to_u8(&self).unwrap() - } -} - #[derive(PartialEq, Clone, Debug)] pub struct S2K { - hash_algo: u8, + hash_algo: HashAlgo, salt: Option<[u8; 8]>, coded_count: Option<u8>, } @@ -448,7 +352,7 @@ pub struct Signature { pub version: u8, pub sigtype: u8, pub pk_algo: u8, - pub hash_algo: u8, + pub hash_algo: HashAlgo, pub hashed_area: parse::subpacket::SubpacketArea, pub unhashed_area: parse::subpacket::SubpacketArea, pub hash_prefix: [u8; 2], @@ -469,7 +373,7 @@ pub struct OnePassSig { pub common: packet::Common, pub version: u8, pub sigtype: u8, - pub hash_algo: u8, + pub hash_algo: HashAlgo, pub pk_algo: u8, pub issuer: [u8; 8], pub last: u8, @@ -567,7 +471,7 @@ pub struct CompressedData { pub struct SKESK { pub common: packet::Common, pub version: u8, - pub symm_algo: u8, + pub symm_algo: SymmetricAlgo, pub s2k: S2K, // The encrypted session key. pub esk: Vec<u8>, diff --git a/openpgp/src/one_pass_sig.rs b/openpgp/src/one_pass_sig.rs index cd6025d3..21b996ee 100644 --- a/openpgp/src/one_pass_sig.rs +++ b/openpgp/src/one_pass_sig.rs @@ -3,6 +3,7 @@ use std::fmt; use OnePassSig; use Packet; use KeyID; +use HashAlgo; impl fmt::Debug for OnePassSig { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -33,7 +34,7 @@ impl OnePassSig { common: Default::default(), version: 3, sigtype: sigtype, - hash_algo: 0, + hash_algo: HashAlgo::Unknown(0), pk_algo: 0, issuer: [0u8; 8], last: 1, @@ -53,7 +54,7 @@ impl OnePassSig { } /// Sets the hash algorithm. - pub fn hash_algo(mut self, algo: u8) -> Self { + pub fn hash_algo(mut self, algo: HashAlgo) -> Self { self.hash_algo = algo; self } diff --git a/openpgp/src/parse/hashed_reader.rs b/openpgp/src/parse/hashed_reader.rs index 2e6ae751..b7a63349 100644 --- a/openpgp/src/parse/hashed_reader.rs +++ b/openpgp/src/parse/hashed_reader.rs @@ -9,7 +9,6 @@ use buffered_reader::buffered_reader_generic_read_impl; use HashAlgo; use parse::{BufferedReaderState, HashesFor}; -use hash::hash_context; use super::indent; @@ -28,8 +27,8 @@ impl<R: BufferedReader<BufferedReaderState>> HashedReader<R> { pub fn new(reader: R, hashes_for: HashesFor, algos: Vec<HashAlgo>) -> Self { let mut cookie = BufferedReaderState::default(); - for algo in &algos { - cookie.hashes.push((*algo, hash_context(*algo))); + for &algo in &algos { + cookie.hashes.push((algo, algo.context().unwrap())); } cookie.hashes_for = hashes_for; diff --gi |