Archive for July, 2011

NJC: Day 8

Tuesday, July 5th, 2011

This was the last day before a 3 day weekend and as is customary around these parts, not many people came in and the ones who did left early. I didn’t really achieve anything worth talking about, just researched some more ideas for my next few proposals.

Specifically, I looked at AWS documentation about Elastic Block Storage, I looked at new Bacula features, I looked at Chef and specifically Knife.

Then I went to drink with co-workers, former and present.

NJC: Day 7

Tuesday, July 5th, 2011

This day was my first day working from home at the new job, something I negotiated to get for myself. One day a week, I work from home. Unfortunately as today was the second attempt at releasing, and things took about as long as they do the first time you do something operational, this was a 14 hour day of work for me. At least I didn’t need pants to do it.

Our proposed deploy process didn’t survive its encounter with the actual server environment but that doesn’t come as a surprise; it’s still very raw and will be refined a lot, soon.

NJC: Day 6

Tuesday, July 5th, 2011

I had hoped to WFH on this day but we were on track to release something important so I came in to the office.

First order of the day was sharing the Windows virtualbox file with my co-workers so they could fire up IE and validate things work in that browser, too.

That led in to a playdate for something on the web, followed by a process meeting about deployment which turned into a pair programming / code review session using a laptop jacked into a projector. I recommend this if you have more than one developer in a meeting, use the projector to display their code as you talk about related topics.

NJC: Day 5

Tuesday, July 5th, 2011

At this point, I’ve been doing the new job for a week and routines are forming.

I started the morning using a company card to pay for SSL certificates and then spent the rest of the day making them work with JBoss and Apache. The Apache part was the easy part, as the certificates were already in the correct form. Using Subject Alternate Names with the wildcard certificate meant that I could secure a variety of systems using it, with varying depths of subdomains.

But JBoss was a problem and here’s why. All the examples I could find on the web gloss over using a real certificate. They assume that it’s good enough to show you the syntax for a self-signed certificate you generate using keytool. In my case, it wasn’t. The process for using a CA-signed certificate turned out to be very different.

So here’s the key thing to know if you try this craziness. Keytool is a vicious betrayer of hope and will quietly do the wrong thing if you don’t fully grok what it does/wants. You need to turn to something else, in this case, openssl. This command will take your private key and put it in a form keytool can use:

openssl pkcs8 -topk8 -nocrypt -in /your/private/ssl.key -inform PEM -out /someplace/safe/key.der -outform DER

Then this command will turn your SSL certificate into something keytool can use:

openssl x509 -in /your/private/ssl.crt -inform PEM -out /someplace/safe/cert.der -outform DER

Then you run those files through a program someone else wrote. Not entirely excited about it but I read the source and it didn’t seem too dire.

 

import java.security.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.security.spec.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Collection;
import java.util.Iterator;

