From 2dd007f1169c044dae189be8f788f4128501b8cd Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Fri, 31 Jul 2020 13:42:25 +0200 Subject: openpgp: Improve documentation of crypto::hash. - See #474. --- openpgp/src/crypto/hash.rs | 47 ++++++++++++++++++++++++++++++------- openpgp/src/crypto/mpi.rs | 5 ---- openpgp/src/packet/signature/mod.rs | 5 ++++ 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/openpgp/src/crypto/hash.rs b/openpgp/src/crypto/hash.rs index 4d6e1d96..a74b4c28 100644 --- a/openpgp/src/crypto/hash.rs +++ b/openpgp/src/crypto/hash.rs @@ -1,4 +1,12 @@ -//! Functionality to hash packets, and generate hashes. +//! Cryptographic hash functions and hashing of OpenPGP data +//! structures. +//! +//! This module provides [`Context`] representing a hash function +//! context independent of the cryptographic backend, as well as trait +//! [`Hash`] that handles hashing of OpenPGP data structures. +//! +//! [`Context`]: struct.Context.html +//! [`Hash`]: trait.Hash.html use std::convert::TryFrom; @@ -45,7 +53,11 @@ dyn_clone::clone_trait_object!(Digest); /// State of a hash function. /// /// This provides an abstract interface to the hash functions used in -/// OpenPGP. +/// OpenPGP. `Context`s are created using [`HashAlgorithm::context`]. +/// +/// [`HashAlgorithm::context`]: ../../types/enum.HashAlgorithm.html#method.context +/// +/// # Examples /// /// ```rust /// # f().unwrap(); fn f() -> sequoia_openpgp::Result<()> { @@ -94,8 +106,10 @@ impl Context { /// /// Resets the hash function contexts. /// - /// `digest` must be at least `self.digest_size()` bytes large, + /// `digest` must be at least [`self.digest_size()`] bytes large, /// otherwise the digest will be truncated. + /// + /// [`self.digest_size()`]: #method.digest_size pub fn digest>(&mut self, mut digest: D) { self.ctx.digest(digest.as_mut()); } @@ -198,13 +212,31 @@ impl Digest for HashDumper { } /// Hashes OpenPGP packets and related types. +/// +/// Some OpenPGP data structures need to be hashed to be covered by +/// OpenPGP signatures. Hashing is often based on the serialized +/// form, with some aspects fixed to ensure consistent results. This +/// trait implements hashing as specified by OpenPGP. +/// +/// Most of the time it is not necessary to manually compute hashes. +/// Instead, higher level functionality, like the streaming +/// [`Verifier`], [`DetachedVerifier`], or [`Signature`'s verification +/// functions] should be used, which handle the hashing internally. +/// +/// [`Verifier`]: ../../parse/stream/struct.Verifier.html +/// [`DetachedVerifier`]: ../../parse/stream/struct.DetachedVerifier.html +/// [`Signature`'s verification functions]: ../../packet/enum.Signature.html#verification-functions +/// +/// This is a low-level mechanism. See [`Signature`'s hashing +/// functions] for how to hash compounds like (Key,UserID)-bindings. +/// +/// [`Signature`'s hashing functions]: ../../packet/enum.Signature.html#hashing-functions pub trait Hash { /// Updates the given hash with this object. fn hash(&self, hash: &mut Context); } impl Hash for UserID { - /// Update the Hash with a hash of the user id. fn hash(&self, hash: &mut Context) { let len = self.value().len() as u32; @@ -218,7 +250,6 @@ 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 len = self.value().len() as u32; @@ -235,7 +266,6 @@ impl Hash for Key4 where P: key::KeyParts, R: key::KeyRole, { - /// Update the Hash with a hash of the key. fn hash(&self, hash: &mut Context) { use crate::serialize::MarshalInto; @@ -272,7 +302,6 @@ impl Hash for Key4 } impl Hash for Signature { - /// Adds the `Signature` to the provided hash context. fn hash(&self, hash: &mut Context) { match self { Signature::V4(sig) => sig.hash(hash), @@ -282,14 +311,12 @@ impl Hash for Signature { } impl Hash for Signature4 { - /// Adds the `Signature` to the provided hash context. fn hash(&self, hash: &mut Context) { self.fields.hash(hash); } } impl Hash for signature::SignatureFields { - /// Adds the `Signature` to the provided hash context. fn hash(&self, hash: &mut Context) { use crate::serialize::MarshalInto; @@ -348,6 +375,8 @@ impl Hash for signature::SignatureFields { } /// Hashing-related functionality. +/// +/// impl Signature { /// Computes the message digest of standalone signatures. pub fn hash_standalone(sig: &signature::SignatureFields) diff --git a/openpgp/src/crypto/mpi.rs b/openpgp/src/crypto/mpi.rs index 25150a7e..b2610810 100644 --- a/openpgp/src/crypto/mpi.rs +++ b/openpgp/src/crypto/mpi.rs @@ -179,7 +179,6 @@ impl fmt::Debug for MPI { } impl Hash for MPI { - /// Update the Hash with a hash of the MPIs. fn hash(&self, hash: &mut hash::Context) { let len = self.bits() as u16; @@ -408,7 +407,6 @@ impl PublicKey { } impl Hash for PublicKey { - /// Update the Hash with a hash of the MPIs. fn hash(&self, hash: &mut hash::Context) { self.serialize(hash).expect("hashing does not fail") } @@ -678,7 +676,6 @@ impl SecretKeyMaterial { } impl Hash for SecretKeyMaterial { - /// Update the Hash with a hash of the MPIs. fn hash(&self, hash: &mut hash::Context) { self.serialize(hash).expect("hashing does not fail") } @@ -781,7 +778,6 @@ impl Ciphertext { } impl Hash for Ciphertext { - /// Update the Hash with a hash of the MPIs. fn hash(&self, hash: &mut hash::Context) { self.serialize(hash).expect("hashing does not fail") } @@ -867,7 +863,6 @@ pub enum Signature { } impl Hash for Signature { - /// Update the Hash with a hash of the MPIs. fn hash(&self, hash: &mut hash::Context) { self.serialize(hash).expect("hashing does not fail") } diff --git a/openpgp/src/packet/signature/mod.rs b/openpgp/src/packet/signature/mod.rs index 7c95e9f8..e91f0bef 100644 --- a/openpgp/src/packet/signature/mod.rs +++ b/openpgp/src/packet/signature/mod.rs @@ -805,7 +805,12 @@ impl crate::packet::Signature { } sig } +} +/// Verification-related functionality. +/// +/// +impl Signature { /// Verifies the signature against `hash`. /// /// Note: Due to limited context, this only verifies the -- cgit v1.2.3