Introduction
If you are creating and distributing RPMs, one thing you may want to consider providing digital signatures for the RPMs. Providing such a digital signature for an RPM will allow users, no matter where their copy of the RPM originated, to verify that you are it’s creator. Not only can they perform such verification, they can do it without requiring any intervention on your behalf.
Even though I know of no problems with the instructions on this page, I have to state the following:
These instruction are provided as is and with no implied warranty – use them at your own risk. I assume absolutely no liability for any damage which results either from the direct or indirect use of the information and instructions outlined on this page.
Key Generation
The first thing required for digitially signing an RPM is to generate a public / private key set for yourself and to have them located in the key ring in your home directory. If you aren’t certain whether you have a key ring or just want to see what keys you have available, you can can run the following command:
gpg –list-keys
You should see output similar to what is show below though of course the directory and specifics of the key information will reflect your system and available keys.
/home/mlampkin/.gnupg/pubring.gpg pub 1024D/11A050A7 2005-06-25 [expires: 2006-06-25] uid Michael M. Lampkin <mlampkin@cognitus.net> sub 4096g/206A4D23 2005-06-25 [expires: 2006-06-25]
If you don’t see something like this or all the keys are marked expired ( or revoked ) then you should generate a new key pair using the instructions found here or elsewhere on the Internet.
Creatingthe .rpmmacros file
Once you have verified that there is an available key for creating digital signatures, the next step is to create a file named .rpmmacros in your home directory. The .rpmmacros file takes the following format when using GPG:
%_signature gpg %_gpg_path [USER_HOME]/.gnupg %_gpg_name [KEY_ID] %_gpgbin [PATH_TO_GPG]
The fields shown enclosed in brackets should be defined in your .rpmmacros file as follows:
[USER_HOME] The full pathname of your home directory
[PATH_TO_GPG] The full path and name of the gpg program. A typical value here is /usr/bin/gpg
[KEY_ID] This field can be one of the following three values. Following are descriptions and examples using the example output from the gpg –list-keys command shown previously:
-
the numeric value of a key e.g. 11A050A7
-
the email address associated with a key e.g.<mlampkin<at>cognitus.net>
-
the entire human readable identifier associated with a key e.g. Michael M. Lampkin <mlampkin<at>cognitus.net>
Signing an RPM file
Once you are set up, signing the RPM is the easiest of tasks. Simply execute the command:
rpm –addsign [rpm name]
and when prompted enter the pass phrase for the key you specified in your .rpmmacros file.
Verifying an RPM signature
Verifying a signature on an RPM is done using the command:
rpm –checksig [rpm name]
At this point, anyone can use that command and verify that the RPM has been signed by someone and the ID of the signing key but thats about it. There is no way to know anything else about the signer and the output on a signed ‘test.rpm’ shows this
test.rpm:
Header V3 DSA signature: NOKEY, key ID 5e00df4c
Header SHA1 digest: OK (f2cdf537bdec0e6c8079665a579ddcbc97766bdc)
MD5 digest: OK (f8e64725089b27222627777c0a7429a7)
V3 DSA signature: NOKEY, key ID 5e00df4c
What the receiver must do first is obtain a copy of your public key. With any luck you have placed it on a public key server and they can just download and add it to their key ring using the key ID. The format of the key download command is:
gpg ––keyserver [server] ––recv–keys key [ID]
For example, if they knew that the key was on wwwkeys.us.pgpg.net and that the ID was 11A050A7 ( as in our example ) then the command they would use would take the form:
gpg ––keyserver hkp://wwwkeys.us.pgp.net ––recv–keys key 11A050A7
They still aren’t finished though. Now GPG knows about the key but RPM still doesn’t and so they still have a couple steps to perform. First they will export the retrieved public key into an ASCII format file using the command:
gpg ––export –armor ID > [filename]
Again using our example key and an output filename of pub.asc the command would look like:
gpg ––export ––armor 11A050A7 > pub.asc
Now there is an ASCII armored version of the public key with the ID 11A050A7 in the file pub.asc and the last step of importing into the RPM key ring is done. The command for this action is:
rpm –import [filename]
Which gives us:
rpm –import pub.asc
One thing to mention: the RPM program keyring requires privileged access to modify. This means to execute this final command the user will have to be logged in as root or temporary grant themselves root privileges via a sudo command or similar.
Lets see the output if we run the command rpm –checksig –verbose test.rpm again after we have imported the public key into the RPM keyring.
test.rpm:
Header V3 DSA signature: OK, key ID 11a050a7
Header SHA1 digest: OK (f2cdf537bdec0e6c8079665a579ddcbc97766bdc)
MD5 digest: OK (f8e64725089b27222627777c0a7429a7)
V3 DSA signature: OK, key ID 11a050a7
We can plainly see the difference from the previous run as now the DSA signature field is marked “OK” instead of “NOKEY”. This means that the local version of RPM has read the signature and successfully verified it as known and trusted.
Finishing Up
We’ve seen that signing an RPM is a fairly simple affair, especially if we already have a pre-existing GPG key pair to use. Even if we have to generate a new key pair for use there aren’t that many additional tasks required of us.
On the other hand, it may like more work than its worth for the recipient of the RPM to verify a digital signature. The truth is though, that once the user has imported your public key into their RPM key ring, they can use it to verify your signature on any number of RPMs you send them as long as that public key has not expired ( or been revoked ). So in the long term the amount of work required really isn’t that much of a constraint.