Bug 127113

Summary: Signing a 3.0.x *.rpm with rpm4 does not change signature region marker.
Product: [Fedora] Fedora Reporter: Ville Skyttä <scop>
Component: rpmAssignee: Paul Nasrat <nobody+pnasrat>
Status: CLOSED WONTFIX QA Contact: Mike McLean <mikem>
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: barryn, joshkel, k.georgiou, mitr, n3npq, plazonic, ulisses
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-10-25 22:20:09 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Patch none

Description Ville Skyttä 2004-07-01 23:34:13 UTC
FC2 stock rpm-4.3.1-0.3 may break a rpm by signing under some
circumstances.  Reproducible case on my box:

Grab Sun's J2SE SDK, the "rpm in self-extracting file" flavour of
1.4.2_05 for i586 from http://java.sun.com/j2se/1.4.2/download.html,
run it to get the plain rpm.

Then, check it:

  $ rpm -K j2sdk-1_4_2_05-linux-i586.rpm
  j2sdk-1_4_2_05-linux-i586.rpm: md5 OK

...and sign it:

  $ rpm --resign j2sdk-1_4_2_05-linux-i586.rpm
  Enter pass phrase:
  Pass phrase is good.
  j2sdk-1_4_2_05-linux-i586.rpm:

So far, so good, but:

  $ rpm -K j2sdk-1_4_2_05-linux-i586.rpm
  error: j2sdk-1_4_2_05-linux-i586.rpm: rpmReadSignature failed:
region trailer: BAD, tag 61 type 7 offset 48 count 16

Using -v or -vv did not produce more info.  It's not only -K which
fails, but all rpm operations on the signed package (with the same
result message) -> the package is borked by signing.

Comment 1 Jeff Johnson 2004-07-02 15:11:49 UTC
Yup.

And here's the reason:
$ rpm -qp --qf '%{rpmversion}\n' j2sdk-1_4_2_05-linux-i586.rpm
3.0.3

WONTFIX, but I'll be happy to suggest workarounds for jpackage
privately if you want. Not hard, the header needs to brought
out of the stone ages, a headerLoad and headerUnload will
accomplish that.

The real fix has to come from Sun, not rpm or jpackage.

Comment 2 Miloslav Trmac 2004-07-02 15:17:06 UTC
Wouldn't it be reasonable to expect that rpm fails the signing process
with an error message instead of silently corrupting data?

Comment 3 Ville Skyttä 2004-07-02 17:13:02 UTC
Comment 2 seconded, aborting the signing process and leaving the
package as-is is what I would have expected if signing an archaic
package such as this one cannot be correctly done.

A workaround could be useful at some point, but not necessary right
now as we can't distribute that particular rpm from JPackage anyway. 
Will ping later if need be, thanks for the offer.

Silently breaking a package is plain unacceptable IMO, reopening based
on that.  Isn't this likely to break with a lot of LSB compliant
packages as well (which IIRC specifies rpm 3 as a requirement)?

Comment 4 Jeff Johnson 2004-07-02 17:30:33 UTC
Again, WONTFIX because
    a) rpm-3.0.3 been dead for years
    b) Red Hat has never shipped a Solaris version of rpm.
    c) Red Hat does not "officially" support anything prior
    to fc1 any more, and not the jdsk on AS 2.1.
    d) rpm needs to complete the transition to header-only
    signatures, not continue to try to support known deficient.
    e) Sun != Red Hat.

But I'll be perfectly happy to tell you (and jpackage.org) privately
what to do. The workaround is not hard, little more than
headerUnload/headerLoad with a header+payload md5 digest
recompute.

Comment 5 Ville Skyttä 2004-07-02 18:42:38 UTC
Shrug.  I don't really expect this to change your WONTFIX decision
(which still IMO is a bad one (nothing personal)), but:

a) So?  This bug report is against rpm 4.3.1-0.3 on FC2.

b) Assuming that this particular reason was created by a faulty
version of rpm running on Solaris, ie. if the initial rpm was already
broken, I might see the point.  3.0.3 != broken per se, it's just old.
 How do you check that it was created by a version of rpm running on
Solaris?  Anyway, if the package is already broken before signing it
(and it certainly does not seem to be completely broken, installs fine
here), going silently ahead with making it _completely_ useless is
unfriendly at best.

