summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r--openpgp/src/crypto/aead.rs29
-rw-r--r--openpgp/src/crypto/asymmetric.rs60
-rw-r--r--openpgp/src/crypto/ecdh.rs12
-rw-r--r--openpgp/src/crypto/hash.rs122
-rw-r--r--openpgp/src/crypto/keygrip.rs89
-rw-r--r--openpgp/src/crypto/mem.rs24
-rw-r--r--openpgp/src/crypto/mod.rs32
-rw-r--r--openpgp/src/crypto/mpi.rs (renamed from openpgp/src/crypto/mpis.rs)17
-rw-r--r--openpgp/src/crypto/s2k.rs5
-rw-r--r--openpgp/src/crypto/sexp.rs141
-rw-r--r--openpgp/src/crypto/symmetric.rs16
11 files changed, 303 insertions, 244 deletions
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs
index 03d5c995..61cfd7f7 100644
--- a/openpgp/src/crypto/aead.rs
+++ b/openpgp/src/crypto/aead.rs
@@ -1,4 +1,5 @@
use std::cmp;
+use std::convert::TryInto;
use std::fmt;
use std::io;
@@ -24,6 +25,14 @@ use crate::parse::Cookie;
/// malformed AEAD-encrypted messages.
const DANGER_DISABLE_AUTHENTICATION: bool = false;
+/// Converts a chunk size to a usize.
+pub(crate) fn chunk_size_usize(chunk_size: u64) -> Result<usize> {
+ chunk_size.try_into()
+ .map_err(|_| Error::InvalidOperation(
+ format!("AEAD chunk size exceeds size of \
+ virtual memory: {}", chunk_size)).into())
+}
+
impl AEADAlgorithm {
/// Returns the digest size of the AEAD algorithm.
pub fn digest_size(&self) -> Result<usize> {
@@ -54,8 +63,8 @@ impl AEADAlgorithm {
}
}
- /// Creates a nettle context.
- pub fn context(&self, sym_algo: SymmetricAlgorithm, key: &[u8], nonce: &[u8])
+ /// Creates a Nettle context.
+ pub(crate) fn context(&self, sym_algo: SymmetricAlgorithm, key: &[u8], nonce: &[u8])
-> Result<Box<dyn aead::Aead>> {
match self {
AEADAlgorithm::EAX => match sym_algo {
@@ -133,9 +142,9 @@ impl<'a> Decryptor<'a> {
-> Result<Self>
{
Ok(Decryptor {
- source: source,
- sym_algo: sym_algo,
- aead: aead,
+ source,
+ sym_algo,
+ aead,
key: key.clone(),
iv: Vec::from(iv).into_boxed_slice(),
ad: [
@@ -148,7 +157,7 @@ impl<'a> Decryptor<'a> {
0, 0, 0, 0, 0, 0, 0, 0,
],
digest_size: aead.digest_size()?,
- chunk_size: chunk_size,
+ chunk_size,
chunk_index: 0,
bytes_decrypted: 0,
buffer: Vec::with_capacity(chunk_size),
@@ -551,8 +560,8 @@ impl<W: io::Write> Encryptor<W> {
Ok(Encryptor {
inner: Some(sink),
- sym_algo: sym_algo,
- aead: aead,
+ sym_algo,
+ aead,
key: key.clone(),
iv: Vec::from(iv).into_boxed_slice(),
ad: [
@@ -565,11 +574,11 @@ impl<W: io::Write> Encryptor<W> {
0, 0, 0, 0, 0, 0, 0, 0,
],
digest_size: aead.digest_size()?,
- chunk_size: chunk_size,
+ chunk_size,
chunk_index: 0,
bytes_encrypted: 0,
buffer: Vec::with_capacity(chunk_size),
- scratch: scratch,
+ scratch,
})
}
diff --git a/openpgp/src/crypto/asymmetric.rs b/openpgp/src/crypto/asymmetric.rs
index b39100e2..534e4912 100644
--- a/openpgp/src/crypto/asymmetric.rs
+++ b/openpgp/src/crypto/asymmetric.rs
@@ -4,7 +4,7 @@ use nettle::{dsa, ecc, ecdsa, ed25519, rsa, random::Yarrow};
use crate::packet::{self, key, Key};
use crate::crypto::SessionKey;
-use crate::crypto::mpis::{self, MPI};
+use crate::crypto::mpi::{self, MPI};
use crate::types::{Curve, HashAlgorithm};
use crate::Error;
@@ -22,7 +22,7 @@ pub trait Signer {
/// Creates a signature over the `digest` produced by `hash_algo`.
fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8])
- -> Result<mpis::Signature>;
+ -> Result<mpi::Signature>;
}
impl Signer for Box<dyn Signer> {
@@ -31,7 +31,7 @@ impl Signer for Box<dyn Signer> {
}
fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8])
- -> Result<mpis::Signature> {
+ -> Result<mpi::Signature> {
self.as_mut().sign(hash_algo, digest)
}
}
@@ -47,7 +47,7 @@ pub trait Decryptor {
fn public(&self) -> &Key<key::PublicParts, key::UnspecifiedRole>;
/// Decrypts `ciphertext`, returning the plain session key.
- fn decrypt(&mut self, ciphertext: &mpis::Ciphertext,
+ fn decrypt(&mut self, ciphertext: &mpi::Ciphertext,
plaintext_len: Option<usize>)
-> Result<SessionKey>;
}
@@ -73,8 +73,8 @@ impl KeyPair {
-> Result<Self>
{
Ok(Self {
- public: public,
- secret: secret,
+ public,
+ secret,
})
}
@@ -95,10 +95,10 @@ impl Signer for KeyPair {
}
fn sign(&mut self, hash_algo: HashAlgorithm, digest: &[u8])
- -> Result<mpis::Signature>
+ -> Result<mpi::Signature>
{
use crate::PublicKeyAlgorithm::*;
- use crate::crypto::mpis::PublicKey;
+ use crate::crypto::mpi::PublicKey;
let mut rng = Yarrow::default();
@@ -108,10 +108,10 @@ impl Signer for KeyPair {
{
(RSASign,
&PublicKey::RSA { ref e, ref n },
- &mpis::SecretKeyMaterial::RSA { ref p, ref q, ref d, .. }) |
+ &mpi::SecretKeyMaterial::RSA { ref p, ref q, ref d, .. }) |
(RSAEncryptSign,
&PublicKey::RSA { ref e, ref n },
- &mpis::SecretKeyMaterial::RSA { ref p, ref q, ref d, .. }) => {
+ &mpi::SecretKeyMaterial::RSA { ref p, ref q, ref d, .. }) => {
let public = rsa::PublicKey::new(n.value(), e.value())?;
let secret = rsa::PrivateKey::new(d.value(), p.value(),
q.value(), Option::None)?;
@@ -129,20 +129,20 @@ impl Signer for KeyPair {
hash_algo.oid()?,
&mut rng, &mut sig)?;
- Ok(mpis::Signature::RSA {
+ Ok(mpi::Signature::RSA {
s: MPI::new(&sig),
})
},
(DSA,
&PublicKey::DSA { ref p, ref q, ref g, .. },
- &mpis::SecretKeyMaterial::DSA { ref x }) => {
+ &mpi::SecretKeyMaterial::DSA { ref x }) => {
let params = dsa::Params::new(p.value(), q.value(), g.value());
let secret = dsa::PrivateKey::new(x.value());
let sig = dsa::sign(&params, &secret, digest, &mut rng)?;
- Ok(mpis::Signature::DSA {
+ Ok(mpi::Signature::DSA {
r: MPI::new(&sig.r()),
s: MPI::new(&sig.s()),
})
@@ -150,7 +150,7 @@ impl Signer for KeyPair {
(EdDSA,
&PublicKey::EdDSA { ref curve, ref q },
- &mpis::SecretKeyMaterial::EdDSA { ref scalar }) => match curve {
+ &mpi::SecretKeyMaterial::EdDSA { ref scalar }) => match curve {
Curve::Ed25519 => {
let public = q.decode_point(&Curve::Ed25519)?.0;
@@ -173,7 +173,7 @@ impl Signer for KeyPair {
}
res?;
- Ok(mpis::Signature::EdDSA {
+ Ok(mpi::Signature::EdDSA {
r: MPI::new(&sig[..32]),
s: MPI::new(&sig[32..]),
})
@@ -184,7 +184,7 @@ impl Signer for KeyPair {
(ECDSA,
&PublicKey::ECDSA { ref curve, .. },
- &mpis::SecretKeyMaterial::ECDSA { ref scalar }) => {
+ &mpi::SecretKeyMaterial::ECDSA { ref scalar }) => {
let secret = match curve {
Curve::NistP256 =>
ecc::Scalar::new::<ecc::Secp256r1>(
@@ -203,7 +203,7 @@ impl Signer for KeyPair {
let sig = ecdsa::sign(&secret, digest, &mut rng);
- Ok(mpis::Signature::ECDSA {
+ Ok(mpi::Signature::ECDSA {
r: MPI::new(&sig.r()),
s: MPI::new(&sig.s()),
})
@@ -223,19 +223,19 @@ impl Decryptor for KeyPair {
}
/// Creates a signature over the `digest` produced by `hash_algo`.
- fn decrypt(&mut self, ciphertext: &mpis::Ciphertext,
+ fn decrypt(&mut self, ciphertext: &mpi::Ciphertext,
plaintext_len: Option<usize>)
-> Result<SessionKey>
{
use crate::PublicKeyAlgorithm::*;
- use crate::crypto::mpis::PublicKey;
+ use crate::crypto::mpi::PublicKey;
self.secret.map(
|secret| Ok(match (self.public.mpis(), secret, ciphertext)
{
(PublicKey::RSA{ ref e, ref n },
- mpis::SecretKeyMaterial::RSA{ ref p, ref q, ref d, .. },
- mpis::Ciphertext::RSA{ ref c }) => {
+ mpi::SecretKeyMaterial::RSA{ ref p, ref q, ref d, .. },
+ mpi::Ciphertext::RSA{ ref c }) => {
// Workaround for #440: Make sure c is of the same
// length as n.
// XXX: Remove once we depend on nettle > 7.0.0.
@@ -272,14 +272,14 @@ impl Decryptor for KeyPair {
}
(PublicKey::ElGamal{ .. },
- mpis::SecretKeyMaterial::ElGamal{ .. },
- mpis::Ciphertext::ElGamal{ .. }) =>
+ mpi::SecretKeyMaterial::ElGamal{ .. },
+ mpi::Ciphertext::ElGamal{ .. }) =>
return Err(
Error::UnsupportedPublicKeyAlgorithm(ElGamalEncrypt).into()),
(PublicKey::ECDH{ .. },
- mpis::SecretKeyMaterial::ECDH { .. },
- mpis::Ciphertext::ECDH { .. }) =>
+ mpi::SecretKeyMaterial::ECDH { .. },
+ mpi::Ciphertext::ECDH { .. }) =>
crate::crypto::ecdh::decrypt(&self.public, secret, ciphertext)?,
(public, secret, ciphertext) =>
@@ -300,7 +300,7 @@ impl From<KeyPair> for Key<key::SecretParts, key::UnspecifiedRole> {
impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
/// Encrypts the given data with this key.
- pub fn encrypt(&self, data: &SessionKey) -> Result<mpis::Ciphertext> {
+ pub fn encrypt(&self, data: &SessionKey) -> Result<mpi::Ciphertext> {
use crate::PublicKeyAlgorithm::*;
#[allow(deprecated)]
@@ -308,14 +308,14 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
RSAEncryptSign | RSAEncrypt => {
// Extract the public recipient.
match self.mpis() {
- mpis::PublicKey::RSA { e, n } => {
+ mpi::PublicKey::RSA { e, n } => {
// The ciphertext has the length of the modulus.
let mut esk = vec![0u8; n.value().len()];
let mut rng = Yarrow::default();
let pk = rsa::PublicKey::new(n.value(), e.value())?;
rsa::encrypt_pkcs1(&pk, &mut rng, data,
&mut esk)?;
- Ok(mpis::Ciphertext::RSA {
+ Ok(mpi::Ciphertext::RSA {
c: MPI::new(&esk),
})
},
@@ -327,7 +327,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
},
}
},
- ECDH => crate::crypto::ecdh::encrypt(self.mark_parts_public_ref(),
+ ECDH => crate::crypto::ecdh::encrypt(self.parts_as_public(),
data),
algo => Err(Error::UnsupportedPublicKeyAlgorithm(algo).into()),
}
@@ -337,7 +337,7 @@ impl<P: key::KeyParts, R: key::KeyRole> Key<P, R> {
pub fn verify(&self, sig: &packet::Signature, digest: &[u8]) -> Result<()>
{
use crate::PublicKeyAlgorithm::*;
- use crate::crypto::mpis::{PublicKey, Signature};
+ use crate::crypto::mpi::{PublicKey, Signature};
#[allow(deprecated)]
let ok = match (sig.pk_algo(), self.mpis(), sig.mpis()) {
diff --git a/openpgp/src/crypto/ecdh.rs b/openpgp/src/crypto/ecdh.rs
index b191d556..e95ecd58 100644
--- a/openpgp/src/crypto/ecdh.rs
+++ b/openpgp/src/crypto/ecdh.rs
@@ -19,7 +19,7 @@ use crate::utils::{
};
use crate::crypto::SessionKey;
use crate::crypto::mem::Protected;
-use crate::crypto::mpis::{MPI, PublicKey, SecretKeyMaterial, Ciphertext};
+use crate::crypto::mpi::{MPI, PublicKey, SecretKeyMaterial, Ciphertext};
use nettle::{cipher, curve25519, mode, mode::Mode, ecc, ecdh, random::Yarrow};
/// Wraps a session key using Elliptic Curve Diffie-Hellman.
@@ -343,7 +343,7 @@ fn make_param<P, R>(recipient: &Key<P, R>,
+ 1 // Public key algorithm ID,
+ 4 // KDF parameters,
+ 20 // "Anonymous Sender ",
- + fp.as_slice().len()); // Recipients key fingerprint.
+ + fp.as_bytes().len()); // Recipients key fingerprint.
param.push(curve.oid().len() as u8);
param.extend_from_slice(curve.oid());
@@ -353,13 +353,13 @@ fn make_param<P, R>(recipient: &Key<P, R>,
param.push((*hash).into());
param.push((*sym).into());
param.extend_from_slice(b"Anonymous Sender ");
- param.extend_from_slice(fp.as_slice());
+ param.extend_from_slice(fp.as_bytes());
assert_eq!(param.len(),
1 + curve.oid().len() // Length and Curve OID,
+ 1 // Public key algorithm ID,
+ 4 // KDF parameters,
+ 20 // "Anonymous Sender ",
- + fp.as_slice().len()); // Recipients key fingerprint.
+ + fp.as_bytes().len()); // Recipients key fingerprint.
param
}
@@ -581,9 +581,9 @@ pub fn aes_key_unwrap(algo: SymmetricAlgorithm, key: &Protected,
let mut iv: Protected = vec![0; cipher.block_size()].into();
// For j = 5 to 0
- for j in (0..6_usize).into_iter().map(|x| 5 - x) {
+ for j in (0..=5).rev() {
// For i = n to 1
- for i in (0..n).into_iter().map(|x| n - 1 - x) {
+ for i in (0..=n-1).rev() {
// B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
write_be_u64(&mut tmp[..8], a ^ ((n * j) + i + 1) as u64);
&mut tmp[8..].copy_from_slice(&r[8 * i..8 * (i + 1)]);
diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs
index 87d89b34..6fe9146c 100644
--- a/openpgp/src/crypto/hash.rs
+++ b/openpgp/src/crypto/hash.rs
@@ -22,6 +22,30 @@ use std::io::{self, Write};
const DUMP_HASHED_VALUES: Option<&str> = None;
/// State of a hash function.
+///
+/// This provides an abstract interface to the hash functions used in
+/// OpenPGP.
+///
+/// ```rust
+/// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> {
+/// use sequoia_openpgp::types::HashAlgorithm;
+///
+/// // Create a context and feed data to it.
+/// let mut ctx = HashAlgorithm::SHA512.context()?;
+/// ctx.update(&b"The quick brown fox jumps over the lazy dog."[..]);
+///
+/// // Extract the digest.
+/// let mut digest = vec![0; ctx.digest_size()];
+/// ctx.digest(&mut digest);
+///
+/// use sequoia_openpgp::fmt::hex;
+/// assert_eq!(&hex::encode(digest),
+/// "91EA1245F20D46AE9A037A989F54F1F7\
+/// 90F0A47607EEB8A14D12890CEA77A1BB\
+/// C6C7ED9CF205E67B7F2B8FD4C7DFD3A7\
+/// A8617E45F3C463D481C7E586C39AC1ED");
+/// # Ok(()) }
+/// ```
#[derive(Clone)]
pub struct Context {
algo: HashAlgorithm,
@@ -84,7 +108,7 @@ impl HashAlgorithm {
}
}
- /// Creates a new Nettle hash context for this algorithm.
+ /// Creates a new hash context for this algorithm.
///
/// # Errors
///
@@ -114,16 +138,14 @@ impl HashAlgorithm {
HashAlgorithm::__Nonexhaustive => unreachable!(),
};
- if let Some(prefix) = DUMP_HASHED_VALUES {
- c.map(|c: Box<dyn nettle::hash::Hash>| {
- Context {
- algo: self,
- ctx: Box::new(HashDumper::new(c, prefix)),
- }
- })
- } else {
- c.map(|c| Context { algo: self, ctx: c })
- }
+ c.map(|ctx| Context {
+ algo: self,
+ ctx: if let Some(prefix) = DUMP_HASHED_VALUES {
+ Box::new(HashDumper::new(ctx, prefix))
+ } else {
+ ctx
+ },
+ })
}
/// Returns the ASN.1 OID of this hash algorithm.
@@ -167,9 +189,9 @@ impl HashDumper {
};
eprintln!("HashDumper: Writing to {}...", &filename);
HashDumper {
- h: h,
- sink: sink,
- filename: filename,
+ h,
+ sink,
+ filename,
written: 0,
}
}
@@ -208,16 +230,13 @@ pub trait Hash {
impl Hash for UserID {
/// Update the Hash with a hash of the user id.
fn hash(&self, hash: &mut Context) {
- let mut header = [0; 5];
+ let len = self.value().len() as u32;
+ let mut header = [0; 5];
header[0] = 0xB4;
- let len = self.value().len() as u32;
- header[1] = (len >> 24) as u8;
- header[2] = (len >> 16) as u8;
- header[3] = (len >> 8) as u8;
- header[4] = (len) as u8;
+ header[1..5].copy_from_slice(&len.to_be_bytes());
- hash.update(&header[..]);
+ hash.update(header);
hash.update(self.value());
}
}
@@ -225,16 +244,13 @@ impl Hash for UserID {
impl Hash for UserAttribute {
/// Update the Hash with a hash of the user attribute.
fn hash(&self, hash: &mut Context) {
- let mut header = [0; 5];
+ let len = self.value().len() as u32;
+ let mut header = [0; 5];
header[0] = 0xD1;
- let len = self.value().len() as u32;
- header[1] = (len >> 24) as u8;
- header[2] = (len >> 16) as u8;
- header[3] = (len >> 8) as u8;
- header[4] = (len) as u8;
+ header[1..5].copy_from_slice(&len.to_be_bytes());
- hash.update(&header[..]);
+ hash.update(&header);
hash.update(self.value());
}
}
@@ -247,18 +263,17 @@ impl<P, R> Hash for Key4<P, R>
fn hash(&self, hash: &mut Context) {
use crate::serialize::MarshalInto;
- // We hash 8 bytes plus the MPIs. But, the len doesn't
+ // We hash 9 bytes plus the MPIs. But, the len doesn't
// include the tag (1 byte) or the length (2 bytes).
- let len = (9 - 3) + self.mpis().serialized_len();
+ let len = (9 - 3) + self.mpis().serialized_len() as u16;
- let mut header : Vec<u8> = Vec::with_capacity(9);
+ let mut header: Vec<u8> = Vec::with_capacity(9);
// Tag. Note: we use this whether
header.push(0x99);
- // Length (big endian).
- header.push(((len >> 8) & 0xFF) as u8);
- header.push((len & 0xFF) as u8);
+ // Length (2 bytes, big endian).
+ header.extend_from_slice(&len.to_be_bytes());
// Version.
header.push(4);
@@ -266,12 +281,9 @@ impl<P, R> Hash for Key4<P, R>
// Creation time.
let creation_time: u32 =
Timestamp::try_from(self.creation_time())
- .unwrap_or_else(|_| Timestamp::try_from(0).unwrap())
+ .unwrap_or_else(|_| Timestamp::from(0))
.into();
- header.push((creation_time >> 24) as u8);
- header.push((creation_time >> 16) as u8);
- header.push((creation_time >> 8) as u8);
- header.push((creation_time >> 0) as u8);
+ header.extend_from_slice(&creation_time.to_be_bytes());
// Algorithm.
header.push(self.pk_algo().into());
@@ -300,7 +312,7 @@ impl Hash for Signature4 {
}
}
-impl Hash for signature::Builder {
+impl Hash for signature::SignatureBuilder {
/// Adds the `Signature` to the provided hash context.
fn hash(&self, hash: &mut Context) {
use crate::serialize::MarshalInto;
@@ -328,10 +340,9 @@ impl Hash for signature::Builder {
header[2] = self.pk_algo().into();
header[3] = self.hash_algo().into();
- // The length of the hashed area, as a 16-bit endian number.
- let len = hashed_area.len();
- header[4] = (len >> 8) as u8;
- header[5] = len as u8;
+ // The length of the hashed area, as a 16-bit big endian number.
+ let len = hashed_area.len() as u16;
+ header[4..6].copy_from_slice(&len.to_be_bytes());
hash.update(&header[..]);
hash.update(&hashed_area);
@@ -349,15 +360,12 @@ impl Hash for signature::Builder {
// See https://tools.ietf.org/html/rfc4880#section-5.2.4
let mut trailer = [0u8; 6];
- trailer[0] = 0x4;
+ trailer[0] = 4;
trailer[1] = 0xff;
// The signature packet's length, not including the previous
// two bytes and the length.
- let len = header.len() + hashed_area.len();
- trailer[2] = (len >> 24) as u8;
- trailer[3] = (len >> 16) as u8;
- trailer[4] = (len >> 8) as u8;
- trailer[5] = len as u8;
+ let len = (header.len() + hashed_area.len()) as u32;
+ trailer[2..6].copy_from_slice(&len.to_be_bytes());
hash.update(&trailer[..]);
}
@@ -367,7 +375,7 @@ impl Hash for signature::Builder {
impl Signature {
/// Computes the message digest of standalone signatures.
pub fn hash_standalone<'a, S>(sig: S) -> Result<Vec<u8>>
- where S: Into<&'a signature::Builder>
+ where S: Into<&'a signature::SignatureBuilder>
{
let sig = sig.into();
let mut h = sig.hash_algo().context()?;
@@ -381,7 +389,7 @@ impl Signature {
/// Computes the message digest of timestamp signatures.
pub fn hash_timestamp<'a, S>(sig: S) -> Result<Vec<u8>>
- where S: Into<&'a signature::Builder>
+ where S: Into<&'a signature::SignatureBuilder>
{
Self::hash_standalone(sig)
}
@@ -391,7 +399,7 @@ impl Signature {
pub fn hash_direct_key<'a, P, S>(sig: S, key: &Key<P, key::PrimaryRole>)
-> Result<Vec<u8>>
where P: key::KeyParts,
- S: Into<&'a signature::Builder>,
+ S: Into<&'a signature::SignatureBuilder>,
{
let sig = sig.into();
@@ -414,7 +422,7 @@ impl Signature {
-> Result<Vec<u8>>
where P: key::KeyParts,
Q: key::KeyParts,
- S: Into<&'a signature::Builder>
+ S: Into<&'a signature::SignatureBuilder>
{
let sig = sig.into();
@@ -438,7 +446,7 @@ impl Signature {
-> Result<Vec<u8>>
where P: key::KeyParts,
Q: key::KeyParts,
- S: Into<&'a signature::Builder>
+ S: Into<&'a signature::SignatureBuilder>
{
Self::hash_subkey_binding(sig.into(), key, subkey)
}
@@ -450,7 +458,7 @@ impl Signature {
userid: &UserID)
-> Result<Vec<u8>>
where P: key::KeyParts,
- S: Into<&'a signature::Builder>
+ S: Into<&'a signature::SignatureBuilder>
{
let sig = sig.into();
let mut h = sig.hash_algo().context()?;
@@ -472,7 +480,7 @@ impl Signature {
ua: &UserAttribute)
-> Result<Vec<u8>>
where P: key::KeyParts,
- S: Into<&'a signature::Builder>,
+ S: Into<&'a signature::SignatureBuilder>,
{
let sig = sig.into();
diff --git a/openpgp/src/crypto/keygrip.rs b/openpgp/src/crypto/keygrip.rs
index 32c58e84..68401e53 100644
--- a/openpgp/src/crypto/keygrip.rs
+++ b/openpgp/src/crypto/keygrip.rs
@@ -3,7 +3,7 @@ use std::fmt;
use crate::Error;
use crate::Result;
use crate::types::{Curve, HashAlgorithm};
-use crate::crypto::mpis::{MPI, PublicKey};
+use crate::crypto::mpi::{MPI, PublicKey};
/// A proprietary, protocol agnostic identifier for public keys.
///
@@ -33,22 +33,15 @@ impl std::str::FromStr for Keygrip {
type Err = anyhow::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- Self::from_hex(s)
- }
-}
-
-impl Keygrip {
- /// Parses a keygrip.
- pub fn from_hex(hex: &str) -> Result<Self> {
- let bytes = crate::fmt::from_hex(hex, true)?;
- if bytes.len() != 20 {
- return Err(Error::InvalidArgument(
- format!("Expected 20 bytes, got {}", bytes.len())).into());
+ let bytes = crate::fmt::hex::decode_pretty(s)?;
+ if bytes.len() == 20 {
+ let mut digest = [0; 20];
+ &mut digest[..].copy_from_slice(&bytes[..]);
+ Ok(Keygrip(digest))
+ } else {
+ Err(Error::InvalidArgument(
+ format!("Expected 20 bytes, got {}", bytes.len())).into())
}
-
- let mut digest = [0; 20];
- &mut digest[..].copy_from_slice(&bytes[..]);
- Ok(Keygrip(digest))
}
}
@@ -301,46 +294,46 @@ mod tests {
let keygrips: HashMap<FP, KG> = [
// testy.pgp
- (FP::from_hex("3E8877C877274692975189F5D03F6F865226FE8B").unwrap(),
- KG::from_hex("71ADDE3BBC0B7F1BFC2DA414C4F473B197763733").unwrap()),
- (FP::from_hex("01F187575BD45644046564C149E2118166C92632").unwrap(),
- KG::from_hex("CB6149C50DF90DC88626283A6B6C918A1C29E37D").unwrap()),
+ ("3E8877C877274692975189F5D03F6F865226FE8B".parse::<FP>().unwrap(),
+ "71ADDE3BBC0B7F1BFC2DA414C4F473B197763733".parse::<KG>().unwrap()),
+ ("01F187575BD45644046564C149E2118166C92632".parse::<FP>().unwrap(),
+ "CB6149C50DF90DC88626283A6B6C918A1C29E37D".parse::<KG>().unwrap()),
// neal.pgp
- (FP::from_hex("8F17777118A33DDA9BA48E62AACB3243630052D9").unwrap(),
- KG::from_hex("C45986381F54F967C2F6B104521C8634090F326A").unwrap()),
- (FP::from_hex("C03FA6411B03AE12576461187223B56678E02528").unwrap(),
- KG::from_hex("BE2FE8C8793141322AC30E3EAFD1E4F9D8DACCC4").unwrap()),
- (FP::from_hex("50E6D924308DBF223CFB510AC2B819056C652598").unwrap(),
- KG::from_hex("9873FD355DE470DDC151CD9919AC9785C3C2FDDE").unwrap()),
- (FP::from_hex("2DC50AB55BE2F3B04C2D2CF8A3506AFB820ABD08").unwrap(),
- KG::from_hex("9483454871CC1239D4C2A1416F2742D39A14DB14").unwrap()),
+ ("8F17777118A33DDA9BA48E62AACB3243630052D9".parse::<FP>().unwrap(),
+ "C45986381F54F967C2F6B104521C8634090F326A".parse::<KG>().unwrap()),
+ ("C03FA6411B03AE12576461187223B56678E02528".parse::<FP>().unwrap(),
+ "BE2FE8C8793141322AC30E3EAFD1E4F9D8DACCC4".parse::<KG>().unwrap()),
+ ("50E6D924308DBF223CFB510AC2B819056C652598".parse::<FP>().unwrap(),
+ "9873FD355DE470DDC151CD9919AC9785C3C2FDDE".parse::<KG>().unwrap()),
+ ("2DC50AB55BE2F3B04C2D2CF8A3506AFB820ABD08".parse::<FP>().unwrap(),
+ "9483454871CC1239D4C2A1416F2742D39A14DB14".parse::<KG>().unwrap()),
// dennis-simon-anton.pgp
- (FP::from_hex("5BFBCD2A23E6866B77198C1147606B18E3D45CE9").unwrap(),
- KG::from_hex("D3E87BECEF18FB4C56