An OpenPGP certificate linter.

This program checks for and can fix issues with OpenPGP certificates. The current focus is on the use of SHA-1, which has been [successfully attacked], and was [deprecated by NIST] in 2011:

Since 2005 SHA-1 has not been considered secure against well-funded opponents, as of 2010 many organizations have recommended its replacement. NIST formally deprecated use of SHA-1 in 2011 and disallowed its use for digital signatures in 2013. As of 2020, attacks against SHA-1 are as practical as against MD5; as such, it is recommended to remove SHA-1 from products as soon as possible and use instead SHA-256 or SHA-3. Replacing SHA-1 is urgent where it's used for signatures.

This program checks for the following issues:

sq-keyring-linter can fix all three of these issues in a straightforward manner:

$ gpg --export-secret-key 4BE50C526C743502 | cargo run -- --fix | gpg --import Certificate 4BE50C526C743502 is not valid under the standard policy Certificate 4BE50C526C743502 contains a User ID ("SHA1 User ID, SHA256 Subkeys <sha1-user-id-sha256-subkeys@example.org>") protected by SHA-1 Certificate 4BE50C526C743502, key CC6387BFA4D9263D uses a SHA-1-protected binding signature. Examined 1 certificate. 0 certificates are invalid and were not linted. (GOOD) 1 certificate was linted. 1 of the 1 linted certificates (100%) has at least one issue. (BAD) 1 certificate has at least one non-revoked User IDs: 1 has at least one User IDs protected by SHA-1. (BAD) 1 has all User IDs protected by SHA-1. (BAD) 1 certificate has at least one non-revoked, live subkeys: 1 has at least one non-revoked, live subkeys with a binding signature that uses SHA-1. (BAD) 1 certificate has at least one non-revoked, live, signing-capable subkeys: 0 certificates have at least one non-revoked, live, signing-capable subkeys with a strong binding signature, but a backsig that uses SHA-1. (GOOD) gpg: key 4BE50C526C743502: "SHA1 User ID, SHA256 Subkeys <sha1-user-id-sha256-subkeys@example.org>" 2 new signatures gpg: key 4BE50C526C743502: secret key imported gpg: Total number processed: 1 gpg: new signatures: 2 gpg: secret keys read: 1 gpg: secret keys unchanged: 1

(The diagnostics and the summary are printed to stderr; any fixed keys are printed to stdout and encoded using ASCII Armor.)

If you run it again, no issues will be detected:

$ gpg --export-secret-key 4BE50C526C743502 | cargo run -- --fix | gpg --import Examined 1 certificate. No issues found (see `/tmp/keyring-linter/debug/sq-keyring-linter --help` for a list of issues that are checked for). gpg: no valid OpenPGP data found. gpg: Total number processed: 0

You can examine the signatures that sq-keyring-linter creates using, for instance, pgpdump:

$ gpg --export-secret-key 4BE50C526C743502 | cargo run -- --fix | pgpdump ...

In our experience, Sequoia's output is a bit more readable. You can either use sq packet dump or https://dump.sequoia-pgp.org/.

You can check whether one or more OpenPGP certificates have issues as follows:

$ dpkg -l debian-keyring ... ii debian-keyring 2020.09.24 $ cargo run -- /usr/share/keyrings/debian-keyring.gpg ... Examined 885 certificates. 1 certificate is invalid and was not linted. (BAD) 884 certificates were linted. 207 of the 884 linted certificates (23%) have at least one issue. (BAD) 884 certificates have at least one non-revoked User IDs: 169 have at least one User IDs protected by SHA-1. (BAD) 106 have all User IDs protected by SHA-1. (BAD) 836 certificates have at least one non-revoked, live subkeys: 160 have at least one non-revoked, live subkeys with a binding signature that uses SHA-1. (BAD) 230 certificates have at least one non-revoked, live, signing-capable subkeys: 10 certificates have at least one non-revoked, live, signing-capable subkeys with a strong binding signature, but a backsig that uses SHA-1. (BAD)

From the above output, we can see that the current Debian keyring has 885 certificates. One certificate is considered invalid by Sequoia and was skipped. Of the rest, 207 (23%) use SHA-1 in some way. These should be fixed.