5 releases (3 breaking)

0.4.0 May 17, 2024
0.3.1 Apr 9, 2024
0.3.0 Mar 22, 2024
0.2.0 Mar 10, 2024
0.1.0 Mar 4, 2024

#2141 in Cryptography

Download history 364/week @ 2024-03-04 77/week @ 2024-03-11 403/week @ 2024-03-18 32/week @ 2024-03-25 155/week @ 2024-04-01 375/week @ 2024-04-08 288/week @ 2024-04-15 232/week @ 2024-04-22 78/week @ 2024-04-29 79/week @ 2024-05-06 332/week @ 2024-05-13 305/week @ 2024-05-20

840 downloads per month
Used in 3 crates (2 directly)

LGPL-2.0-or-later

195KB
4K SLoC

This crate includes functionality for interacting with GnuPG's gpg-agent.

gpg-agent is a secret key store, which is shipped as part of GnuPG. It is used to manage secret key material, and hardware devices that contain secret key material. It provides an RPC interface using the Assuan protocol.

This is how gpg, GnuPG's primary command-line interface, communicates with it.

This crate provides a Rust API for interacting with gpg-agent.

Note: this crate communicates directly with gpg-agent; it does not go via gpg.


lib.rs:

This crate includes functionality for interacting with GnuPG's gpg-agent.

gpg-agent is a secret key store, which is shipped as part of GnuPG. It is used to manage secret key material, and hardware devices that contain secret key material. It provides an RPC interface using the Assuan protocol.

This is how gpg, GnuPG's primary command-line interface, communicates with it.

This crate provides a Rust API for interacting with gpg-agent.

Note: this crate communicates directly with gpg-agent; it does not go via gpg.

Examples

Import secret key material, list the keys, and sign a message:

use std::io::{Read, Write};

use sequoia_openpgp as openpgp;
use openpgp::Cert;
use openpgp::packet::signature;
use openpgp::parse::Parse;
use openpgp::policy::StandardPolicy;
use openpgp::serialize::stream::{Message, Signer, LiteralWriter};
use openpgp::types::HashAlgorithm;
use openpgp::types::SignatureType;

use sequoia_gpg_agent as gpg_agent;
use gpg_agent::KeyPair;

const P: &StandardPolicy = &StandardPolicy::new();

#
// Load a TSK, i.e., a certificate with secret key material.
let key = // ...
#
let cert = Cert::from_bytes(key)?;
assert!(cert.is_tsk());

// Connect to a temporary GnuPG home directory.  Usually,
// you'll want to connect to the default home directory using
// Agent::connect_to_default.
let mut agent = gpg_agent::Agent::connect_to_ephemeral().await?;

// Import the secret key material into gpg-agent.
for k in cert.keys().secret() {
    agent.import(P,
                 &cert, k.parts_as_secret().expect("have secret"),
                 true, true).await?;
}

// List the keys.
let list = agent.list_keys().await?;
println!("gpg agent manages {} keys:", list.len());
for k in list.iter() {
    eprintln!("  - {}", k.keygrip());
}

// Sign a message using the signing key we just imported.
let signing_key = cert.with_policy(P, None)?
    .keys().for_signing()
    .next().expect("Have a signing-capable subkey.");

let mut keypair = agent.keypair(&signing_key)?;

let mut signed_message = Vec::new();
let message = Message::new(&mut signed_message);
let message = Signer::new(message, keypair).build()?;
let mut message = LiteralWriter::new(message).build()?;
message.write_all(b"I love you!")?;
message.finalize()?;

Dependencies

~23–37MB
~500K SLoC