use pgp::{
crypto::{
aead::{AeadAlgorithm, ChunkSize},
hash::HashAlgorithm,
public_key::PublicKeyAlgorithm,
sym::SymmetricKeyAlgorithm,
},
types::{CompressionAlgorithm, EcdhPublicParams, PublicParams, Timestamp},
};
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Seipd {
SEIPD1,
SEIPD2,
}
pub const PREFERRED_SEIPD_MECHANISMS: &[Seipd] = &[Seipd::SEIPD2, Seipd::SEIPD1];
pub const AEAD_CHUNK_SIZE: ChunkSize = ChunkSize::C16KiB;
pub const PREFERRED_SYMMETRIC_KEY_ALGORITHMS: &[SymmetricKeyAlgorithm] = &[
SymmetricKeyAlgorithm::AES256,
SymmetricKeyAlgorithm::AES192,
SymmetricKeyAlgorithm::AES128,
];
pub const PREFERRED_AEAD_ALGORITHMS: &[(SymmetricKeyAlgorithm, AeadAlgorithm)] = &[
(SymmetricKeyAlgorithm::AES256, AeadAlgorithm::Ocb),
(SymmetricKeyAlgorithm::AES192, AeadAlgorithm::Ocb),
(SymmetricKeyAlgorithm::AES128, AeadAlgorithm::Ocb),
(SymmetricKeyAlgorithm::AES256, AeadAlgorithm::Eax),
(SymmetricKeyAlgorithm::AES192, AeadAlgorithm::Eax),
(SymmetricKeyAlgorithm::AES128, AeadAlgorithm::Eax),
];
pub const PREFERRED_HASH_ALGORITHMS: &[HashAlgorithm] = &[
HashAlgorithm::Sha512,
HashAlgorithm::Sha384,
HashAlgorithm::Sha256,
];
pub const PREFERRED_HASH_ALGORITHMS_V6: &[HashAlgorithm] = &[
HashAlgorithm::Sha512,
HashAlgorithm::Sha3_512,
HashAlgorithm::Sha384,
HashAlgorithm::Sha256,
HashAlgorithm::Sha3_256,
];
const ACCEPTABLE_HASH_ALGORITHMS_ECDH: &[HashAlgorithm] = &[
HashAlgorithm::Sha512,
HashAlgorithm::Sha384,
HashAlgorithm::Sha256,
];
pub const PREFERRED_COMPRESSION_ALGORITHMS: &[CompressionAlgorithm] = &[];
pub const MAX_RECURSION: usize = 10;
const MD5_REJECT_AFTER: u32 = 1262304000;
const SHA1_FOR_DATA_REJECT_AFTER: u32 = 1388534400;
const SHA1_REJECT_AFTER: u32 = 1675209600;
const RSA_UNDER_2K_REJECT_AFTER: u32 = 1388534400;
const RSA_UNDER_2K_CUTOFF_BIT_SIZE: usize = 2048;
const DSA_REJECT_AFTER: u32 = 1675382400;
pub(crate) fn acceptable_pk_algorithm(pp: &PublicParams, reference: Timestamp) -> bool {
if let PublicParams::RSA(rsa) = pp {
use rsa::traits::PublicKeyParts;
let rsa_bits = rsa.key.n().bits();
if rsa_bits < RSA_UNDER_2K_CUTOFF_BIT_SIZE
&& reference.as_secs() > RSA_UNDER_2K_REJECT_AFTER
{
return false;
}
}
if let PublicParams::DSA { .. } = pp {
if reference.as_secs() > DSA_REJECT_AFTER {
return false;
}
}
true
}
pub(crate) fn acceptable_hash_algorithm(
hash_algo: HashAlgorithm,
reference: Timestamp,
data_signature: bool,
) -> bool {
match hash_algo {
HashAlgorithm::Md5 => {
MD5_REJECT_AFTER > reference.as_secs()
}
HashAlgorithm::Sha1 => {
match data_signature {
true => SHA1_FOR_DATA_REJECT_AFTER > reference.as_secs(),
false => SHA1_REJECT_AFTER > reference.as_secs(),
}
}
HashAlgorithm::Ripemd160 => {
true
}
_ => true,
}
}
pub(crate) fn accept_for_encryption(pp: &PublicParams) -> bool {
match pp {
PublicParams::ECDH(
EcdhPublicParams::Curve25519 { hash, alg_sym, .. }
| EcdhPublicParams::P256 { hash, alg_sym, .. }
| EcdhPublicParams::P384 { hash, alg_sym, .. }
| EcdhPublicParams::P521 { hash, alg_sym, .. },
) => {
if !ACCEPTABLE_HASH_ALGORITHMS_ECDH.contains(hash) {
return false;
}
if !PREFERRED_SYMMETRIC_KEY_ALGORITHMS.contains(alg_sym) {
return false;
}
true
}
_ => true,
}
}
pub(crate) fn accept_for_signatures(pk_alg: PublicKeyAlgorithm, reference: Timestamp) -> bool {
if pk_alg == PublicKeyAlgorithm::DSA {
reference.as_secs() <= DSA_REJECT_AFTER
} else {
true
}
}