rpm-software-management / rpm

The RPM package manager
http://rpm.org
Other
501 stars 360 forks source link

Signing can leave an invalid digest behind if not verifying it #3291

Open pmatilai opened 1 month ago

pmatilai commented 1 month ago

Signing can leave an invalid digest in the package if we're not verifying it, this seems broken:

Steps to reproduce:

  1. take hello-2.0-1.x86_64.rpm from the test-suite and corrupt its md5 hash in the signature header with dd if=/dev/zero of=hello-2.0-1.x86_64.rpm conv=notrunc bs=1 seek=333 count=4
  2. sign it with md5 verification disabled (ie --define "_pkgverify_flags 0x00200" to rpmsign)
  3. note that this succeeds where you kinda expect it to fail
  4. run rpmkeys -Kv on the package with --define "_pkgverify_flags 0x00200" and notice that the corrupt md5 hash is still there

It's not entirely obvious what the right thing here is. We don't want to override the verify flags on signing because that could fail for the wrong reasons - like an obsolete hash we cannot verify. Perhaps we should just delete any signature header elements we did not verify when signing, but that seems a weird too.

nwalfield commented 1 month ago

If a signature header element is corrupted, otherwise invalid, or violates a policy, then the signer probably shouldn't be signing it. How about the following: if there are any signature header elements that can't be verified, rpmsign should complain and refuse to generate a sign.

pmatilai commented 1 month ago

That's basically what it does (refuse to sign if verification fails), but things get weird when you start disabling elements. I ran into this when disabling the verification of MD5 digests, related to #1292.

If MD5 verification is disabled, then we'll merrily verify and sign a package with corrupt MD5 hash, because that hash just isn't interesting to us. But the same package will fail on an rpm version that still checks MD5. This is pretty much what happens on FIPS mode as well: signing on FIPS mode fails unless the package also has SHA256 payload digest which effectively makes the MD5 hash moot anyhow, but then the package that verifies in FIPS mode might not do so in non-FIPS mode because of the broken MD5 hash. And so, the relatively straightforward seeming "require all present elements to be verified before signing" policy prevents package signing on FIPS mode (and maybe going forward, elsewhere too) :zany_face:

Of course, in v6 packages there wont be such tag so these issues are basically limited to v6 signing v4 packages, but you can run into it on any remotely recent rpm v4 version outside default configs.

nwalfield commented 1 month ago

Thanks for the detailed explanation, @pmatilai.

If MD5 verification is disabled, then we'll merrily verify and sign a package with corrupt MD5 hash, because that hash just isn't interesting to us

What about refusing to sign if a disabled element is present? That is, if the package has an MD5 element and the MD5 element is disabled, then refuse to sign the package.

pmatilai commented 1 month ago

That still prevents signing v4 content in FIPS mode, which seems somehow backwards.

I don't think this is an urgent issue by any means, just an ugly wart that we'll want to deal with somehow going forward. Being explicit about it would be a start anyhow, the current silent behavior is nasty.