First part of end-user guide.

This commit is contained in:
Heiko Schaefer 2022-04-21 18:02:22 +02:00
parent 9edd459d86
commit 9057ad516f
No known key found for this signature in database
GPG key ID: 4A849A1904CCBD7D
5 changed files with 325 additions and 0 deletions

View file

@ -3,6 +3,7 @@
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
stages: stages:
- pages
- lint - lint
- test - test
- virtual-test - virtual-test
@ -21,6 +22,21 @@ cache: &general_cache_config
- target/ - target/
- $CARGO_HOME - $CARGO_HOME
pages:
stage: pages
cache: [ ]
image: debian:stable-slim
before_script:
- apt update -y -qq
- apt install -y -qq --no-install-recommends wget ca-certificates
- wget https://github.com/rust-lang/mdBook/releases/download/v0.4.15/mdbook-v0.4.15-x86_64-unknown-linux-gnu.tar.gz
- tar xvzf mdbook-v0.4.15-x86_64-unknown-linux-gnu.tar.gz
script:
- ./mdbook build guide/
artifacts:
paths:
- public
reuse: reuse:
stage: lint stage: lint
cache: [ ] cache: [ ]
@ -29,6 +45,7 @@ reuse:
entrypoint: [ "" ] entrypoint: [ "" ]
script: script:
- reuse lint - reuse lint
dependencies: []
cargo-fmt: cargo-fmt:
stage: lint stage: lint

16
guide/book.toml Normal file
View file

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022 Heiko Schaefer <heiko@schaefer.name>
# SPDX-License-Identifier: MIT OR Apache-2.0
[book]
authors = ["hkos"]
language = "en"
multilingual = false
src = "src"
title = "OpenPGP card user guide"
[output.html]
git-repository-url = "https://gitlab.com/hkos/openpgp-card"
git-repository-icon = "fa-gitlab"
[build]
build-dir = "../public"

12
guide/src/SUMMARY.md Normal file
View file

@ -0,0 +1,12 @@
<!--
SPDX-FileCopyrightText: 2022 Heiko Schaefer <heiko@schaefer.name>
SPDX-License-Identifier: MIT OR Apache-2.0
-->
# Summary
- [Context](context.md)
- [Initializing cards with `opgpcard`](opgpcard.md)
- [SSH authentication](ssh.md)
- [git commit signing](git.md)
- [Thunderbird](thunderbird.md)

29
guide/src/context.md Normal file
View file