/**
* ImportKey.java
*
*

This class imports a key and a certificate into a keystore
* ($home/keystore.ImportKey). If the keystore is
* already present, it is simply deleted. Both the key and the
* certificate file must be in DER-format. The key must be
* encoded with PKCS#8-format. The certificate must be
* encoded in X.509-format.

*
*

Key format:

*

openssl pkcs8 -topk8 -nocrypt -in YOUR.KEY -out YOUR.KEY.der
* -outform der

*

Format of the certificate:

*

openssl x509 -in YOUR.CERT -out YOUR.CERT.der -outform
* der

*

Import key and certificate:

*

java comu.ImportKey YOUR.KEY.der YOUR.CERT.der
*
*

Caution: the old keystore.ImportKey-file is
* deleted and replaced with a keystore only containing YOUR.KEY
* and YOUR.CERT. The keystore and the key has no password;
* they can be set by the keytool -keypasswd-command for setting
* the key password, and the keytool -storepasswd-command to set
* the keystore password.
*

The key and the certificate is stored under the alias
* importkey; to change this, use keytool -keyclone.
*
* Created: Fri Apr 13 18:15:07 2001
* Updated: Fri Apr 19 11:03:00 2002
*
* @author Joachim Karrer, Jens Carlberg
* @version 1.1
**/
public class ImportKey {

/**
*

Creates an InputStream from a file, and fills it with the complete
* file. Thus, available() on the returned InputStream will return the
* full number of bytes the file contains

* @param fname The filename
* @return The filled InputStream
* @exception IOException, if the Streams couldn’t be created.
**/
private static InputStream fullStream ( String fname ) throws IOException {
FileInputStream fis = new FileInputStream(fname);
DataInputStream dis = new DataInputStream(fis);
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return bais;
}

/**
*

Takes two file names for a key and the certificate for the key,
* and imports those into a keystore. Optionally it takes an alias
* for the key.
*

The first argument is the filename for the key. The key should be
* in PKCS8-format.
*

The second argument is the filename for the certificate for the key.
*

If a third argument is given it is used as the alias. If missing,
* the key is imported with the alias importkey
*

The name of the keystore file can be controlled by setting
* the keystore property (java -Dkeystore=mykeystore). If no name
* is given, the file is named keystore.ImportKey
* and placed in your home directory.
* @param args [0] Name of the key file, [1] Name of the certificate file
* [2] Alias for the key.
**/
public static void main ( String args[]) {

// change this if you want another password by default
String keypass = “importkey”;

// change this if you want another alias by default
String defaultalias = “importkey”;

// change this if you want another keystorefile by default
String keystorename = System.getProperty(“keystore”);

if (keystorename == null)
keystorename = System.getProperty(“user.home”)+
System.getProperty(“file.separator”)+
“keystore.ImportKey”; // especially this ;-)

// parsing command line input
String keyfile = “”;
String certfile = “”;
if (args.length < 2 || args.length>3) {
System.out.println(“Usage: java comu.ImportKey keyfile certfile [alias]“);
System.exit(0);
} else {
keyfile = args[0];
certfile = args[1];
if (args.length>2)
defaultalias = args[2];
}

try {
// initializing and clearing keystore
KeyStore ks = KeyStore.getInstance(“JKS”, “SUN”);
ks.load( null , keypass.toCharArray());
System.out.println(“Using keystore-file : “+keystorename);
ks.store(new FileOutputStream ( keystorename ),
keypass.toCharArray());
ks.load(new FileInputStream ( keystorename ),
keypass.toCharArray());

// loading Key
InputStream fl = fullStream (keyfile);
byte[] key = new byte[fl.available()];
KeyFactory kf = KeyFactory.getInstance(“RSA”);
fl.read ( key, 0, fl.available() );
fl.close();
PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
PrivateKey ff = kf.generatePrivate (keysp);

// loading CertificateChain
CertificateFactory cf = CertificateFactory.getInstance(“X.509″);
InputStream certstream = fullStream (certfile);

Collection c = cf.generateCertificates(certstream) ;
Certificate[] certs = new Certificate[c.toArray().length];

if (c.size() == 1) {
certstream = fullStream (certfile);
System.out.println(“One certificate, no chain.”);
Certificate cert = cf.generateCertificate(certstream) ;
certs[0] = cert;
} else {
System.out.println(“Certificate chain length: “+c.size());
certs = (Certificate[])c.toArray();
}

// storing keystore
ks.setKeyEntry(defaultalias, ff,
keypass.toCharArray(),
certs );
System.out.println (“Key and certificate stored.”);
System.out.println (“Alias:”+defaultalias+” Password:”+keypass);
ks.store(new FileOutputStream ( keystorename ),
keypass.toCharArray());
} catch (Exception ex) {
ex.printStackTrace();
}
}

}// KeyStore

As found at Agent Bob.

Then the last remaining tricky bit is getting it out of the keystore this program creates and in to the one you intend to use. That could be as easy as just pointing jboss at this keystore but I made it harder and did this to copy from one keystore into another.

keytool -importkeystore -srckeystore /the/keystore/made/by/importkey.java/keystore.ImportKey -srcstorepass importkey -destkeystore /the/one/you/use/jboss.keystore -deststorepass somethingclever -alias importkey -destalias production -srckeypass importkey -destkeypass somethingclever

Then I edited /usr/local/java/jboss-VERSION/server/default/deploy/jboss-web.deployer/server.xml to modify the 8443 SSL connector they ship to do this:

    &lt;Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
        address="${jboss.bind.address}"
                keystoreFile="/usr/local/java/jboss-VERSION/server/default/conf/ark.keystore"
                keyAlias="production"
                keystorePass="somethingclever"
               clientAuth="false" sslProtocol="TLS" /&gt;

During this day I also got my hands on the 12G file which is a Windows virtualbox image in use by my nearest IT group. This doesn’t reveal some deep latent desire to be using Windows after all this time, this was me attempting to solve an issue for the people around me without taking on administration of Windows systems. It very nearly worked.

ETA: the key has its own password separate from the keystore. You can change it when you import that key into the new keystore, so I updated the command to reflect that.

NJC: Day 4

Tuesday, July 5th, 2011

This was my first Monday in the new office and so the focus was on all the orientation activity they only do on Mondays. I got my picture taken for a security badge (taken with a smart phone) and spent the day following up on orientation information as well as researching SSL certificate options before proposing that the company pay for a wildcard SSL certificate for use in production environments and that we self-sign a different wildcard SSL certificate for use in development and testing environments.

Then I dug in to the documentation for how to use an SSL certificate with jboss. That was more opaque than it needed to be and I’ll probably explain what I did in the next post.

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...