Issue
We use RPM packages in order to deploy our product in our customers' environments. In order to make the RPM fully self-contained, we 'personalize' the RPM to suit the specific customer's environment. This way, the customer only needs to install the RPM without following any wizard to editing configuration files.
My problem is as follows: We sign the RPM package before personalizing it. The personalization process involves appending information to the RPM file (without really adding RPM headers, simply appending raw data). This modification (naturally) breaks the signature of the package.
What I'm looking for is a trick to let me modify the file without breaking the signature.
Here's what I've tried so far:
- The 'lead' part of the package contains reserved bytes which can be used, but it is very limited in size and not scalable.
- Adding extended file attributes - very easy to use but the attributes disappear when copying the file (there are special flags to retain the attributes, but we can't enforce their usage).
- We thought of inserting a dummy header to the RPM and to trick the RPM code into not checking it, still not sure how to do that.
- Signing the package AFTER the personalization has taken place - also not scalable because it means we need to sign the package for each customer instead of just once.
Note that I'm know that a signature should prevent modifying the contents of a file (it behaves as expected). Yet, I don't really want to modify the RPM data, just include extra info in the file.
Any ideas?
Thanks!
Solution
If you really MUST modify a *.rpm while preserving existing signatures, then add tags to the signature header, preferably with tag numbers between decimal ~275 to 999. Both existing signature plaintexts (header-only and header+payload) will no be affected by additional tags/data in the signature header.
Note that more recent versions of RPM have been forced to explicitly enumerate tags and types and data in order to prevent segfaults discovered by fuzzing. But even in that case, there is a padding tag (0x3fffffff from memory) that can be populated with additional data. Again -- iirc -- the latest versions of rpm also verify that the padding is all 0x00 so caveat emptor.
Meanwhile you have not described what "personalization" is, and any tags added to the signature header will be discarded when the package is installed. Note also that the code to rewrite a signature header in a *.rpm is a bit tricky because of padding to ensure that the metadata header that follows a signature header is 8byte aligned.
I suggest that you will find that an additional file containing "personalization" is a better engineering approach. The art of hacking is knowing when to stop ;-)
Answered By - Jeff Johnson Answer Checked By - Pedro (WPSolving Volunteer)