#openpgp-card #sequoia #decryption #wrapper #security #kdf

openpgp-card-sequoia

Wrapper of openpgp-card for use with Sequoia PGP

27 releases

0.2.2 Jun 5, 2024
0.2.1 Feb 16, 2024
0.2.0 Sep 5, 2023
0.1.2 Apr 8, 2023
0.0.1 Jun 30, 2021

#1840 in Cryptography

Download history 83/week @ 2024-04-01 8/week @ 2024-04-08 55/week @ 2024-04-15 107/week @ 2024-04-22 23/week @ 2024-04-29 14/week @ 2024-05-06 22/week @ 2024-05-13 67/week @ 2024-05-20 13/week @ 2024-05-27 182/week @ 2024-06-03 28/week @ 2024-06-10 50/week @ 2024-06-17 26/week @ 2024-06-24 76/week @ 2024-07-08 48/week @ 2024-07-15

153 downloads per month
Used in 4 crates (2 directly)

MIT/Apache and LGPL-2.0-or-later

400KB
8K SLoC

Crate deprecated

This crate is deprecated in favor of openpgp-card-rpgp.

openpgp-card-sequoia is based on the legacy openpgp-card 0.4 API. It is no longer under development.

The next generation openpgp-card version 0.5 includes bugfixes and new features (including additional KDF support), which I won't be backporting to this crate.

You are welcome to use openpgp-card-sequoia as is, but be aware that the library will see no further work and also no bugfix or security releases. If you have any questions about porting existing client code, feel free to reach out.


lib.rs:

This crate offers ergonomic abstractions to use OpenPGP card devices. The central abstraction is the [Card] type, which offers access to all card operations.

A [Card] object is always in one of the possible [State]s. The [State] determines which operations can be performed on the card.

This crate is a convenient higher-level wrapper around the openpgp-card crate (which exposes low level access to OpenPGP card functionality). sequoia-openpgp is used to perform OpenPGP operations.

Backends

To make use of this crate, you need to use a backend for communication with cards. The suggested default backend is card-backend-pcsc.

With card-backend-pcsc you can either open all available cards:

use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, Card};

for backend in PcscBackend::cards(None)? {
    let mut card = Card::<Open>::new(backend?)?;
    let mut transaction = card.transaction()?;
    println!(
        "Found OpenPGP card with ident '{}'",
        transaction.application_identifier()?.ident()
    );
}

Or you can open one particular card, by ident:

use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, Card};

let cards = PcscBackend::card_backends(None)?;
let mut card = Card::<Open>::open_by_ident(cards, "abcd:01234567")?;
let mut transaction = card.transaction()?;

Use for cryptographic operations

Decryption

To use a card for decryption, it needs to be opened, and user authorization needs to be available. A sequoia_openpgp::crypto::Decryptor implementation can then be obtained:

use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, Card};

// Open card via PCSC
let cards = PcscBackend::card_backends(None)?;
let mut card = Card::<Open>::open_by_ident(cards, "abcd:01234567")?;
let mut transaction = card.transaction()?;

// Get user access to the card (and authorize with the user pin)
let mut user = transaction.to_user_card("123456")?;

// Get decryptor
let decryptor = user.decryptor(&|| println!("Touch confirmation needed for decryption"));

// Perform decryption operation(s)
// ..

Signing

To use a card for signing, it needs to be opened, and signing authorization needs to be available. A sequoia_openpgp::crypto::Signer implementation can then be obtained.

(Note that by default, some OpenPGP Cards will only allow one signing operation to be performed after the password has been presented for signing. Depending on the card's configuration you need to present the user password before each signing operation!)

use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, Card};

// Open card via PCSC
let cards = PcscBackend::card_backends(None)?;
let mut card = Card::<Open>::open_by_ident(cards, "abcd:01234567")?;
let mut transaction = card.transaction()?;

// Get signing access to the card (and authorize with the user pin)
let mut user = transaction.to_signing_card("123456")?;

// Get signer
let signer = user.signer(&|| println!("Touch confirmation needed for signing"));

// Perform signing operation(s)
// ..

Setting up and configuring a card

use card_backend_pcsc::PcscBackend;
use openpgp_card_sequoia::{state::Open, Card};

// Open card via PCSC
let cards = PcscBackend::card_backends(None)?;
let mut card = Card::<Open>::open_by_ident(cards, "abcd:01234567")?;
let mut transaction = card.transaction()?;

// Get admin access to the card (and authorize with the admin pin)
let mut admin = transaction.to_admin_card("12345678")?;

// Set the Name and URL fields on the card
admin.set_cardholder_name("Alice Adams")?;
admin.set_url("https://example.org/openpgp.asc")?;

Dependencies

~16–24MB
~326K SLoC