The Legion of the Bouncy Castle – Listing Public Key Certifications

Posted on Updated on

Instead of calling this post Part 6, I’ve decided to just give them nice and descriptive names from now on.

When managing your PGP Keys you often need to know who you trust and who you do not trust. All we need is the public key file (ASCII armored or binary). I have nested the operation in 3 different methods, mainly done for readability.

public void listPublicKeyCertifications() {
	String keysDir = System.getProperty("user.dir")+File.separator+"src/george/crypto/pgp/keys";
	File publicKeyFile = new File(keysDir+File.separator+"MrBilly.asc");
	
	try {
		System.out.println("The public key was certified by: ");	
		List<String> keyIds = listCertifications(publicKeyFile);
		for (String keyId : keyIds) {
			System.out.println("\t"+keyId);
		}
	}
	catch(Exception ex) {
		ex.printStackTrace();
	}
}

public static final List<String> listCertifications(File publicKeyFile) throws IOException {
	FileInputStream keyInputStream = new FileInputStream(publicKeyFile);
	List<String> keyIds = getCertifications(keyInputStream);
	return keyIds;
}

private static final List<String> getCertifications(InputStream input) throws IOException
{
	List<String> keyIds = new ArrayList<String>();
	
	PGPPublicKeyRing pgpPubRing = new PGPPublicKeyRing(PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());
	PGPPublicKey pubKey = pgpPubRing.getPublicKey();
	
	@SuppressWarnings("unchecked")
	Iterator<PGPSignature> sigIter = pubKey.getSignatures();
	while(sigIter.hasNext()) {
		PGPSignature pgpSig = sigIter.next();
		long keyId = pgpSig.getKeyID();
		keyIds.add(Long.toHexString(keyId).toUpperCase());
	}
	
	return keyIds;
}

Method listPublicKeyCertifications() is the front facing method which reads the public key file and sends it to the listCertifications(File).

The listCertifications(File) requests a list of certifications from the getCertifications(InputStream) method while converting the File to an InputStream. I always prefer that the user send a File and let the underlying subsystems do all the I/O stuff 🙂

The getCertifications(InputStream) method will decode the inputstream and generate a PGPPublicKeyRing object to represent the file. Then we extract the Public Key from it and iterate through its list of PGPSignatures. From there we simply just add all the KeyIDs in a list (converting them to Hex for convenience) and sending it back up.

Now the reason why we would want to do this is when establishing trust among your peers who gave you their keys (Trust in a key’s owner). Seeing who you trust signed the unknown public key automatically gives you an idea of how much you trust that key. Lets say you are Alice, or rather Alice Cooper because you know he’s cool, and lets say you have a friend called Bob that you really trust and know him for a long time. Bob gives you his Public Key and you set the trust level to Full. Then you get a message from Charlie (whom you met once but don’t know him that well) encrypted with Charlie’s private key and your public key (most likely given to him by Bob, cos Bob and Charlie are best buddies). So you list all the keys that have signed Charlie’s public key and see that Bob has signed Charlie’s key. So because someone you trust fully has signed someone else’s key, it gives you some confidence that you can also trust Charlie’s key (not fully of course but marginally) so you import Charlie’s public key to your key store and decrypt the message and have a good laugh at the joke they sent you.

Setting trust levels on Bouncy Castle is going to be my next task and I’ll share it. It’s going to be a bit challenging due to posts like these http://bouncy-castle.1462172.n4.nabble.com/Need-help-understanding-Trust-Data-Bytes-td1466148.html

Happy Coding!

Advertisements

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s