use std::io::Write; use std::path::PathBuf; use sequoia_openpgp as openpgp; use sequoia_gpg_agent::Agent; use sequoia_gpg_agent::Context; #[tokio::main] async fn main() -> openpgp::Result<()> { let args = std::env::args().collect::>(); let (homedir, keygrip) = match args.len() { 2 if std::env::var("GNUPGHOME").is_ok() => { (PathBuf::from(std::env::var("GNUPGHOME").unwrap()), &args[1][..]) } 3 => { (PathBuf::from(&args[1]), &args[2][..]) } _ => { panic!("Usage: export-sexp [GNUPGHOME] KEYGRIP"); } }; let ctx = Context::with_homedir(homedir)?; let mut agent = Agent::connect(&ctx).await?; let kek = agent.send_simple("KEYWRAP_KEY --export").await?; let encrypted_key = agent.send_simple( format!("EXPORT_KEY {}", keygrip.to_string())).await?; let key = openpgp::crypto::ecdh::aes_key_unwrap( openpgp::types::SymmetricAlgorithm::AES128, &kek, &encrypted_key.as_ref())?; let mut key = key.as_ref(); // Strip any trailing NULs. They are only there for padding // purposes. while ! key.is_empty() && key[key.len() - 1] == 0 { key = &key[..key.len() - 1]; } std::io::stdout().write_all(key)?; Ok(()) }