c) Again, this bug report is about rpm 4.3.1-0.3 on FC2.  It has
nothing to do with Java or RH's support for Java.  The reproducer just
happens to carry the J2SE files in the payload.

d) Cool.  Is this a sign of a more general direction in mainline rpm
development of dropping backwards compatibility cruft?

e) [no comment]

Thanks again for the workaround support offer, but as said, I think
the workaround is not urgently needed right now.  I just thought you
might be interested in fixing a bug in rpm.  Posting the workaround
recipe here (or somewhere in public) for future reference so that more
people could benefit from it would be nice though.

Comment 6 Ville Skyttä 2004-07-02 18:43:53 UTC
b) s/particular reason/particular package/

Comment 7 Jeff Johnson 2004-07-02 23:08:19 UTC
a) so I have a day job, and do what my boss tells me to do ;-)

b) there is no fault in rpm-3.0.3, resigning the package
with rpm-3.0.3 should work fine. rpm-4.0.2 started development
of header-only signatures, while rpm-4.1 was made immune to
all segfaults due to accidental/malicious damage in headers
while reading a header. The sanity checks that needed to
be retrofitted onto a format that was never designed
to not segfault with bad data is what is preventing
you from resigning, not anything else.

c) yes, it's a bug with current rpm. I've never said otherwise.

d) more than 100% of my rpm development time is (and has been)
spent fussing with legacy problems that hardly matter. Without
a mandate to attempt explicit QA on legacy releases, the problems
cannot be adequately resolved. The hardest problems involve
ABI compliance with versions of rpm that have been burned on
CDROM over the years, that is an insoluble engineering problem.

e) nod. nothing lonelier than fixing a bug for a competitor. Been
there, done that, with Ximian Red Carpet. Not again.

So yes, increasingly legacy compatibility must be abandoned,
for lack of adequate resources, not for any more fundamental reason
in rpm format. No matter what, rpm is often and usually not
the impediment to using old package contents, or for users
who insist on using dead code.

Go figger, sun is almost certainly using the version of
rpm I built on my wee little solaris sun-4c. Even that
machine has no given up the ghost.

Comment 8 Jeff Johnson 2004-07-02 23:19:38 UTC
now given up the ghost. In fact, Sun itself no longer supports sun-4c
IIRC.

Comment 9 Jeff Johnson 2004-07-02 23:41:04 UTC
No breakage is expected with LSB compliance. A later revision
of the LSB packaging standard attempted a better description
of package contents. A standard that says "Packages understood
by rpm-3.0.5" is no standard at all. That was pointed out
at length to LSB at the time they made the mistake.

Not that LSB compliant packaging is ever going to be viable.
There's much, much more to packaging than the rather awkward
and Draconian decision to specify

    LSB compliant packaging can only have
        Requires: lsb

You know this quite well.



Comment 10 Jeff Johnson 2004-07-03 12:49:08 UTC
*** Bug 90334 has been marked as a duplicate of this bug. ***

Comment 11 Jeff Johnson 2004-07-06 12:09:09 UTC
*** Bug 127280 has been marked as a duplicate of this bug. ***

