Creating GENI certificates and credentials using OMNI/gcf tool for use with pubsub

Generating certificates, keys and credentials

We have made minor modifications to the GPO OMNI/gcf toolkit to generate certificates and credentials for XMPP servers and XMPP clients. These modifications will be rolled into the next version of gcf toolkit distribution.

Assuming gcf is unzipped and untarred in /home/orca/gcf-xmpp/gcf , follow these steps

Edit gcf_config

cd /home/orca/gcf-xmpp/gcf
vi gcf_config

Under [global] section, change

base_name=geni//gpo//gcf

to

base_name=geni//renci

Under [aggregate_manager] section, change

name=am1 
keyfile=~/.gcf/am-key.pem
certfile=~/.gcf/am-cert.pem

to

name=xmpp1
keyfile=~/.gcf/xmpp-key.pem
certfile=~/.gcf/xmpp-cert.pem

The value of 'name' is the name of your aggregate manager. This gets appended to base_name. The value of 'keyfile' is where your xmpp server key file would be generated. The value of 'certfile' is where your xmpp server certificate file would be generated.

Edit gen-certs.py

cd /home/orca/gcf-xmpp/gcf
vi src/gen-certs.py

Change

AM_CERT_SUBJ = 'am' 

to

AM_CERT_SUBJ = 'xmpp'

This is the subject name of your xmpp server, used in the URN.

Generate certificates

cd /home/orca/gcf-xmpp/gcf 
python26 src/gen-certs.py -u user1

This will generate all the three types of certificates - a certificate-keypair for a representative GENI clearing house (CH cert), a certificate-keypair for the XMPP server and a certificate-keypair for user with username 'user1' .

If you already have an existing CH certificate, run the following command to generate another user certificate for user with username 'user2' .

python26 src/gen-certs.py --notAll --exp -u user2

Certificates will be saved under ~/.gcf/ directory.

Generating credentials

To generate credentials for xmpp node namespaces '/orca' and '/orca/sm',

cd ~/.gcf
python26 /home/orca/gcf-xmpp/gcf/src/xmppcred.py xmpp-key.pem xmpp-cert.pem user1-cert.pem ch-cert.pem orca orca/sm > user1-cred.xml

You can pass as many xmpp node namespaces as you wish as arguments. The above will give pub/sub credentials to user with certificate user1-cert.pem on xmpp pubsub nodes that start with '/orca' and '/orca/sm' . You have to pass the xmpp server cert, xmpp server key and CH certificate as arguments. These have been generated in the ~/.gcf directory in the "Generating certificates" step.

Uploading credentials to credentials store for use by Opnefire

1. Find the CN in the user certificate and create a credential file with the name with prefix same as the CN.

openssl x509 -in user1-cert.pem -text

Find the CN of the user certificate, say for example, the CN is b8e6e0b2-7f6c-4583-aa0c-6681dc9356bd . Copy user1-cred.xml to a a file with name <CN>.xml

cp user1-cred.xml b8e6e0b2-7f6c-4583-aa0c-6681dc9356bd.xml

2. Upload the credential file to credential store from where the Openfire XMPP server would pull the credentials from. This server url has to be known to the Openfire server.

scp b8e6e0b2-7f6c-4583-aa0c-6681dc9356bd.xml geni-orca@geni-images.renci.org:/images/public/credentials/.

 http://geni-images.renci.org:/images/public/credentials/ is the base url known to geni-imf-dev.renci.org and geni-imf-xmpp.renci.org - our Openfire servers.

Configuring Openfire server to accept these certificates and credentials

Modify Openfire client truststore

1. Migrate the CH cert (CA cert in our case) to geni-imf-xmpp.renci.org into openfire's client truststore.

On the machine with the gcf tool, convert ch-cert.pem to binary format ch-cert.der .

cd ~/.gcf
openssl x509 -in ch-cert.pem -inform PEM -out ch-cert.der -outform DER

2. Copy ch-cert.der to machine running Openfire server. We copied ch-cert.der to anirban@…:/home/anirban/certs/ca-certs/.

3. Use keytool to insert this CH certificate into the client truststore.

keytool -importcert -keystore /opt/openfire/resources/security/geni-trusted.jks -alias GENITestCHRenci -file /home/anirban/certs/ca-certs/ch-cert.der -trustcacerts

Choose an alias, "GENITestCHRenci", in our example. Here, our client truststore is /opt/openfire/resources/security/geni-trusted.jks

** NOTE: Generally, the default client truststore is /opt/openfire/resources/security/client.truststore and that value can be changed on the Openfire web portal.

Add credential properties on the Openfire web portal

Go to the Openfire web portal. Click Server Manager -> System Properties . Add the following properties to specify that credential verification is turned on, and if it is turned on, to specify the base url where credentials are stored. Change the URL to the location where the client credentials are stored.

xmpp.pubsub.credentials.verify=true
xmpp.pubsub.credentials.url=http://geni-images.renci.org/images/credentials/

Notes for users/clients trying to use the certificates and credentials as generated above

