Add decrypt and detach-sign examples
This should mirror the usage of `gpg --decrypt` and `gpg --detach --sign`.
This commit is contained in:
parent
1ce74ab8c6
commit
1ec7fc97dc
5 changed files with 169 additions and 0 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
[workspace]
|
||||
members = [
|
||||
"openpgp-card-apps",
|
||||
"openpgp-card",
|
||||
"openpgp-card-sequoia",
|
||||
"pcsc",
|
||||
|
|
25
openpgp-card-apps/Cargo.toml
Normal file
25
openpgp-card-apps/Cargo.toml
Normal 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"
|
43
openpgp-card-apps/README.md
Normal file
43
openpgp-card-apps/README.md
Normal 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
|
||||
```
|
46
openpgp-card-apps/src/bin/decrypt.rs
Normal file
46
openpgp-card-apps/src/bin/decrypt.rs
Normal 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(())
|
||||
}
|
54
openpgp-card-apps/src/bin/detach-sign.rs
Normal file
54
openpgp-card-apps/src/bin/detach-sign.rs
Normal 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(())
|
||||
}
|
Loading…
Reference in a new issue