use anyhow::Context as _;
use clap::ArgMatches;
use itertools::Itertools;
use std::time::{SystemTime, Duration};
use crate::openpgp::KeyHandle;
use crate::openpgp::Packet;
use crate::openpgp::Result;
use crate::openpgp::armor::{Writer, Kind};
use crate::openpgp::cert::prelude::*;
use crate::openpgp::packet::prelude::*;
use crate::openpgp::packet::signature::subpacket::SubpacketTag;
use crate::openpgp::parse::Parse;
use crate::openpgp::policy::Policy;
use crate::openpgp::serialize::Serialize;
use crate::openpgp::types::KeyFlags;
use crate::openpgp::types::SignatureType;
use crate::{
open_or_stdin,
};
use crate::Config;
use crate::SECONDS_IN_YEAR;
use crate::parse_duration;
use crate::decrypt_key;
pub fn dispatch(config: Config, m: &clap::ArgMatches) -> Result<()> {
match m.subcommand() {
("generate", Some(m)) => generate(config, m)?,
("extract-cert", Some(m)) => extract_cert(config, m)?,
("adopt", Some(m)) => adopt(config, m)?,
("attest-certifications", Some(m)) =>
attest_certifications(config, m)?,
_ => unreachable!(),
}
Ok(())
}
fn generate(config: Config, m: &ArgMatches) -> Result<()> {
let mut builder = CertBuilder::new();
// User ID
match m.values_of("userid") {
Some(uids) => for uid in uids {
builder = builder.add_userid(uid);
},
None => {
eprintln!("No user ID given, using direct key signature");
}
}
// Expiration.
match (m.value_of("expires"), m.value_of("expires-in")) {
(None, None) => // Default expiration.
builder = builder.set_validity_period(
Some(Duration::new(3 * SECONDS_IN_YEAR, 0))),
(Some(t), None) if t == "never" =>
builder = builder.set_validity_period(None),
(Some(t), None) => {
let now = builder.creation_time()
.unwrap_or_else(std::time::SystemTime::now);
let expiration = SystemTime::from(
crate::parse_iso8601(t, chrono::NaiveTime::from_hms(0, 0, 0))?);
let validity = expiration.duration_since(now)?;
builder = builder.set_creation_time(now)
.set_validity_period(validity);
},
(None, Some(d)) if d == "never" =>
builder = builder.set_validity_period(None),
(None, Some(d)) => {
let d = parse_duration(d)?;
builder = builder.set_validity_period(Some(d));
},
(Some(_), Some(_)) => unreachable!("conflicting args"),
}
// Cipher Suite
match m.value_of("cipher-suite") {
Some("rsa3k") => {
builder = builder.set_cipher_suite(CipherSuite::RSA3k);
}
Some("rsa4k") => {
builder = builder.set_cipher_suite(CipherSuite::RSA4k);
}
Some("cv25519") => {
builder = builder.set_cipher_suite(CipherSuite::Cv25519);
}
Some(ref cs) => {
return Err(anyhow::anyhow!("Unknown cipher suite '{}'", cs));
}
None => panic!("argument has a default value"),
}
// Signing Capability
match (m.is_present("can-sign"), m.is_present("cannot-sign")) {
(false, false) | (true, false) => {
builder = builder.add_signing_subkey();
}
(false, true) => { /* no signing subkey */ }
(true, true) => {