-
Notifications
You must be signed in to change notification settings - Fork 372
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
rpm --import does not replace old keys with new keys #2577
Comments
I should mention that I am not the first person to encounter this problem -- I imagine many people are affected. See for example this Reddit thread: https://www.reddit.com/r/chrome/comments/13s799o/googlechromebeta_1140573545_rpm_invalid_signature/ |
Looking at the code, it seems: which checks if the certificate's key id is known, and if so, don't do anything. OpenPGP certificates are made up of packets. It is possible to add new packets without updating other packets (e.g., a new subkey, a new self signature that extends the certificate's expiration time). So it is not easy to generate a linear version number for an OpenPGP certificate. I think we need to extend rpm's pgp interface to add a function to merge two versions of a certificate. |
@nwalfield, merging certificates sounds like a relatively hard problem to solve in general. In this situation, if the user types
then they probably just wants to replace the pre-existing key/certificate with the supplied one. Can you think of any use cases where this would cause a problem? |
Can you explain what you are thinking or worried about here? The implementation to merge certificates in Sequoia starts here. We basically turn the two certificates into arrays of packets, and merge the two arrays. Then we canonicalize the result, which reorders and dedups the packets. I admit it is a few lines of code, but I think it is a stretch to say that it is a hard problem.
Yes. If the new certificate is missing some components that the existing version has, signatures that could once be verified may no longer be verifiable. |
I'm not especially worried. It just sounds like a lot of work! But it sounds like you have already done the work, so there is no problem.
I suppose there might be some situations where that is helpful. But it sounds dangerous as a default behaviour. Old keys would never get retired / revoked. This could leave users vulnerable to attack. Otherwise, what's the point of rotating keys? |
I see. If I understand you correctly, you're suggesting that the old component would be dropped. Are you suggesting that people resign their old messages when they retire an signing subkey (that sounds like a lot of work)? If not, how would a third party verify an old signature? |
Yes, I think the old component should be dropped by default. No, I don't think old packages should be re-signed by the new key. Rather, I think that the key master ought to keep old keys inside the certificate unless they want to revoke it (e.g. due to an attack). The old keys would still have expiry dates, so RPM would complain about old signatures -- but this can be overriden. To reiterate, I think the common scenarios would be one of:
|
Is a "key master" the entity that controls the key? I think we are using the word certificate in different ways. According to RFC 4880, a certificate in OpenPGP (as a first approximation) is a Public Key packet, zero or more direct key signatures, zero or more User ID packets with any accompanying self signatures, and zero or more Subkey packets with any accompanying self signatures. Is that how you are using the word certificate? Can you explain what it means for "a key master" to "publish keys with separate certificates"? |
You are right, I am not on top of OpenPGP terminology, and I suspect much of the documentation floating around (including GPG's own manual) is not entirely aligned with it. Thank you for being patient with me! By key master, I mean the person (or team of people) who manage the signing keys at Google. I think I was using the word certificate inconsistently, but mostly in the same way you are. I think it's helpful to use examples to make 100% sure we are talking about the same thing. Examples of certificates include:
My first example above -- the Fedora 36 signing key -- is distributed in its own certificate. Fedora 37 has a separate key and a separate certificate. This separation means that the user can install any combination of them at their leisure. If for some reason they want to check old signatures, they can do so by installing old certificates containing old keys. Since Fedora publishes keys in separate certificates, there is no need to merge Fedora's certificates. On the other hand, Google publishes many keys within a single certificate (the second example). If a new version of the certificate removes some old keys, this would prevent the user from verifying old signatures. For example, the key that was issued on 2016-04-12 (and expired in 2019) might get removed from future versions of this certificate. If this happens, then the user would have no obvious way of verifying packages signed by this key. Your proposal of merging the new certificate with previously installed ones is one way of addressing this problem. But I think it comes with a serious downside that the user has no way removing revoked keys. If the 2016-04-12 key gets compromised, your proposal might leave the user vulnerable to attacker-signed packages. (The fact that they key has expired might help, but it's not the end of the story; e.g. what if a more recent key gets compromised?) Sorry for the long letter. But hopefully my writing (and my thinking!) is a bit clearer now. |
Yes.
This is not how the term certificate is commonly used in the OpenPGP ecosystem. This file includes two certificates: 4CCA1EAF950CEE4AB83976DCA040830F7FAC5991 and EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796.
You've unfortunately lost me again. In OpenPGP, a key is not separate from a certificate. A key is a component.
I don't understand why a user would want to remove a revoked key. If it is revoked, the user should just import the revocation certificate and then it can't be used to verify packages any more. |
Thank you for your patience! They are bundled together into a single file, and into a single (virtual?) RPM package gpg-pubkey-38ab71f4-60242b08. Is there standard terminology for this situation?
What I mean is that the Fedora 36 signing key can be installed separately from the Fedora 37 signing key. They are in separate virtual RPM packages, and they have separate keys and certificates. This contrasts with the Google situation where it's different versions of the same certificate.
Good point. I guess I was worried that the key master might not distribute a revocation certificate, or that DNF / RPM might not acquire and process the revocation certificate correctly. Has this been tested? |
@andrewclausen The Sequoia backend should process revocation certificates correctly. The internal backend does not, which is one of multiple reasons it is deprecated. |
It's not just a question of the backend. For example, how would the revocation certificates be distributed? My main point here is: security is hard, and users (like me) definitely appreciate seeing that everything has been thought through. If so, I think @nwalfield's proposal should work well. |
This blocks Google Chrome updates on Fedora Silverblue entirely: |
I agree --import needs some sort of "update" operation. But any solution that may be developed in the future is not going to help the now of Chrome users as there's no way to get it deployed to all the (enterprise) distros out there. Google needs to use keys that are compatible with how existing rpm works, no matter how inconventient or braindead it may be at this time (it is). In practise this means using a new (top-level) key so the gpg-pubkey "version" changes. |
@pmatilai, unfortunately, I think you're right. Where should we discuss how to implement the merge / update operation? |
This is as good as any, I just wanted to point out to the reporter that whatever and whenever happens here can only be a forward-going solution, Google will need to deal with their existing users by some other means. |
Ok, thanks for the clarification. From my perspective, there is no way to generate a version number for an OpenPGP certificate. This is because an OpenPGP certificate is composed of packets, and packets can be left out without making the certificate completely invalid. This is exactly what |
Yup, trying to shoehorn the keys into something resembling a package has been a major source of headache as long as it's been there. It's just difficult to get rid of. Ideally this would all happen in some blackbox keyring and rpm doesn't need to care. As long as we're stuck with the gpg-pubkey "packages"... One possible, if crude, way to handle this could be turning the "version" field into a hash that's calculated from the contained keys to differentiate the "packages", so it can at least be imported. That should "work" with the internal backend too, at least for cases where an updated key contains a new subkey (such as is the case with Chrome I guess). Changing the way the "version" is calculated is going to break something of course, but something is going to break here no matter what we do. On a related note, there's a long-standing RFE to stop using the short id for the version because it can (quite easily) conflict. And no, we're not going to try to implement any merge thing in the internal backend, no way. |
Also, the way the keys are handled as sort of packages, people probably wouldn't be too shocked if we just treated it as a simple upgrade (erase old, import new) based on timestamp, and not worry about any merging at all. |
I'd really prefer that we merge the existing certificate with the new certificate. This is particularly important as gpg strips old self signatures when exporting certificates. One consequence of replacing an existing certificate with a new version is that existing packages may not verify any more, which is annoying. Another is that we may remove a revocation certificate, which is dangerous. If we don't need to order versions, then using the hash as the version seems reasonable. Is that correct? If we use the hash of the "blob," this may mean that we have version A installed, the user installs version B, and as a result C is installed. Is that okay? Using a hash also assumes a canonical form. OpenPGP certificates don't have a canonical form. Packets, for instance, can be reordered. Is that an issue? It occurs to me that for the internal backend, this isn't really a problem as the only thing that really matters is the primary key packet. So we can probably come up with a straightforward hack. |
Workaround for Chrome found:
via: https://discussion.fedoraproject.org/t/google-chrome-failed-update-due-to-signature-not-ok/83540/38 |
Fixed by #3083 (but not in rpm-sequoia yet) |
I'll find some time to add this in the near future. Thanks everyone who made this possible! |
Encountering the problem with Google Linux Signing keys
When I try to install new Google Linux Signing keys in Fedora 37 (with the latest stable release of
rpm
, namely 4.18.1), it fails. However, when I delete the old (pre-installed) keys, and try again, it works. Here is what I typed:Here is the output. Notice that the first attempt at importing the keys fails silently, whereas the second attempt (after deleting old keys) succeeds.
The root of the problem
Google's Linux Signing keys have an unusual configuration: they retain the same master key, but replace the subkeys which do the actual signing. Since
rpm
identifies the whole collection of keys by the master key, the new key looks like the pre-existing key. So it ignores it.Work around
The work around -- as alluded to above -- is to delete the old keys before trying to import the new ones. This can be done with:
Discussion
This bug is potentially quite serious. Millions of Linux users use Google Chrome, and right now, there is no way for them to install or upgrade it. They will just see that signature verification fails. Most people will give up, or worse, disable signature checks. Those that try to check the signature manually will be thwarted by the same bug again.
This means there is a serious usability impact (not being able to install Google Chrome), as well as a serious security impact (not getting security updates, or installing unverified updates for Google Chrome).
Solution
Please either fix
rpm
so that it correctly imports keys (e.g. by using a timestamp as the key version), or deprecate the use of subkeys.The text was updated successfully, but these errors were encountered: