Skip to content
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

Validate and require subkey binding signatures on PGP public keys #1795

Merged
merged 3 commits into from
Oct 19, 2021

Conversation

pmatilai
Copy link
Member

All subkeys must be followed by a binding signature by the primary key as per the OpenPGP RFC, enforce the presence and validity in the parser.

The implementation is as kludgey as they come to work around our simple-minded parser structure without touching API, to maximise backportability. Store all the raw packets internally as we decode them to be able to access previous elements at will, needed to validate ordering and access the actual data. Add testcases for manipulated keys whose import previously would succeed.

Depends on the two previous commits:
55d5811 and d2fcd53

No immediate effect but needed by the following commits.
No functional changes, just to reduce code duplication and needed by
the following commits.
All subkeys must be followed by a binding signature by the primary key
as per the OpenPGP RFC, enforce the presence and validity in the parser.

The implementation is as kludgey as they come to work around our
simple-minded parser structure without touching API, to maximise
backportability. Store all the raw packets internally as we decode them
to be able to access previous elements at will, needed to validate ordering
and access the actual data. Add testcases for manipulated keys whose
import previously would succeed.

Depends on the two previous commits:
7b399fc and
236b802

Fixes CVE-2021-3521.
Copy link
Contributor

@DemiMarie DemiMarie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs #1705 or equivalent to ensure that non-PGPSIGTYPE_BINARY signatures are not accepted as package signatures.

Comment on lines +559 to +560
if (sigalg->setmpi(sigalg, i, p))
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires a corresponding change in the package signature checking code to ensure that package signatures are PGPSIGTYPE_BINARY. #1705 is one implementation, and I can replace it with a better one that uses proper accessor functions.

Copy link
Member Author

@pmatilai pmatilai Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you've repeated this quite a few times now.

The signature type information is there to tell the reader how to hash the material for correct results. We ignore the byte anyhow for the package hashing purposes because it's just not that intersting for our purposes.

A better implementation would do things differently in many ways, but removing that misplaced semi-random check from 20 years ago is hardly a security regression.

Copy link
Contributor

@DemiMarie DemiMarie Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature type information is there to tell the reader how to hash the material for correct results. We ignore the byte anyhow for the package hashing purposes because it's just not that intersting for our purposes.

It also provides cryptographic domain separation between different types of signatures, which prevents a signature of a public key, a certification signature, or a revocation signature from being accepted as a signature of a document. That is where the security aspect comes from. In the case of RPM, this is somewhat mitigated since the data being signed must start with 0x8e, which means it cannot collide data being signed in any of the other currently standardized signature types. However, there is no guarantee that new signature types will not be added that make this a problem.

A better implementation would do things differently in many ways, but removing that misplaced semi-random check from 20 years ago is hardly a security regression.

See above: in the case of RPM it may not be exploitable, but it could become exploitable if future changes are made to the OpenPGP standard. Best to add the check now as a precaution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really even disagree - optimally we should check for it someplace.
It's just that the check doesn't really fit anywhere nicely and meanwhile arguing over a relatively petty issue is just delaying getting the silly CVE fixed. Silly, because if you get an admin to import a key file you have access to, you don't need to pull off stunts like fiddle with subkey binding signatures.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if I made a good quality PR that fixed the problem, either directly or on to your branch? #1705 got NAK’d on the grounds that it added “another struct pgpDigParams direct access when we're trying to eliminate those.” I can instead add a proper accessor function (is pgpDigParamsSigType okay?) and use it.

Silly, because if you get an admin to import a key file you have access to, you don't need to pull off stunts like fiddle with subkey binding signatures.

The main worry is if someone does something like:

$ gpg --export 'some trusted fingerprint'

and their /usr/bin/gpg doesn’t bother to check subkey binding signatures when exporting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not about just accessors.

The point is, these worries are so far out there when there are a thousand more practical ways to exploit that an inordinate time has already been spent on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmatilai good point. In fact, I would argue that not adding the check would make this PR a regression security wise. Would it be possible to include #1705 in this PR? It is tiny and passes the regression test suite, and can be replaced with a better solution later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repeating yourself ad nauseum isn't helpful to the cause. Really.

