zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
extern crate sequoia_openpgp as openpgp;

use std::io::{self, Write};

use openpgp::parse::{stream::*, Parse};
use openpgp::policy::StandardPolicy as P;

/// Verifies the given message.
pub fn verify(
    plaintext: &mut dyn Write,
    signed_message: &[u8],
    sender: &openpgp::Cert,
) -> openpgp::Result<()> {
    let policy = &P::new();

    // Make a helper that that feeds the sender's public key to the
    // verifier.
    let helper = Helper { cert: sender };

    // Now, create a verifier with a helper using the given Certs.
    let mut verifier =
        VerifierBuilder::from_bytes(signed_message)?.with_policy(policy, None, helper)?;

    // Verify the data.
    io::copy(&mut verifier, plaintext)?;

    Ok(())
}

struct Helper<'a> {
    cert: &'a openpgp::Cert,
}

impl VerificationHelper for Helper<'_> {
    fn get_certs(&mut self, _ids: &[openpgp::KeyHandle]) -> openpgp::Result<Vec<openpgp::Cert>> {
        // Return public keys for signature verification here.
        Ok(vec![self.cert.clone()])
    }

    fn check(&mut self, structure: MessageStructure) -> openpgp::Result<()> {
        // In this function, we implement our signature verification
        // policy.

        let mut good = false;
        for (i, layer) in structure.into_iter().enumerate() {
            match (i, layer) {
                // First, we are interested in signatures over the
                // data, i.e. level 0 signatures.
                (0, MessageLayer::SignatureGroup { results }) => {
                    // Finally, given a VerificationResult, which only says
                    // whether the signature checks out mathematically, we apply
                    // our policy.
                    match results.into_iter().next() {
                        Some(Ok(_)) => good = true,
                        Some(Err(e)) => return Err(openpgp::Error::from(e).into()),
                        None => return Err(anyhow::anyhow!("No signature")),
                    }
                }
                _ => return Err(anyhow::anyhow!("Unexpected message structure")),
            }
        }

        if good {
            Ok(()) // Good signature.
        } else {
            Err(anyhow::anyhow!("Signature verification failed"))
        }
    }
}