-
Notifications
You must be signed in to change notification settings - Fork 370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Key Fingerprints to rpmsinfoMsg() #3321
Conversation
Fishing out an example output from the CI run to make it easier to discuss:
The :OK (or whatever the result) should continue to be the very last thing on this line to make it trivial to see/parse what the TLDR outcome of each part is. The keyid becomes redundant if the fingerprint is there, so I guess we should just go with what @nwalfield suggested in #3292 (comment) and show either the fingerprint or if not available, the long keyid. Some programs split up the fingerprint a bit to make it easier for humans to consume (eg split by space so the keyid is easy to see), but I don't know if there's a "best practise" on that. Just FWIW, we're in no way married to using pgpIdentItem() for the rest of our days. That dumb thing never should've been a public API but the rpmio/lib split and lack of other APIs forced the issue at the time - it was supposedly the lesser evil compared leaving all the structs wide open. If we want to dynamically decide on fingerprint/keyid we'll need to ditch it anyhow it seems. |
Maybe it's a good idea to also return the pubkey version with the fingerprint if you're adding a new API function. |
OK, put #3292 underneath, adjusted the message and the name of For now I have not remove the key IDs from the messages. I wonder if keeping them is more backward compatible. While they are technical redundant figuring out the key IDs from the fingerprints is kinda annoying for anyone parsing the output. But I agree that the messages are getting overly long. Any other opinions? @nwalfield ? |
See my point about splitting the fingerprint up a bit, that way you could make the keyid part stand out. |
rpmio/rpmkeyring.c
Outdated
if (key == NULL) | ||
return -1; | ||
key = key->mainkey; | ||
pthread_rwlock_rdlock(&key->lock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lock should be taken one line earlier, above the key assignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure about that. To be fair may be I should just use an new variable for that.
But right now we are locking the main key. The one we are actually processing. For sub keys we might need to lock that, too, if the assignment needs a lock around it. Ofc we'd need to be more careful for main keys to not lock them twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see it's a bit different than the average key member, and it's indeed trickier than that. But mainkey can go away between the assignment and the locking, so that's not safe as it is.
Subkeys can become separated from the main key (call rpmGetSubkeys() and then free the main key), so the mainkey needs to be reference counted instead. And then you here take a reference to the mainkey.
Also, it's indeed better to use a new variable than reuse an argument, such reuse doesn't save anything at all and makes the code less obvious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW now that #3302 got merged, you'll need to rebase this and switch to the C++ locking instead of pthread_*.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, now that the locking is completely different I have re-done this.
I think when the fingerprint is available, we should strictly prefer it.
What are you thinking of here? Are you imaging a script breaking because it matches on the key ID? Will those scripts still work when we add the fingerprint to the output?
In what cases does one need a key ID, but a fingerprint is rejected? In other words, why would anyone ever need to derive the key ID? |
How do you imagine rpm or an application that uses the library using this information? |
Lets say you want to put the key in a database so that you can find it if you want to check a signature. In that case you need to use pubkey version plus fingerprint as a key. |
Why do you need to use the version as part of the key? Are you worried about collisions? Fingerprints don't require collision resistance, because the attacker doesn't control the key material. As such, both SHA-1 and MD5 are safe. See, for instance, this wikipedia article. |
Are you really arguing that the keyid would have been enough in the signature and switching to the fingerprint was a mistake? Note that the fingerprint subpackage does include the version of the key. |
I really don't understand you. Sure, the issuer fingerprint subpacket includes the version, in which case you have the fingerprint and don't need the key ID. But in the case of the issuer subpacket, you don't have a version. Also, the issuer is self-authenticating. So if multiple key IDs match, then you (should) try them all. |
0a63303
to
a927b9d
Compare
I wonder what's the deal with upper verses lower case hex strings. I split the fingerprints into groups of four and in lowercase this looks very wrong to me for some reason. Any opinions on that topic? Looks like RPM has always used lowercase in one continuous string. |
From my POV this is now complete. |
As for the upper/lowercase thing: lets leave it at lowercase here - like it is in the PR now. We'll want to revisit that when we deal with #3313 but there's no need to mess with that here just now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some unresolved review remarks still. Marking as request changes to make it stand out, the main conversation is getting crowded to the point where its hard to see what's still relevant.
tests/rpmvfylevel.at
Outdated
@@ -319,15 +319,15 @@ done | |||
[0], | |||
[nopls | |||
/data/RPMS/hello-2.0-1.x86_64-signed.rpm: | |||
Header V4 RSA/SHA256 Signature, key ID 1964c5fc: OK | |||
Header V4 RSA/SHA256 Signature, key ID 4344591e1964c5fc, key fingerprint: 771b18d3d7baa28734333c424344591e1964c5fc: OK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I realize now why you originally put the fingerprint after the OK: the "key ID" part belongs to the signature. "key fingerprint" after that seems just repetitive, until you realize it comes from a different source entirely.
The message should probably make this clear somehow 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a related note, this is also why you should really decide what to output first, and once that is agreed upon, go and implement. You don't need a single line of code to mock up various versions of such messages, and concrete examples are always easier to discuss than highlevel this or that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you really want to keep both, then perhaps:
... signing subkey 4344591e1964c5fc, certificate: 771b18d3d7baa28734333c424344591e1964c5fc
But I'd rather just show the certificate as users don't need to know about this detail.
rpmio/rpmkeyring.c
Outdated
if (key == NULL) | ||
return -1; | ||
key = key->mainkey; | ||
pthread_rwlock_rdlock(&key->lock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see it's a bit different than the average key member, and it's indeed trickier than that. But mainkey can go away between the assignment and the locking, so that's not safe as it is.
Subkeys can become separated from the main key (call rpmGetSubkeys() and then free the main key), so the mainkey needs to be reference counted instead. And then you here take a reference to the mainkey.
Also, it's indeed better to use a new variable than reuse an argument, such reuse doesn't save anything at all and makes the code less obvious.
rpmio/rpmkeyring.c
Outdated
if (key == NULL) | ||
return -1; | ||
key = key->mainkey; | ||
pthread_rwlock_rdlock(&key->lock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW now that #3302 got merged, you'll need to rebase this and switch to the C++ locking instead of pthread_*.
Short (4 bytes) PGP Key IDs or insecure and prone to collisions. Long Key IDs (8 bytes) are still not as good as full Fingerprints with 20 to 32 bytes but a huge step up. Related: rpm-software-management#2403
Store pointer to primarykey and use it to get the Fingerprint of the primary key for sub keys.
Add the key to rpmsinfo_s so we have the key available with the verified signature and can print the key's finger print when desired
The Key IDs may only be confusing when subkeys are used and the key ID won't match up with the finger print of the main key.
Even if a signature fails giving the fingerprint of the public key that is involved has some value. The key can no longer be trusted for various reasons or the package was tempered with. In both cases it might be of interest which key is outdated or attacked.
{ | ||
rpmPubkey key = new rpmPubkey_s {}; | ||
/* Packets with all subkeys already stored in main key */ | ||
/* Packets with all subkeys already stored in primary key */ | ||
key->primarykey = primarykey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I think this is pretty nice now.
The issues with the subkey refcounts and locking were there to begin with, and its quite impossible to reason about those things if one of the places doesn't honor the rules at all. Would've probably been easier if we'd spotted the subkey handling doesn't make much sense to begin and address that first, but it is what it is.
This does not yet adjust the test cases. So 198 209 216 217 220 221 222 223 226 227 are failing due to unexpected key finger prints.
Can probably be used in combination with #3292 as this does not touch the keyid output. Although we might want to skip the key id for verified signatures.
Related: #2403