Comment on lines +1070 to +1072
0x99,
(pkt->blen >> 8),
(pkt->blen ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inconsistent (at best) for keys larger than 0xFFFF bytes. Not sure if such keys should just be rejected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may be, but it's what the spec says. It's not a security problem because the complete package is hashed anyway. V5 keys hash the complete length, not just the lowest 16 bits.

Comment on lines +559 to +560
if (sigalg->setmpi(sigalg, i, p))
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmatilai good point. In fact, I would argue that not adding the check would make this PR a regression security wise. Would it be possible to include #1705 in this PR? It is tiny and passes the regression test suite, and can be replaced with a better solution later.

@pmatilai pmatilai merged commit bd36c5d into rpm-software-management:master Oct 19, 2021
@pmatilai pmatilai deleted the selfsig-binding-pr branch February 10, 2022 13:43
@sshedi
Copy link
Contributor

sshedi commented Sep 14, 2022

Hi @DemiMarie,

I followed https://access.redhat.com/articles/3359321 to generate keys. But after this fix, I'm unable to import the keys.

root [ ~ ]# rpm --import foo.key 
error: foo.key: key 1 import failed.

root [ ~ ]# rpm -qi rpm
Name        : rpm
Version     : 4.16.1.3
Release     : 12.ph4
Architecture: x86_64
Install Date: Tue Sep 13 16:57:51 2022

Can you please assist me on generating the keys properly?

Here are my patches where I back ported this CVE fix to 4.16.x

https://github.com/vmware/photon/blob/4.0/SPECS/rpm/CVE-2021-3521-1.patch
https://github.com/vmware/photon/blob/4.0/SPECS/rpm/CVE-2021-3521-2.patch
https://github.com/vmware/photon/blob/4.0/SPECS/rpm/CVE-2021-3521-3.patch

@DemiMarie
Copy link
Contributor

@sshedi GnuPG always generates subkey binding signatures by default.

@DemiMarie
Copy link
Contributor

@sshedi you will also need to backport daeddb0

@sshedi
Copy link
Contributor

sshedi commented Sep 14, 2022

But why the import failure? I saw some other discussions #1977

How can I generate gpg keys with sha512 algo?

I tried this:

$ cat .gnupg/gpg.conf 
personal-digest-preferences SHA512
cert-digest-algo SHA512
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

but still I'm getting import failure.

@pmatilai
Copy link
Member Author

A closed PR is hardly a place for assistance requests of any kind. Please open a discussion on the subject.

@sshedi
Copy link
Contributor

sshedi commented Sep 14, 2022

Sorry about that @pmatilai.
We can continue here #2186

gerrit-photon pushed a commit to vmware/photon that referenced this pull request Sep 21, 2022
- CVE-2021-3521.patch taken from
  https://git.rockylinux.org/staging/rpms/rpm/-/blob/r8/SOURCES/rpm-4.14.3-validate-and-require-subkey-binding-sigs.patch

- And add rpm upstream commit
  rpm-software-management/rpm@daeddb0
  This is based on suggestion
  rpm-software-management/rpm#1795 (comment)

Change-Id: Ie6222da4f001e36f4584844c83946dbec72bf283
Signed-off-by: Shreenidhi Shedi <[email protected]>
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/17876
Reviewed-by: Tapas Kundu <[email protected]>
Tested-by: Tapas Kundu <[email protected]>
gerrit-photon pushed a commit to vmware/photon that referenced this pull request Sep 21, 2022
- CVE-2021-3521.patch taken from
  https://git.rockylinux.org/staging/rpms/rpm/-/blob/r9/SOURCES/rpm-4.16.1.3-validate-and-require-subkey-binding-sigs.patch

- And add rpm upstream commit
  rpm-software-management/rpm@daeddb0
  This is based on suggestion
  rpm-software-management/rpm#1795 (comment)

Change-Id: If30dfde170dcb2ee6496b632feb0597f2f7b13a1
Signed-off-by: Shreenidhi Shedi <[email protected]>
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/17875
Reviewed-by: Tapas Kundu <[email protected]>
Tested-by: Tapas Kundu <[email protected]>
gerrit-photon pushed a commit to vmware/photon that referenced this pull request Sep 21, 2022
- CVE-2021-3521.patch taken from
  https://git.rockylinux.org/staging/rpms/rpm/-/blob/r8/SOURCES/rpm-4.14.3-validate-and-require-subkey-binding-sigs.patch
- And add rpm upstream commit
  rpm-software-management/rpm@daeddb0
  This is based on suggestion
  rpm-software-management/rpm#1795 (comment)

Change-Id: Id9e0fa045c70594bc16a7a4a0f206cb2789b8efa
Signed-off-by: Shreenidhi Shedi <[email protected]>
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/17877
Tested-by: gerrit-photon <[email protected]>
Reviewed-by: Tapas Kundu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants