Closed ghost closed 5 years ago
I'll try and get this library resurected - https://github.com/esl/egpgme . I've got an open issue and PR trying to get it working https://github.com/sa2ajj/egpgme/pull/1 . If I can get it running, would you be interested in a PR? It's LGPL (unavoidable given the GPL code of gpgme library) - is that an issue. Alternatively - could have a go at creating a parser for the GPG export format.
Hi @bryanhuntesl, I did not have time to implement RFC 4880 - OpenPGP Message Format in order to parse GPG public keys and extract mandatory fields (key-id, subkeys, emails, etc.) so far.
I would prefer to not pull an external dependency such as gpgme and instead write the parser using pattern matching (see RFC 4880).
In order to show a "Verified" label for a each sign commit in a performant manner, we
1) Parse the gpgsig
header from each commit in GitGud.RepoStorage.push/2
, extract relevant informations and store them in the GitGud.Commit
helper schema.
2) When rendering commits (and their "Verified" label), we retrieve their GPG key-id and match them against our GitGud.GPGKey
schema. Similar to what we do to verify author's email addresses.
I've made a first attempt to display "Verified" commits. See 69f1e99.
The current implementation is weak and does not provide any checks in order to verify the commit's raw data with the associated public key. We basically only store GPG key ids on push and use them in order to match GitGud.GPGKey
and associated GitGud.User
when listing commits.
Currently, a commit is "Verified" only if the commit's author matches the user that signed the commit...
I'm not sure how GitHub or GitLab are verifying signed commits. I assume that they require to associate a verified email address to the public GPG key (which is easy to implement in our case). see 3292bde.
I'm also pretty sure that they verify the commit's raw data with the public key but I'm not sure when this occurs. Having to do so for each rendered commit will not perform well.
We could add a :signed_by
field to GitGud.Commit
and use it instead of :gpg_key_id
when rendering commits. If we do so, we will have to implement commit verification (verify commit's raw data with the public key and set :signed_by
) when
1) a commit is pushed (GitGud.RepoStorage.push/2
) - retrieve the GPG key matching :gpg_key_id
, verify the commit and set :signed_by
field.
2) a GPG key is added - retrieve commits signed with the GPG key, verify them and set :signed_by
accordingly.
I also know very little about GPG sub-keys and how hard it would be to support commit signing via subkeys.
We still need to calculate the fingerprint of :pubk
and :pubsubk
.
These fields are not stored as such within the OpenPGP Message Format. We need to calculate their fingerprint using a 160-bit SHA1 hash of the key and it meta-data (see Key IDs and Fingerprints).
A V4 fingerprint is the 160-bit SHA-1 hash of the octet 0x99, followed by the two-octet packet length, followed by the entire Public-Key packet starting with the version field. The Key ID is the low-order 64 bits of the fingerprint. Here are the fields of the hash material, with the example of a DSA key:
a.1) 0x99 (1 octet)
a.2) high-order length octet of (b)-(e) (1 octet)
a.3) low-order length octet of (b)-(e) (1 octet)
b) version number = 4 (1 octet);
c) timestamp of key creation (4 octets);
d) algorithm (1 octet): 17 = DSA (example);
e) Algorithm-specific fields.
Closing this. I've open #42 for further work.
File type is : PGP/GPG key public ring (v4) created Thu May 3 22:35:56 2018 RSA (Encrypt or Sign) 2048 bits MPI=0xb33dca8fc4b3b174...
https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/
There may be a library to decode it's fields built into beam or maybe pick it apart using binary pattern matching.