7 releases
0.1.5 | Nov 18, 2024 |
---|---|
0.1.4 | Sep 23, 2024 |
0.1.3 | Jun 30, 2024 |
0.1.0 | May 6, 2024 |
0.0.2 | Apr 30, 2024 |
#385 in Cryptography
143 downloads per month
210KB
691 lines
OpenPGP card tool for Git signing and verification
This project provides the oct-git
"OpenPGP card tool for Git".
oct-git
generates (and verifies) OpenPGP signatures in the context of the Git distributed version control system. It serves as a replacement to the gpg
program, for use with Git.
Why
The oct-git
tool is a stand-alone, "no-moving-parts" solution, written in pure Rust, based on the rPGP OpenPGP library and Rust Crypto.
It aims for simplicity, requires no long-running processes[^pcsc], and doesn't keep a permanent connection to OpenPGP card hardware devices.
[^pcsc]: On Linux, the pcscd
system service is required, while on Windows and Mac, a PC/SC subsystem doesn't need to be installed (it is a part of the core system and available by default).
oct-git
works natively on Linux, Mac and Windows. It is a new standalone solution and doesn't require (or use) any part of GnuPG.
By contrast, other tools that deal with OpenPGP tend to be complex, have many moving parts (including multiple processes, some of them long-running).
Setup
oct-git
is designed specifically for use with the Git version control system, as a helper to perform OpenPGP signing and verification.
Users will typically not interact directly with oct-git
, after an initial one-time setup.
If you call oct-git
without parameters, you'll see a very brief setup help text.
Configuring Git to use oct-git
To use oct-git
, Git must be configured appropriately.
Most importantly, the binary that git
calls for OpenPGP functionality must be configured:
git config --global gpg.program <path to oct-git>
Additionally, the OpenPGP key that git
should use for signing must be configured.
This value can be set to the OpenPGP fingerprint of the signing component key, or the primary fingerprint of the key:
git config --global user.signingkey <fingerprint>
Once this basic setup is done, git
can be instructed to sign every commit by default:
git config --global commit.gpgsign true
And/or to sign every Git tag by default:
git config --global tag.gpgsign true
Switching Git's OpenPGP subsystem between oct-git and GnuPG
If you'd like to try oct-git
, but are undecided between using it or GnuPG, once you have set up Git's OpenPGP configuration, you can always easily switch between OpenPGP Git subsystems:
You can simply call:
git config --global gpg.program <path to GnuPG>
or
git config --global gpg.program <path to oct-git>
Switching between the two alternative OpenPGP subsystems should be quick and a mostly unexciting experience. We encourage unhesitant switching between the implementations if you want to compare them, or just play.
Architecture and subsystems
The oct-git
tool consists of one standalone binary, which is called by git
, both for the creation of signatures and for the verification of signatures.
Logically, oct-git
consists of a set of subsystems:
graph TB
Git --> OG["oct-git <br/> (commit/tag signing and verification)"]
OG --> CARD["OpenPGP card <br/> (produces signatures, accessed via PC/SC)"]
OG --> STATE["openpgp-card-state library <br/> (config and PIN storage backend access)"]
STATE --> PINS["PIN storage backend <br/> (makes User PINs available to applications)"]
OG --> NOTIFY["Desktop notifications <br/> (e.g.: touch confirmation required)"]
OG --> RCS["rpgpie-certificate-store"]
RCS --> CERTD["openpgp-cert-d <br/> (shared public key storage)"]
RCS --> PKI["OpenPGP PKI <br/> (retrieve certificates from keyservers etc)"]
Most of these subsystems consist of Rust libraries that are linked into the oct-git
program.
The following subsystems are not libraries:
- "OpenPGP card" is a physical hardware security device (often a USB device) that contains your private signing key material, to issue Git signatures with.
- An "openpgp-cert-d" instance consists of a set of files in a shared location in your local filesystem that contains OpenPGP certificates (public keys).
- "OpenPGP PKI" means public keyservers that serve OpenPGP certificates (public keys). This subsystem queries keyservers over the internet, to acquire copies of certificates.
User PINs: Configuring access to OpenPGP card devices
OpenPGP card devices require a User PIN to authorize private key operations (in the case of this tool: creating cryptographic signatures for git commits).
Access to OpenPGP card User PINs is handled indirectly, using the shared openpgp-card-state infrastructure.
If you have already stored the User PIN for your card in openpgp-card-state, it can be used from oct-git
immediately.
Otherwise, you can store the User PIN using oct-git
, like this:
$ oct-git --store-card-pin
Found OpenPGP card 0000:01234567
No User PIN is stored in openpgp-card-state
Enter User PIN to store (or <Enter> to skip):
User PIN has been stored in openpgp-card-state
The User PIN storage process in oct-git
is interactive. For each connected OpenPGP card device, it checks if a valid PIN is already available in openpgp-card-state
. If not, the user is prompted for the User PIN of that card.
Signing
oct-git
can be used by Git to sign commits or tags.
Signing with oct-git
requires that an OpenPGP card with the data signing key material is plugged into your system.
Additionally, the User PIN for any OpenPGP card device must be accessible via openpgp-card-state (see above).
Verification
Verification of signatures automatically uses OpenPGP certificates from the local openpgp-cert-d "shared OpenPGP Certificate Directory".
If a certificate is not present in the local openpgp-cert-d store, oct-git
attempts to automatically download it [^lookup] from a number of well-known public online directories (currently,oct-git
queries keyserver.ubuntu.com and keys.openpgp.org).
[^lookup]: PKI queries to acquire certificates perform a lookup by signing key fingerprint or key id.
Manually importing certificates to the store
You can manually import certificates into the "shared OpenPGP Certificate Directory" using oct-git
:
$ oct-git --import <certificate file>
This can be useful if you want to verify commits by a certificate that oct-git
can't obtain from the public OpenPGP PKI.
Limitation: Updating certificates in the store
oct-git
currently isn't able to update certificates in the openpgp-cert-d store. There is a tracking issue for this feature.
Limitation: Verification "trust level"
oct-git
currently doesn't display a "trust level" for signature verification. The "trust" concept in question is based on the Web of Trust, and requires configuration of "trust roots", as well as signature chains on which to perform "Web of Trust" evaluations.
This functionality will be added in the future.
Until then, oct-git
displays signatures with the "Unverified" trust level, since we don't currently have a basis for emitting more specific information.
This output means that the signature is cryptographically correct, and the fingerprint of the issuer is shown. However, no chain of trust to the signer is known.
Internals
Technically, oct-git
implements a lookalike for a very small subset of GnuPG's CLI interface.
Specifically, we implement just enough functionality so that Git is able to do signing and verification operations using oct-git
instead of gpg
.
Having a separate binary for use with Git enables oct-git
to be a lot more specific in its user interactions. For example, when touch confirmation is required, oct-git
will show a notification that informs the user that a touch input on a card is required, and shows that the request originates from oct-git
.
The two following sections show how oct-git
is called internally - usually such calls to oct-git
are issued by the git
program.
Basic detached signing
oct-git -u SIGNING_KEY_FPR --detach-sign < Cargo.toml > Cargo.toml.sig
The SIGNING_KEY_FPR
parameter must be set to the fingerprint of the signing subkey (not the certificate) in a hex-encoded format with no spaces (0x
prefix is optional and removed during comparisons).
The fingerprint may be retrieved using oct status
command.
Signature verification
oct-git --verify Cargo.toml.sig - < Cargo.toml
Future directions
The coupling of Git with the OpenPGP signing and verification subsystem is currently based on GnuPG's CLI interface.
This is not ideal, and it limits the design space for alternative OpenPGP subsystems for Git, such as oct-git
.
In the longer term, it would be great if Git supported a more simple, generic and well-defined interface between itself and signing/verification subsystems.
This goal is currently out of scope for this project, but we'd love to hear from you, if you are working on it!
Funding
This project has been funded in part through NGI Assure, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program.
🐒️🥯️
Dependencies
~47–81MB
~1.5M SLoC