summaryrefslogtreecommitdiffstats
path: root/openpgp/fuzz/fuzz_targets/decrypt_from_bytes.rs
blob: 517a936cca0f9dab2eb2a56b11d8de01f475b7a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#![no_main]

use libfuzzer_sys::{Corpus, fuzz_target};

use sequoia_openpgp as openpgp;
use openpgp::{
    Cert,
    Fingerprint,
    KeyHandle,
    Result,
    crypto::SessionKey,
    packet::prelude::*,
    parse::{Parse, stream::*},
    policy::StandardPolicy,
    types::*,
};

const P: &StandardPolicy = &StandardPolicy::new();
const CERT_BYTES: &[u8; 665] = b"
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEWlNvABYJKwYBBAHaRw8BAQdA+EC2pvebpEbzPA9YplVgVXzkIG5eK+7wEAez
lcBgLJq0MVRlc3R5IE1jVGVzdGZhY2UgKG15IG5ldyBrZXkpIDx0ZXN0eUBleGFt
cGxlLm9yZz6IkAQTFggAOBYhBDnRAKtn1b2MBAECBfs3UfFYfa7xBQJaU28AAhsD
BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPs3UfFYfa7xJHQBAO4/GABMWUcJ
5D/DZ9b+6YiFnysSjCT/gILJgxMgl7uoAPwJherI1pAAh49RnPHBR1IkWDtwzX65
CJG8sDyO2FhzDrg4BFpTbwASCisGAQQBl1UBBQEBB0B+A0GRHuBgdDX50T1nePjb
mKQ5PeqXJbWEtVrUtVJaPwMBCAeIeAQYFggAIBYhBDnRAKtn1b2MBAECBfs3UfFY
fa7xBQJaU28AAhsMAAoJEPs3UfFYfa7xzjIBANX2/FgDX3WkmvwpEHg/sn40zACM
W2hrBY5x0sZ8H7JlAP47mCfCuRVBqyaePuzKbxLJeLe2BpDdc0n2izMVj8t9Cg==
=bbbT
-----END PGP PUBLIC KEY BLOCK-----
";

lazy_static::lazy_static! {
    /// This is an example for using doc comment attributes
    static ref CERT: Cert = Cert::from_bytes(&CERT_BYTES[..]).unwrap();
    static ref FP: Fingerprint = CERT.fingerprint();
    static ref SK: SessionKey = vec![].into();
}


fuzz_target!(|data: &[u8]| -> Corpus {
    struct Helper {}
    impl VerificationHelper for Helper {
        fn get_certs(&mut self, _ids: &[KeyHandle])
                     -> openpgp::Result<Vec<Cert>> {
            Ok(vec![CERT.clone()])
        }

        fn check(&mut self, structure: MessageStructure)
                 -> openpgp::Result<()> {
            for (i, layer) in structure.into_iter().enumerate() {
                match layer {
                    MessageLayer::Encryption { .. } if i == 0 => (),
                    MessageLayer::Compression { .. } if i == 1 => (),
                    MessageLayer::SignatureGroup { ref results } => {
                        if ! results.iter().any(|r| r.is_ok()) {
                            return Err(anyhow::anyhow!(
                                "No valid signature"));
                        }
                    }
                    _ => return Err(anyhow::anyhow!(
                        "Unexpected message structure")),
                }
            }
            Ok(())
        }
    }
    impl DecryptionHelper for Helper {
        fn decrypt<D>(&mut self, _: &[PKESK], _: &[SKESK],
                      _sym_algo: Option<SymmetricAlgorithm>,
                      mut decrypt: D) -> Result<Option<openpgp::Fingerprint>>
        where D: FnMut(SymmetricAlgorithm, &SessionKey) -> bool
        {
            decrypt(SymmetricAlgorithm::AES128, &SK);
            Ok(Some(FP.clone()))
        }
    }

    let h = Helper {};
    if let Ok(mut v) = DecryptorBuilder::from_bytes(data)
        .and_then(|b| b.with_policy(P, None, h))
    {
        let _ = std::io::copy(&mut v, &mut std::io::sink());
        Corpus::Keep
    } else {
        Corpus::Keep
    }
});