The supporting cast: LockSmith, LockSet, LockStore and LockHolder
The previous examples don’t explain where you get your Locks and Keys from. Obviously, you get them from a LockSmith.
LockSmith
LockSmith has one static method: createLockSet(File keyDirectory, String username, char[] passphrase), which returns a LockSet. It takes three arguments: a File object, which is the directory used to store the key files; a String, which is the username, and a passphrase – which is used to protect the resulting Key.
LockSet
A LockSet is also what it says on the tin: it is a set comprising a Lock and its matching Key. It has two public methods: getLock(), which returns the Lock, and getKey(), which returns the Key.
LockStore
Obviously, once you’ve created your Locks and Keys, you need to store them somewhere. What you do with Locks and Keys is different. Keys are sensitive and should only be available to the keyholder, so any particular user should only be able to access his or her own Keys. There is no valid use case for any user, or sysadmin, being able to access any other user’s Keys. In regular use, Key objects are created from OpenPGP key material, which is stored as a block of text. It is good practice to store this material only on removable media, such as a USB stick kept with the user. Remember above, when we passed a File argument to the LockSmith.createLockSet(file, username, passphrase) method? That file should really be the path to the usb stick. It isn’t always practical to adopt the removable-media approach – particularly if you are doing mostly server-side programming – so you should think carefully about how you would provide your users with the equivalent level of security. On the other hand, users will often be able to access many different Lock objects. The LockStore interface provides an easy method for accessing these objects, and Enigma provides a basic implementation of this interface in the EnigmaStore class. This stores locks in the filesystem in the form of an OpenPGP keyring file. Larger applications will often find it better to provide a custom implementation of LockStore using a jdbc database to store the lock material.
Adding a Lock to a Store
This is easy: just call the LockStore’s addLock(Lock lock) method, passing the Lock you want to add as its only argument.
Retrieving a Lock from a store
LockStore has methods to retrieve Locks by their PGP KeyID (a long), or by their user id , which in PGP is usually an email address:
getLock(long keyID);
and
getLock(String userID).
It also has a no-args getLock() method, which returns a single Lock object containing a concatenation of all the Locks in the store. However, you should note that neither the keyID, nor the userID are necessarily unique. It is usually sufficient to rely on the keyID, but given the theoretical possibility of keyID collisions best practice would involve an additional sanity-check on the retrieved Lock to ensure that it is, indeed, the Lock sought.
Removing a Lock from a LockStore
You will sometimes want to remove a Lock from a LockStore, as, for example, when the LockStore contains the Locks of existing customers, and someone ceases to be a customer. The method to do this is removeLock(Lock lock). Note that the lock to be removed is supplied as an argument. Given the theoretical risk of keyID collisions, good practice on lock removal is as follows:
Lock lock = lockStore.getLock(keyID);
if (sanityCheck(lock)){
lockStore.removeLock(lock);
}
It’s up to you to write a sanityCheck(Lock lock) method to suit your application.
LockHolder
LockHolder is an interface which you can choose to implement in your application. If you do, you must implement its only method, getLock();