Creating a user JKS (Java keystore file) from the user cert-key pair

Sometimes clients need a java keystore containing user certificates and keys. The steps to generate a jks file are

1. Create a .p12 file (PKCS12 format) using openssl from your certificate and key

openssl pkcs12 -export -in user1-cert.pem -inkey user1-key.pem -out user1-gcf-encrypted.p12

This will ask for a password. Remember it. Need to give it in 4th step when using Portecle to generate the JKS file.

2. Use Portecle:  http://portecle.sourceforge.net/ Click Launch.

  • Create a new keystore of type JKS
  • Click on "Import Key Pair"
  • Locate the .p12 file (user1-gcf-encrypted.p12 in the example)
  • Enter the password protecting the .p12 file
  • Import the key and certificate, but change the key alias to something simpler than a GUID
  • Enter and confirm a new key password (I usually give the same password as the one protecting .p12 file)
  • Click on "Save Keystore"
  • Enter and confirm the new keystore password (use same as the key password)

Save jks file as user1-gcf-encrypted.jks . Point clients to this file, as required.

Use with PSM toolkit

Add the following properties in measurement.properties and/or subscriber.properties in $IMF_HOME so that the 'Simple' publisher and 'SimpleSubscriber?' subscriber can use certificates to log in.

IMF.pubsub.usecertificate=true
IMF.pubsub.login=<JID>  --- the CN in the client certificate
IMF.pubsub.password=<password protecting the JKS file as above>
IMF.pubsub.keystorepath=<path to java keystore with your cert-keypair>  -- for eg. /Users/anirban/Misc/tmp/testJKS/user1-gcf-encrypted.jks
IMF.pubsub.keystoretype=jks
IMF.pubsub.truststorepath=<path to java keystore with your cert-keypair>  -- for eg. /Users/anirban/Misc/tmp/testJKS/user1-gcf-encrypted.jks
IMF.pubsub.root=<pubsub node you want to pubsub to>  -- any client with pubsub credentials to the value of IMF.pubsub.root would be able to pubsub to any node that starts with the value of IMF.pubsub.root

For example, if the IMF.pubsub.root is 'Repository-psm', and user1 has credentials to publish to '/Repository-psm', user1 would be able to publish to '/Repository-psm/foo1', '/Repository-psm/foo1/foo2' and so on.

Use with ORCA pubsub client

Download the ORCA pubsubclient from  http://geni-images.renci.org/images/credentials/pubsubclient.zip and unzip it.

Edit subscriber.properties as follows

IMF.pubsub.server=<Openfire server url>:5222
IMF.pubsub.usecertificate=true
IMF.pubsub.login=<JID>  --- the CN in the client certificate
IMF.pubsub.password=<password protecting the JKS file as above>
IMF.pubsub.keystorepath=<path to java keystore with your cert-keypair>  -- for eg. /Users/anirban/Misc/tmp/testJKS/user1-gcf-encrypted.jks
IMF.pubsub.keystoretype=jks
IMF.pubsub.truststorepath=<path to java keystore with your cert-keypair>  -- for eg. /Users/anirban/Misc/tmp/testJKS/user1-gcf-encrypted.jks
IMF.pubsub.root=<pubsub node you want to pubsub to>  -- any client with pubsub credentials to the value of IMF.pubsub.root would be able to pubsub to any node that starts with the value of IMF.pubsub.root

For example, if the IMF.pubsub.root is 'orca', and user1 has credentials to subscribe to '/orca', user1 would be able to subscribe to '/orca/sm1', and so on. The prerequisite is that user1's credential stored at the credential url must have privileges for /orca.

Compile the pubsubclient.

$ mvn clean install assembly:assembly

If, during the above build, maven reports problems with unavailable jars (jms, mail, jmxtools, jmxri, smack-pubsub, smackx-pubsub) they can be installed manually as follows:

$ mvn install:install-file -DgroupId=org.jivesoftware.smackx -DartifactId=smackx-pubsub -Dversion=3.1.0 -Dpackaging=jar -Dfile=lib/smackx.jar 
$ mvn install:install-file -DgroupId=org.jivesoftware.smack -DartifactId=smack-pubsub -Dversion=3.1.0 -Dpackaging=jar -Dfile=lib/smack.jar 
$ mvn install:install-file -DgroupId=javax.mail -DartifactId=mail -Dversion=1.4 -Dpackaging=jar -Dfile=lib/mail-1.4.jar 
$ mvn install:install-file -DgroupId=javax.jms -DartifactId=jms -Dversion=1.1 -Dpackaging=jar -Dfile=lib/jms.jar 
$ mvn install:install-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=lib/jmxtools.jar 
$ mvn install:install-file -DgroupId=com.sun.jmx -DartifactId=jmxri -Dversion=1.2.1 -Dpackaging=jar -Dfile=lib/jmxri.jar 

Repeat the build attempt:

$ mvn clean install assembly:assembly

Run the client

$ java -cp .:target/pubsubclient-1.0-SNAPSHOT-jar-with-dependencies.jar org.renci.pubsubclient.SimpleSubscriber