Comment 12 Jeff Johnson 2005-04-11 19:00:06 UTC
jbj> nasrat: this prolly gud enuf:
<jbj> Index: lib/signature.c
<jbj> ===================================================================
<jbj> RCS file: /cvs/devel/rpm/lib/signature.c,v
<jbj> retrieving revision 2.155.2.10
<jbj> diff -u -b -B -w -p -r2.155.2.10 signature.c
<jbj> --- lib/signature.c     13 Mar 2005 01:39:19 -0000      2.155.2.10
<jbj> +++ lib/signature.c     11 Apr 2005 18:56:35 -0000
<jbj> @@ -262,7 +262,7 @@ rpmRC rpmReadSignature(FD_t fd, Header *
<jbj>   
<jbj>         xx = headerVerifyInfo(1, dl, info, &entry->info, 1);
<jbj>         if (xx != -1 ||
<jbj> -           !(entry->info.tag == RPMTAG_HEADERSIGNATURES
<jbj> +           !((entry->info.tag == RPMTAG_HEADERSIGNATURES ||
entry->info.tag == RPMTAG_HEADERIMAGE)
<jbj>            && entry->info.type == RPM_BIN_TYPE
<jbj>            && entry->info.count == REGION_TAG_COUNT))
<jbj>         {
<jbj> slightly better is to figger drilling out RPMTAG_HEADERIMAGE. that is
headerUnload, then headerLoad, with fiddle into the region trailer to change the
number.

Comment 13 Paul Nasrat 2005-04-18 15:58:13 UTC
Testing with above patch:

rpm -Kv j2sdk.rpm
j2sdk.rpm:
    Header V3 DSA signature: NOKEY, key ID 831ffbca
    MD5 digest: OK (a57e6cac53241da744d738da18e58016)
    V3 DSA signature: OK, key ID 831ffbca


Note the dsaheader "failure"

rpm --qf '%{RPMVERSION} %{HEADERIMMUTABLE}\n' -qp j2sdk.rpm
3.0.3 (none)

So we can get header+payload working with the above patch but header-only fails
as no headerimmutable region so Header SHA1 not generated which dsaheader check
s for.  If the plan is to move to header only, then we'll need to handle older
packages being resigned that won't support header only sigs.

Comment 14 Paul Nasrat 2005-04-28 11:20:58 UTC
Created attachment 113766 [details]
Patch

If we don't have HEADER_IMMUTABLE don't do rsa/dsa header only signing.  This
enables --resign on older packages which are beyond users control.

/home/pauln/tmp/sigs/j2sdk.rpm: md5 gpg OK

[pauln@anu rpm-4.4.1]$ ./rpm -Kvv ~/tmp/sigs/j2sdk.rpm
D: Expected size:     35602356 = lead(96)+sigs(233)+pad(7)+data(35602020)
D:   Actual size:     35602356
D: opening  db index	   /var/lib/rpm/Packages rdonly mode=0x0
D: locked   db index	   /var/lib/rpm/Packages
D: opening  db index	   /var/lib/rpm/Pubkeys rdonly mode=0x0
D:  read h#    2416 Header sanity check: OK
D: ========== DSA pubkey id e61876e8 831ffbca (h#2416)
/home/pauln/tmp/sigs/j2sdk.rpm:
    MD5 digest: OK (a57e6cac53241da744d738da18e58016)
    V3 DSA signature: OK, key ID 831ffbca
D: closed   db index	   /var/lib/rpm/Pubkeys
D: closed   db index	   /var/lib/rpm/Packages

Comment 15 Jeff Johnson 2005-05-21 17:45:44 UTC
There is a deep design issue underlying this mess.

RPM has been mired between header+payload and header-only signatures for many
years now.

In order to preserve header+payload MD5 as a universal invariant independent of
what is implemented in rpm when resigning, the legacy header which is part
of the header+payload MD5 digest cannot be changed.

In order to support header-only signatures on an immutable region,
markers are added to the header to identify the immutable header-only region
blob that is signed.

The conclusion is that header-only signature/digest should not be attempted
when resigning legacy packages. Any other scheme will either add Yet Another
Package format special case, or otherwise change the invariant header+payload
MD5 digest.

And the right "fix" is to dump header+payload signatures entirely.


Comment 16 Jeff Johnson 2005-05-21 18:08:56 UTC
There are other payload complications that need solving to preserve
header+paload md5 invariance (for true legacy compatibility) as well.
E.g. invariance assumes that zlib never changes what is written to
a resigned package for all rpm implementations.

I'd suggest that the one line patch to handle the region marker change
in the signature header, and living with the accurate (because legacy headers
are invariant all versions of rpm afaik) but mysterious (essential elements to
compute a header-only signature/digest are not present in the definition
of the header, perhaps something other than NOKEY to be returned)
     Header V3 DSA signature: NOKEY, key ID 831ffbca
is the only sane path forward.

But feel free to do whatever you want, patches cheerfully accepted!

Comment 18 Jeff Johnson 2005-10-25 22:20:09 UTC
This problem cannot be fixed transparently to rpm-3.0.x installers, as additional
information to support immutable header regions would need to be added to
the header, which cannot be done without voiding the header+payload md5 digest.

Sign with rpm-3.0.x if you need to resign.