THIS STUFF HAS NOW BEEN ADDED TO THE DocBook CONTRIBUTORS GUIDE.
PGP keys are required for releasing artifacts, as described for the ReleaseProcess, although not (as I now understand it) for the ManualDeployProcessForSnapshots.
Some background notes:
- http://www.apache.org/dev/release-signing.html
- https://docs.sonatype.org/display/Repository/How+To+Generate+PGP+Signatures+With+Maven
These are my notes of the steps required.
Install and configure GnuPG
Reference:
Download GnuPG, http://www.gnupg.org/download/
- 1.4.10 or higher
Edit ~/.gnupg/gpg.conf so that the default is to generate a strong key
- on Windows, the file to edit is C:\Users\xxx\AppData\Roaming\gnupg\gpg.conf
Code Block |
---|
personal-digest-preferences SHA512 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed |
Generate Keys
Reference:
- http://www.apache.org/dev/openpgp.html#generate-key
- http://www.apache.org/dev/release-signing.html#key-id
Generate RSA keys, 4096 bits
Specify RSA:
Code Block |
---|
bash-3.2$ gpg --gen-key gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 |
Specify key length as 4096 bits:
Code Block |
---|
RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits |
Specify duration of key validity:
Code Block |
---|
Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y |
Enter your name, email and comment:
- You should use your apache.org email
- the comment should be "CODE SIGNING KEY"
Code Block |
---|
You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>" Real name: Xxx Xxxxxxxxx Email address: <xxx@apache.org> Comment: CODE SIGNING KEY You selected this USER-ID: "Xxx Xxxxxxxxx (CODE SIGNING KEY) <xxx@apache.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O |
Provide a passphrase:
Code Block |
---|
You need a Passphrase to protect your secret key. Enter passphrase: Repeat passphrase: |
The keys are generated.
Code Block |
---|
We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. ...+++++ .........................+++++ We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. ....+++++ ...+++++ gpg: key nnnnnnnn marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/nnnnnnnn yyyy-mm-dd Key fingerprint = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx uid Xxx Xxxxxx <xxx@apache.org> sub 4096R/kkkkkkkk yyyy-mm-dd |
The public key with id nnnnnnnn is stored in ~/.gnupg/pubring.pgp.
- on Windows 7, this is in c:/Users/xxx/AppData/Roaming/gnupg/pubring.pgp
Code Block ./gpg --list-keys --fingerprint
The key Id is the one true way to identify the key, and is also the last 8 digits of the fingerprint.
The corresponding secret key for id nnnnnnnn is stored in ~/.gnupg/secring.pgp.
- on Windows 7, this is in c:/Users/xxx/AppData/Roaming/gnupg/secring.pgp
Code Block |
---|
./gpg --list-secret-keys |
There are also a couple of other files here, including trustdb.gpg and random_seed.
These files are all important, so backup outside of your computer.
Check key has been correctly generated
Code Block |
---|
./gpg --edit-key nnnnnnnn gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 4096R/nnnnnnnn created: yyyy-mm-dd expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/kkkkkkkk created: yyyy-mm-dd expires: never usage: E [ultimate] (1). Xxx Xxxxxx (CODE SIGNING KEY) <xxx@apache.org> gpg> |
Use the 'showpref' subcommand to list details:
Code Block |
---|
gpg> showpref [ultimate] (1). Xxx Xxxxxxxx (CODE SIGNING KEY) <xxx@apache.org> Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify gpg> |
The Digest line should list SHA-512 first and SHA-1 last.
Use 'quit' to return to the command prompt.
Code Block |
---|
gpg> quit |
Generate Revocation Certifications
Reference:
It's good practice to generate a number of revocation certificates so that the key can be revoked if it happens to be compromised.
First, generate a "no reason specified" key:
Code Block |
---|
gpg --output revoke-nnnnnnnn-0.asc --armor --gen-revoke nnnnnnnn sec 4096R/nnnnnnnn yyyy-mm-dd Xxx Xxxxxxx (CODE SIGNING KEY) <xx@apache.org> Create a revocation certificate for this key? (y/N) Y |
Select "no reason specified"
Code Block |
---|
Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 0 |
Provide a comment:
Code Block |
---|
Enter an optional description; end it with an empty line: > Generic certificate to revoke key, generated at time of key creation. > Reason for revocation: No reason specified Generic certificate to revoke key, generated at time of key creation. Is this okay? (y/N) |
Provide passphrase:
Code Block |
---|
You need a passphrase to unlock the secret key for user: "Xxx Xxxxxxx (CODE SIGNING KEY) <xxx@apache.org>" 4096-bit RSA key, ID nnnnnnnn, created yyyy-mm-dd Enter passphrase: |
The file 'revoke-nnnnnnnn-0.asc' should be created:
Code Block |
---|
Revocation certificate created. Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable. But have some caution: The print system of your machine might store the data and make it available to others! |
Then, backup this file.
Now repeat the process to create two further revocation certificates:
- gpg --output revoke-nnnnnnnn-1.asc --armor --gen-revoke nnnnnnnn
- specify reason as "1 = Key has been compromised"
- gpg --output revoke-nnnnnnnn-3.asc --armor --gen-revoke nnnnnnnn
- specify reason as "3 = Key is no longer used"
Backup these files also.
nb: if you find that you need to revoke your certificate, this blog post explains how
Publish Public Key to Key server
Reference:
- http://www.apache.org/dev/release-signing.html#keyserver-upload
- http://maven.apache.org/developers/release/pmc-gpg-keys.html
It is also necessary to publish your key to a public key server, eg MIT (http://pgp.mit.edu). Apparently the public key servers synchronize with each other, so this should be sufficient.
So, browse to http://pgp.mit.edu/ and paste in the armored representation of your key (ie as generated by gpg --armor --export nnnnnnnn) into the field:
Code Block |
---|
gpg --send-keys --keyserver pgp.mit.edu nnnnnnnn |
where nnnnnnnn is the key Id
Confirm the key has been added by browsing to submitting the following URL http://pgp.mit.edu:11371/pks/lookup?search=0xnnnnnnnnn&op=vindex
where nnnnnnnn is the key Id
Save Public Key to Apache Repositories
Reference:
.pgpkey
Update the .pgpkey file in your home directory on people.apache.org with an ASCII armored public key export of the key:
Code Block |
---|
gpg --ascii --export nnnnnnnn >> .pgpkey |
scp 'd the file into your home directory on people.apache.org.
Standard URL
Copy the same file to be available under a standard URL:
Code Block |
---|
gpg --ascii --export nnnnnnnn >> nnnnnnnnn.asc |
scp this file into ~/public_html on people.apache.org (so that it is accessible via http://people.apache.org/~username/nnnnnnnn.asc).
FOAF
First, check out the committers/info directory:
Code Block |
---|
svn co https://svn.apache.org/repos/private/committers/info |
Now, obtain the fingerprint of your key:
Code Block |
---|
gpg --fingerprint nnnnnnnn |
Go to Apache FOAF-a-matic to generate the FOAF file text (we copy this text out in a minute):
- enter ASF ID
- enter First name, Last name
- for PGP key fingerprints, add Key
- paste in the key id
- paste in the fingerprint
- press "Create"
In the box below, you should have a FOAF file, something like:
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:pm="http://www.web-semantics.org/ns/pm#" xmlns:wot="http://xmlns.com/wot/0.1/" xmlns:rss="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ical="http://www.w3.org/2002/12/cal/ical#" xmlns:doap="http://usefulinc.com/ns/doap#"> <foaf:Person rdf:ID="danhaywood"> <foaf:name>Xxx Xxxxxxxx</foaf:name> <foaf:givenname>Xxx</foaf:givenname> <foaf:family_name>Xxxxxxxx</foaf:family_name> <wot:hasKey> <wot:PubKey> <wot:fingerprint>nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn</wot:fingerprint> <wot:hex_id>nnnnnnnn</wot:hex_id> </wot:PubKey> </wot:hasKey> </foaf:Person> </rdf:RDF> |
(If you are creating the FOAF file for the first time, you may want to add additional details).
From this, copy out the wot:key, and paste into your FDF file in committers/info:
Code Block |
---|
<wot:hasKey> <wot:PubKey> <wot:fingerprint>nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn</wot:fingerprint> <wot:hex_id>nnnnnnnn</wot:hex_id> </wot:PubKey> </wot:hasKey> |
Then, manually add in a <wot:pubkeyAddress> element within <wot:PubKey>:
Code Block |
---|
<wot:hasKey> <wot:PubKey> <wot:fingerprint>nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn nnnn</wot:fingerprint> <wot:hex_id>nnnnnnnn</wot:hex_id> <wot:pubkeyAddress rdf:resource="http://people.apache.org/~username/nnnnnnnn.asc/> </wot:PubKey> </wot:hasKey> |
ie, referencing your publically exported public key
Finally, commit your changes.
Save Public Key to Apache Isis' SVN Repo
Reference:
- http://maven.apache.org/developers/release/pmc-gpg-keys.html as reference...
- nb: this is specific for Maven developers
- for us, we should edit the Isis KEYS file.
The key Id and "armored" (ie ASCII) representation of the public key should be saved to Isis' Keys file https://svn.apache.org/repo/asf/incubator/isis/KEYS
The instructions are at the top of the file; if using gpg then:
Code Block |
---|
gpg --list-sigs nnnnnnnn >>KEYS gpg --armor --export nnnnnnnn >>KEYS |
where nnnnnnnn is the ID of the key
Then commit.
Attend a Key Signing Party to get public key added to the Apache "web of trust"
Although your public key can be used to sign releases ReleaseProcess, this is discouraged until you've had your public key counter-signed by others in the Apache Community.
This is usually done via a Key signing party, eg as described here: http://wiki.apache.org/apachecon/PgpKeySigning.