@ -0,0 +1,29 @@
<!--
SPDX-FileCopyrightText: 2022 Heiko Schaefer <heiko@schaefer.name>
SPDX-License-Identifier: MIT OR Apache-2.0
-->
# OpenPGP card "hardware tokens"
This series of articles describes how to use [OpenPGP card](https://en.wikipedia.org/wiki/OpenPGP_card) devices
(e.g. [YubiKey](https://www.yubico.com/products/), [Nitrokey](https://www.nitrokey.com/)
or [Gnuk](https://www.fsij.org/doc-gnuk/)) with new - and still experimental - Sequoia PGP-based tools.
OpenPGP cards are hardware tokens that can store private key material and perform cryptographic operations.
The point of using such a device is that private cryptographic key material is never directly accessible to the
user's computer.
This way, even if the user's computer is compromised, their private OpenPGP key material is protected from being
exfiltrated by an attacker.
## New tools
Until now, most users have interacted with OpenPGP cards using one or both of:
1. [GnuPG](https://www.gnupg.org) (which internally uses a subsystem called [scdaemon](https://www.gnupg.org/documentation/manuals/gnupg/Invoking-SCDAEMON.html)), or
2. [OpenKeychain](https://www.openkeychain.org/) (OpenKeychain can be used via the K9 email software), or the related [TermBot](https://github.com/cotechde/termbot) SSH client, on Android devices.
This project works towards a new set of tools, using a library-first approach, written in Rust.
These tools are based on a set of [OpenPGP card libraries](https://gitlab.com/hkos/openpgp-card) and [Sequoia PGP](https://sequoia-pgp.org/).

251
guide/src/opgpcard.md Normal file
View file

@ -0,0 +1,251 @@
<!--
SPDX-FileCopyrightText: 2022 Heiko Schaefer <heiko@schaefer.name>
SPDX-License-Identifier: MIT OR Apache-2.0
-->
# The opgpcard tool
To set up (or inspect) an OpenPGP card, we'll use the `opgpcard` tool.
So first, we install that tool.
In short:
1. install the build dependencies, then
2. `cargo install openpgp-card-tools`
Longer form [installation instructions](https://gitlab.com/hkos/openpgp-card/-/tree/main/tools#install).
# Exploring the state of an OpenPGP card
Using the `opgpcard` tool (installed above), you can easily check the status of a card that is plugged in:
`$ opgpcard status`
The output will start like this:
```
OpenPGP card FFFE:12345678 (card version 2.0)
[...]
```
In this case, the card identifier is `FFFE:12345678` (you'll need to use the identifier for your card, in some of the following steps).
# Specifying which card to operate on
For read operations, when exactly one card is plugged in, `opgpcard` will automatically use that card.
In all other cases (when multiple cards are plugged in, or for any write operations), you need to specify which card
you want to interact with, via the `-c` parameter.
For example:
`$ opgpcard status -c FFFE:12345678`
## Enumerating all available cards
You can use `opgpcard list` to enumerate all cards that are connected to the system.
# PINs
For some operations, OpenPGP cards require the user to provide a 'PIN', to show that the user is authorized to perform the operation.
Most OpenPGP cards distinguish two different PINs:
1. a *User PIN* and
2. an *Admin PIN*.
The User PIN is needed for cryptographic operations (such as decryption or signing with the card).
The Admin PIN is needed to configure the card itself (for example to import a key onto a card).
On new (or factory reset) cards, the default User PIN is typically `123456`, the default Admin PIN is `12345678`.
## Modes of PIN entry
`opgpcard` supports three different modes of PIN entry:
1. When the OpenPGP card is inserted in a Smartcard reader with a pinpad (that is, when the OpenPGP card is inserted into a hardware reader device that has a numerical keypad), PINs can be entered directly via that pinpad.
2. If no pinpad reader is available, PINs can be entered directly on the host computer.
3. Alternatively it's possible to supply PINs via a file (or a file descriptor), which can be convenient in non-interactive settings.
## Changing your User and Admin PIN from the default values
To change the User PIN from its default of `123456` to a value that third parties can't easily guess, run:
`$ opgpcard pin -c FFFE:12345678 set-user`
This command will ask you to enter the current User PIN (so `123456`, if your card is new), and then a new PIN,
twice (to avoid inadvertently setting the PIN to an unintended value).
And analogously for the Admin PIN, to change it from its default of `12345678`:
`$ opgpcard pin -c FFFE:12345678 set-admin`
Typically, the minimum length is 6 digits for the User PIN and 8 digits for the Admin PIN.
(Note that if you lose your Admin PIN, there is no way to recover it! In that case you can start over by blanking the
card with the `factory-reset` command. This resets the PINs to their defaults and removes all keys from the card.)
# Setting metadata on a card
## Set name
You can set a "Cardholder Name" on an OpenPGP card. That name field is informational.
`opgpcard admin -c FFFE:12345678 name "Alice Adams"`
## Set URL
You can set a URL on an OpenPGP card.
The URL "should contain a Link to a set of public keys in OpenPGP format, related to the card".
Some software may use this URL to obtain a copy of the corresponding public key for a card.
`$ opgpcard admin -c FFFE:12345678 url <url>`
If you do use the URL field, the URL should serve a copy of your public key.
For most use cases, you don't need to set the URL.
### Using `keys.openpgp.org` for the URL
If you have uploaded (or plan to upload) your certificate to the `keys.openpgp.org` keyserver, you can set the URL
field on your card to point to that server:
If the fingerprint of your certificate is `0123456789ABCDEF0123456789ABCDEF01234567`, then you can set the URL
as follows:
`$ opgpcard admin -c FFFE:12345678 url "https://keys.openpgp.org/vks/v1/by-fingerprint/0123456789ABCDEF0123456789ABCDEF01234567"`
### Other URLs
You can use any URL that serves your public key, including a link to your certificate on:
- gitlab (`https://gitlab.com/<username>.gpg`) or github (`https://github.com/<username>.gpg`)
- any other keyserver, such as https://keyserver.ubuntu.com/,
- a WKD server,
- a copy of your certificate on your personal website, ...
# Importing a key to a card
*(This operation will delete keys that currently exist on your card.
Make sure your card doesn't contain irreplaceable keys before you import keys!)*
If you have a key that you want to use, you can use that key.
If you don't (or if you want to first experiment with a test-key) you can generate a new key with the `sq` utility
(available as `sequoia-sq` in a number of distributions, or installable with the `cargo` Rust package manager).
```
$ sq key generate --export key.pgp
```
We can inspect this newly generated key (or your pre-existing key) by running:
```
$ sq inspect key.pgp
key.pgp: Transferable Secret Key.
Fingerprint: 17F2509AB619C8D78B598E54567817AC43A7F7AE
Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
Public-key size: 256 bits
Secret key: Unencrypted
Creation time: 2022-04-20 09:46:27 UTC
Expiration time: 2025-04-20 03:12:48 UTC (creation time + P1095DT62781S)
Key flags: certification
Subkey: E7A3D0E45991BE6445668CFD348634FD4CC638CA
Public-key algo: EdDSA Edwards-curve Digital Signature Algorithm
Public-key size: 256 bits
Secret key: Unencrypted
Creation time: 2022-04-20 09:46:27 UTC
Expiration time: 2025-04-20 03:12:48 UTC (creation time + P1095DT62781S)
Key flags: signing
Subkey: 593970CE20BFE3D58AA4EF12EA988C77EEC05B0A
Public-key algo: ECDH public key algorithm
Public-key size: 256 bits
Secret key: Unencrypted
Creation time: 2022-04-20 09:46:27 UTC
Expiration time: 2025-04-20 03:12:48 UTC (creation time + P1095DT62781S)
Key flags: transport encryption, data-at-rest encryption
```
In this case, we see (in the `Key flags` field) that the primary key `17F2509AB619C8D78B598E54567817AC43A7F7AE`
can be used for certification only.
In addition, there is a signing subkey `E7A3D0E45991BE6445668CFD348634FD4CC638CA`
and an encryption subkey `593970CE20BFE3D58AA4EF12EA988C77EEC05B0A`:
To explicitly import the two subkeys onto our card, we run:
```
$ opgpcard admin -c FFFE:12345678 import --sig-fp E7A3D0E45991BE6445668CFD348634FD4CC638CA --dec-fp 593970CE20BFE3D58AA4EF12EA988C77EEC05B0A key.pgp
Enter Admin PIN:
Uploading E7A3D0E45991BE6445668CFD348634FD4CC638CA as signing key
Uploading 593970CE20BFE3D58AA4EF12EA988C77EEC05B0A as decryption key
```
Checking the card's status now shows:
```
$ opgpcard status
OpenPGP card FFFE:12345678 (card version 2.0)
Signature key
fingerprint: E7A3 D0E4 5991 BE64 4566 8CFD 3486 34FD 4CC6 38CA
created: 2022-04-20 09:46:27
algorithm: Ed25519 (EdDSA)
Decryption key
fingerprint: 5939 70CE 20BF E3D5 8AA4 EF12 EA98 8C77 EEC0 5B0A
created: 2022-04-20 09:46:27
algorithm: Cv25519 (ECDH)
Authentication key
algorithm: RSA 2048 [e 32]
Signature counter: 0
Signature pin only valid once: true
Password validation retry count:
user pw: 3, reset: 3, admin pw: 3
```
The two subkeys have been loaded into the suitable slots on the card.
In fact, for this key, we don't need to explicitly specify the fingerprints. `opgpcard admin import` automatically
imports keys that contain exactly one signing (sub)key, and zero or one decryption and authentication subkeys, respectively:
```
opgpcard admin -c FFFE:12345678 import key.pgp
Enter Admin PIN:
Uploading E7A3D0E45991BE6445668CFD348634FD4CC638CA as signing key
Uploading 593970CE20BFE3D58AA4EF12EA988C77EEC05B0A as decryption key
```
# Key generation on a card
*(This operation will delete keys that currently exist on your card.
Make sure your card doesn't contain irreplaceable keys before you generate keys on your card!)*
This step will generate a new set of ECC Curve25519 keys on your OpenPGP card:
`opgpcard admin -c FFFE:12345678 generate -o output-cert.pub 25519`
The file `output-cert.pub` will contain the OpenPGP public key that corresponds to the newly generated keys on the card.
We won't need this public key for ssh use (but you might need it if you want to use the key on this card for other purposes).
## Pros and cons of generating keys on a card
When you generate keys on your card, your computer never has access to the private key material.
This is nice if you want to be sure that the private key material can not possibly get exfiltrated from your computer,
even if it is fully compromised.
On the other hand, this means that you can - by design - not make a backup (or second copy) of these private keys.
If the card is lost (or breaks) these keys are gone forever.
Depending on your use case, these tradeoffs may or may not be a good fit for your goals.