Add decrypt and detach-sign examples

This should mirror the usage of `gpg --decrypt` and `gpg --detach
--sign`.
This commit is contained in:
Wiktor Kwapisiewicz 2021-09-27 12:29:38 +02:00
parent 1ce74ab8c6
commit 1ec7fc97dc
No known key found for this signature in database
GPG key ID: E68BE3B312FA33FC
5 changed files with 169 additions and 0 deletions

View file

@ -4,6 +4,7 @@
[workspace]
members = [
"openpgp-card-apps",
"openpgp-card",
"openpgp-card-sequoia",
"pcsc",

View file

@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
# SPDX-License-Identifier: MIT OR Apache-2.0
[package]
name = "openpgp-card-apps"
description = "Examples and demos of apps utilizing openpgp-card-sequoia"
license = "MIT OR Apache-2.0"
version = "0.0.1"
authors = ["Wiktor Kwapisiewicz <wiktor@metacode.biz>"]
edition = "2018"
repository = "https://gitlab.com/hkos/openpgp-card"
documentation = "https://docs.rs/crate/openpgp-card-apps"
[dependencies]
sequoia-openpgp = "1.3"
nettle = "7"
openpgp-card = { path = "../openpgp-card", version = "0.0.4" }
openpgp-card-pcsc = { path = "../pcsc", version = "0.0.4" }
openpgp-card-scdc = { path = "../scdc", version = "0.0.2" }
openpgp-card-sequoia = { path = "../openpgp-card-sequoia", version = "0.0.3" }
chrono = "0.4"
anyhow = "1"
thiserror = "1"
env_logger = "0.8"
log = "0.4"

View file

@ -0,0 +1,43 @@
<!--
SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
SPDX-License-Identifier: MIT OR Apache-2.0
-->
**OpenPGP card usage with Sequoia PGP: Example apps**
*Small GnuPG replacements*
This crate can be used to decrypt OpenPGP data and to sign data
producing OpenPGP data.
First export the certificate that holds keys stored on the card:
```
$ gpg --export --armor $KEYID > cert.asc
```
Then create a test data, encrypted with GnuPG (as an example):
```
$ echo example data | gpg -ear $KEYID > encrypted.asc
```
And put the card PIN in a file called `pin`.
And then use the crate for decryption:
```
$ cargo run --example decrypt $CARD_ID pin cert.asc < encrypted.asc
```
The `$CARD_ID` holds card ident that can be printed using `cargo
run`. It's a string that looks like `0006:12345678`. Remember that if
the GnuPG agent is holding an exclusive access to the card it will not
show up. Unplugging and plugging the card again will relinquish
GnuPG's agent's hold on the card.
Signing works the same way:
```
$ echo data to be signed | cargo run --example detach-sign $CARD_ID pin cert.asc > signature.asc
```

View file

@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
// SPDX-License-Identifier: MIT OR Apache-2.0
use openpgp_card_pcsc::PcscClient;
use openpgp_card_sequoia::card::Open;
use openpgp::parse::{stream::DecryptorBuilder, Parse};
use openpgp::policy::StandardPolicy;
use openpgp::Cert;
use sequoia_openpgp as openpgp;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = std::env::args().collect::<Vec<_>>();
if args.len() < 3 {
eprintln!("Usage: decrypt card-ident pin-file cert-file");
return Ok(());
}
let card_ident = &args[0];
let pin_file = &args[1];
let cert_file = &args[2];
let mut open = Open::open_card(PcscClient::open_by_ident(&card_ident)?)?;
let pin = std::fs::read_to_string(pin_file)?;
open.verify_user(&pin)?;
let mut user = open.user_card().unwrap();
let p = StandardPolicy::new();
let cert = Cert::from_file(cert_file)?;
let d = user.decryptor(&cert, &p)?;
let stdin = std::io::stdin();
let mut stdout = std::io::stdout();
let db = DecryptorBuilder::from_reader(stdin)?;
let mut decryptor = db.with_policy(&p, None, d)?;
std::io::copy(&mut decryptor, &mut stdout)?;
Ok(())
}

View file

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: 2021 Wiktor Kwapisiewicz <wiktor@metacode.biz>
// SPDX-License-Identifier: MIT OR Apache-2.0
use openpgp_card_pcsc::PcscClient;
use openpgp_card_sequoia::card::Open;
use openpgp::parse::Parse;
use openpgp::policy::StandardPolicy;
use openpgp::serialize::stream::{Armorer, Message, Signer};
use openpgp::Cert;
use sequoia_openpgp as openpgp;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = std::env::args().collect::<Vec<_>>();
if args.len() < 3 {
eprintln!("Usage: detach-sign card-ident pin-file cert-file");
return Ok(());
}
let test_card_ident = &args[0];
let pin_file = &args[1];
let cert_file = &args[2];
let mut open =
Open::open_card(PcscClient::open_by_ident(&test_card_ident)?)?;
let pin = std::fs::read_to_string(pin_file)?;
open.verify_user_for_signing(&pin)?;
let mut user = open.signing_card().unwrap();
let p = StandardPolicy::new();
let cert = Cert::from_file(cert_file)?;
let s = user.signer(&cert, &p)?;
let stdout = std::io::stdout();
let message = Message::new(stdout);
let message = Armorer::new(message).build()?;
let signer = Signer::new(message, s);
let mut signer = signer.detached().build()?;
std::io::copy(&mut std::io::stdin(), &mut signer)?;
signer.finalize()?;
Ok(())
}