use anyhow::Context as _;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::{self, Write};
use std::time::SystemTime;
use sequoia_net::pks;
use sequoia_openpgp as openpgp;
use openpgp::{
armor,
};
use openpgp::types::{
CompressionAlgorithm,
};
use openpgp::cert::prelude::*;
use openpgp::crypto;
use openpgp::{Cert, KeyID, Result};
use openpgp::packet::prelude::*;
use openpgp::parse::{
Parse,
PacketParserResult,
};
use openpgp::parse::stream::*;
use openpgp::serialize::stream::{
Message, Signer, LiteralWriter, Encryptor, Recipient,
Compressor,
padding::Padder,
};
use openpgp::policy::Policy;
use openpgp::types::KeyFlags;
use openpgp::types::RevocationStatus;
use crate::{
Config,
};
use crate::sq_cli::encrypt::CompressionMode;
use crate::sq_cli::encrypt::EncryptionMode;
use crate::sq_cli::packet;
#[cfg(feature = "autocrypt")]
pub mod autocrypt;
pub mod decrypt;
pub use self::decrypt::decrypt;
pub mod sign;
pub use self::sign::sign;
pub mod revoke;
pub mod dump;
pub use self::dump::dump;
mod inspect;
pub use self::inspect::inspect;
pub mod key;
pub mod merge_signatures;
pub use self::merge_signatures::merge_signatures;
pub mod keyring;
pub mod net;
pub mod certify;
pub mod keystore;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GetKeysOptions {
AllowNotAlive,
AllowRevoked,
}
enum KeyType {
Primary,
KeyFlags(KeyFlags),
}
/// Returns suitable signing keys from a given list of Certs.
fn get_keys<C>(certs: &[C], p: &dyn Policy,
private_key_store: Option<&str>,
timestamp: Option<SystemTime>,
keytype: KeyType,
options: Option<&[GetKeysOptions]>)
-> Result<Vec<Box<dyn crypto::Signer + Send + Sync>>>
where C: Borrow<Cert>
{
let mut bad = Vec::new();
let options = options.unwrap_or(&[][..]);
let allow_not_alive = options.contains(&GetKeysOptions::AllowNotAlive);
let allow_revoked = options.contains(&GetKeysOptions::AllowRevoked);
let mut keys: Vec<Box<dyn crypto::Signer + Send + Sync>> = Vec::new();
'next_cert: for tsk in certs {
let tsk = tsk.borrow();
let vc = match tsk.with_policy(p, timestamp) {
Ok(vc) => vc,
Err(err) => {
return Err(
err.context(format!("Found no suitable key on {}", tsk)));
}
};
let keyiter = match keytype {
KeyType::Primary => {
Box::new(
std::iter::once(
vc.keys()
.next()
.expect("a valid cert has a primary key")))
as Box<dyn Iterator<Item=ValidErasedKeyAmalgamation<openpgp::packet::key::PublicParts>>>
},
KeyType::KeyFlags(ref flags) => {
Box::new(vc.keys().key_flags(flags.clone()))
as Box<dyn Iterator<Item=_>>
},
};
for ka in keyiter {
let