RPM Community Forums

Mailing List Message of <rpm-devel>

Re: rpm3 package still exist

From: Jeff Johnson <n3npq@mac.com>
Date: Wed 25 Jun 2008 - 18:41:44 CEST
Message-id: <E142E34F-F5DB-49EF-93B8-2711695A6A1D@mac.com>

On Jun 25, 2008, at 12:06 PM, Tim Mooney wrote:

> In regard to: rpm3 package still exist, devzero2000 said (at 4:53pm  
> on Jun...:
>
>> rpm -qi TIVsm-API
>>
>> Name        : TIVsm-API                    Relocations: /opt
>> Version     : 5.3.0                             Vendor: IBM
>> Release     : 0                             Build Date: Wed 08 Dec  
>> 2004
>> 01:29:20 PM CET
>> Install Date: Wed 06 Jun 2007 11:42:51 AM CEST      Build Host:
>> darkover.mainz.de.ibm.com
>> Group       : Utilities/Archiving           Source RPM:
>> TIVsm-5.3.0-0.src.rpm
>> Size        : 13934052                         License: Commercial
>> Signature   : (none)
>> URL         : http://www-3.ibm.com/software/tivoli/products/ 
>> storage-mgr/
>> Summary     : the API
>> Description :
>>                IBM Tivoli Storage Manager API
>>
>> rpm -q --qf '%{RPMVERSION}\n' TIVsm-API
>> 3.0.6
>
> That was built by ibm, and the commercial UNIX vendors are  
> notorious for
> sticking with a particular version of some software to maintain  
> backward
> compatibility.
>
> This segues nicely into a question that just came up on the NetWorker
> (backup software) mailing list.  EMC also packages all their RPMs for
> their backup software using RPM 3.0.6, and EMC and IBM aren't the only
> ones doing this.
>
> If you try sign an RPM built with 3.0.x with a 4.X.Y version of  
> RPM, the
> RPM becomes corrupted.
>

Yup. Sign with the same version of rpm used to build the package will
always "work" no matter what.

> Would this be something that's easy to fix -- make RPM 5.1.x  
> capable of
> signing both modern and ancient RPMs?  It sure would make a lot of
> sysadmins lives easier, as they wouldn't have to keep an old copy  
> of RPM
> around just to sign packages they get from vendors.
>

There is no fix because the plaintext used for signing was changed
from header+payload to header-only.

So packages built by rpm-3.0.x do not include the markers necessary
to recover the canonical form of the original unchanged "immutable"
plaintext that is used by RPMv4 header-only signatures.

What is far more important (imho) is/was to preserve the use of the  
header+payload
MD5 digest as an invariant *.rpm identifier. Clearly, any change to  
header
or payload is impossible without voiding the header+payload digest.

Without adding the "immutable" markers to headers, then recovering
the header-only plaintext is impossible. tags were routinely replaced
in headers by rpm-3.0.x, the original information was discarded, and
so there is no concept of plaintext available with "LSB  
format" (formerly
RPMv3) packages.

Could a converter be written if preserving header+payload MD5 was
not an issue? You betcha. The details necessary to do so I tried to
send to <rpm-lsb@rpm5.org> this weekend past, but apparently
e-mail is becoming increasingly unreliable for communication,
I can't seem to find what I sent in the archives. Oh well ...

Here's what I wrote. The other code necessary to do the rest of
the package conversion is in build/pack.c since like forever.

=============================================================

Along these lines, you should attempt to add a SHA1 on you rregistered
header. Almost all headers (LSB and Sun java being the Luddites)
in an rpmdb carry a SHA1 to guarantee package metadata
integrity many years now. No such guarantee can be attempted unless  
you also
compute and supply the necessary Header SHA1.

The code that is needed to add a header SHA1 is in build/pack.c.

Essentially (this is rpm5 code, there are minor API differences)

     /* Reallocate the header into one contiguous region. */
     Header h = headerReload(h, RPMTAG_HEADERIMMUTABLE);
     ...
     size_t uhlen = 0;
     void * uh = headerUnload(h, &uhlen);
     DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO, 0);
     const char * SHA1 = NULL;

     (void) rpmDigestUpdate(ctx, uh, uhlen)
     (void) rpmDigestFinal(ctx, &SHA1, NULL, 1)

     headerAddEntry(h, RPMTAG_SHA1HEADER, RPM_STRING_TYPE, SHA1, 1);

Note that the ordering of tag additions is also significant. E.g.  
RPMTAG_FILESTATES
should be added _AFTER_ headerReload() and the SHA1 computation I've
just described, because that's what is done during installation with  
RPM.

Ditto adding RPMTAG_INSTALLTIME. FYI, the complete set of
additions is in lib/psm.c near the
      case PSM_RPMDB_ADD:
code.

But I've likely digressed, sigh ...

73 de Jeff
Received on Wed Jun 25 18:42:00 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.