Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

provenance/src/pgp/not_built.rs

//! The OpenPGP verifier's place in a build WITHOUT this crate's `pgp` feature: the same
//! API, and every answer a refusal by name ([`super::not_built`]). No key is ever read,
//! so nothing can be pinned, and no `.asc` can pass.

use super::{not_built, VerifiedSignature};
use crate::error::{ProvenanceError, Result};

/// A pinned OpenPGP key. Without the `pgp` feature none can exist: [`PgpKey::from_armored`]
/// refuses every key, and the empty `never` field keeps any other way out.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PgpKey {
    pub name: String,
    /// The primary key's fingerprint, lower-case hex.
    pub fingerprint: String,
    never: std::convert::Infallible,
}

impl PgpKey {
    /// Refused by name ([`ProvenanceError::TrustRoot`], `[provenance-pgp-not-built]`): this
    /// build cannot check an OpenPGP key's bindings, so it pins none.
    pub fn from_armored(name: &str, bytes: &[u8]) -> Result<Self> {
        let _ = bytes;
        Err(ProvenanceError::TrustRoot(format!(
            "pgp key {name:?}: {}",
            not_built("an OpenPGP key")
        )))
    }
}

/// Unverified, by name ([`ProvenanceError::SignerUntrusted`]): this build cannot check a
/// detached OpenPGP signature, so an `.asc` never passes.
pub fn verify_detached(content: &[u8], asc: &[u8], keys: &[PgpKey]) -> Result<VerifiedSignature> {
    let _ = (content, asc);
    if let Some(k) = keys.first() {
        match k.never {}
    }
    Err(ProvenanceError::SignerUntrusted(format!(
        "unverified: {}",
        not_built("a detached OpenPGP signature (.asc)")
    )))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn every_key_is_refused_by_name() {
        let e =
            PgpKey::from_armored("povirk", b"-----BEGIN PGP PUBLIC KEY BLOCK-----\n").unwrap_err();
        assert_eq!(e.code_str(), "holger-provenance-10");
        let s = e.to_string();
        assert!(
            s.contains("\"povirk\"")
                && s.contains("[provenance-pgp-not-built]")
                && s.contains("`maven-pgp`"),
            "{s}"
        );
    }

    #[test]
    fn every_signature_is_unverified_by_name() {
        let e = verify_detached(b"pom", b"-----BEGIN PGP SIGNATURE-----\n", &[]).unwrap_err();
        assert_eq!(e.code_str(), "holger-provenance-4");
        assert!(
            e.to_string()
                .contains("unverified: [provenance-pgp-not-built]"),
            "{e}"
        );
    }
}