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
91
92
93
94
95
96
97
98
99
100
101
extern crate base64;
extern crate byteorder;
extern crate digest;

#[macro_use]
extern crate failure;
extern crate hex;
extern crate iowrap;
extern crate num;
extern crate sha1;
extern crate sha2;

mod armour;
mod digestable;
mod hash_multimap;
mod high;
mod keyring;
mod mpi;
mod packets;
mod rsa;

use failure::Error;

pub use armour::parse_clearsign_armour;
pub use high::verify_clearsign_armour;
pub use keyring::Keyring;
pub use packets::parse_packet;
pub use packets::Packet;

#[derive(Debug)]
pub enum PublicKeySig {
    Rsa(Vec<u8>),
    Dsa { r: Vec<u8>, s: Vec<u8> },
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub enum PubKey {
    Rsa {
        n: Vec<u8>,
        e: Vec<u8>,
    },
    Ecdsa {
        oid: Vec<u8>,
        point: Vec<u8>,
    },
    Ed25519 {
        oid: Vec<u8>,
        point: Vec<u8>,
    },
    Elgaml {
        p: Vec<u8>,
        g: Vec<u8>,
        y: Vec<u8>,
    },
    Dsa {
        p: Vec<u8>,
        q: Vec<u8>,
        g: Vec<u8>,
        y: Vec<u8>,
    },
}

#[derive(Debug)]
pub enum HashAlg {
    Sha1,
    Sha224,
    Sha256,
    Sha384,
    Sha512,

    Md5,
    RipeMd,
}

pub fn verify(key: &PubKey, sig: &PublicKeySig, padded_hash: &[u8]) -> Result<(), Error> {
    match *key {
        PubKey::Rsa { ref n, ref e } => match *sig {
            PublicKeySig::Rsa(ref sig) => rsa::verify(sig, (n, e), padded_hash),
            _ => bail!("key/signature type mismatch"),
        },
        PubKey::Ecdsa { .. } => bail!("not implemented: verify ecdsa signatures"),
        PubKey::Ed25519 { .. } => bail!("not implemented: verify ed25519 signatures"),
        PubKey::Dsa { .. } => bail!("not implemented: verify dsa signatures"),
        PubKey::Elgaml { .. } => bail!("elgaml may not have signatures"),
    }
}

/// <https://github.com/rust-lang/rust/issues/44290>
fn usize_from(val: u16) -> usize {
    val as usize
}

fn usize_from_u32(val: u32) -> usize {
    assert!(u64::from(val) <= (std::usize::MAX as u64));
    val as usize
}

fn to_u32(val: usize) -> u32 {
    assert!((val as u64) <= u64::from(std::u32::MAX));
    val as u32
}