Notes on implementing your own KeyStore

Notes on implementing your own keyStore

Before starting to write your own KeyStore, consider the keyStore implementations that are available from RIM. RIM provides a variety of flexible and powerful keyStore solutions that allow you to develop an effective custom solution. That being said, the importance of third party development is paramount. This tutorial provides some hints and tips on how to implement your own keystore.

If you have any questions or concerns, please contact Crypto SDK Feedback.

Implementing your own KeyStore class

The set method is the work horse of the keyStore class since it is used to add elements to the keyStore. The KeyStore interface contains a number of instances When developing your own keystore it is a good idea to create one private set method that allows for all of the possible parameters. Then, each public set method will simply call the private set method. This way, you can implement the main method only once and call it numerous times with a subset of the actual parameters.

Once you have determined how to enter data into the keyStore, you need to consider how the data will be accessed. This is accomplished using the KeyStoreIndex class. The KeyStoreIndex class is added to the KeyStore along with the data elements. See Indexing the KeyStore for a tutorial on using the KeyStore index.

Tickets provide time sensitive credentials for a user. A valid ticket allows the user associated with the ticket to perform bulk operations in the KeyStore or KeyStoreData without the need to request the password each and every time.

The RIM Crypto API contains three types of tickets:

Tickets provide a type of hierarchy. For example, when requesting access to the keyStore (using the getTicket() method) it will ask the KeyStorePassword for a ticket. This will return a ticket (there are different methods provided in KeyStorePassword depending on what you are requesting so that the prompt shows exactly what you are trying to get permission to) for the KeyStorePassword class. The KeyStore ticket is then wrapped around this newly obtained ticket. That way, you can control whether or not people who have received a ticket for the KeyStorePassword can actually access your keyStore or not. This is a achieved by wrapping the ticket around the KeyStorePassword ticket and then storing a reference to the keyStore in that ticket. On checking against the ticket during access you simply check to see if the keystore is the same. If so, allow them access. If not, prompt them for another ticket or simply prompt for the password to make sure they can access your keystore.

Also of note are the listeners. Listeners allow people to find out when records have been added or removed from the keystore. This is useful, for example, for applications that add address book entries given certificates in your keystore.

Implementing your own KeyStoreData class

The KeyStoreData class contains the actual keying information and acts as a general repository for other data that might be associated with that key. As you can see from the javadocs there are some very obvious methods that return the certificate, private key, public key, etc.

There are some things to take into consideration when implementing your own KeyStoreData class. First of all, the private key should be encrypted when stored in the KeyStore. The key should be encrypted in the KeyStoreData constructor and decrypted in the getPrivateKey() method. This code can be found in KeyStorePasswordManager. It provides methods for encrypting and decrypting that can be simply called.

The KeyStoreData class should also be immutable, or, without change. That means that there are no modifiers provided for the class and that the class can not be modified in any way, by any user after the class has been created. Another important consideration is the concept of AssociatedData. AssociatedData allows users to place things into the KeyStore record that are not necessarily known at design time. More importantly it allows people to place record-specific data in the keyStore which they can then access by searching for the specific AssociatedData using an index.

For more information on using indexes, see Using the KeyStore index.

ChangePassword

This topic is one that is rather difficult in the keystore and it deserves its own section.

In order to change the password on the device we need to decrypt and re-encrypt all of the things (note that I do not specify only keys since there may be other things in your keystore which are encrypted) that rely on the password based encryption provided by the KeyStorePassword class.

The following chain of events will cause a change password.

  1. The user decides to change their password.
  2. This causes the KeyStorePassword.changePassword() method to be called.
    It prompts for the old password and new password.
  3. If that succeeds (they know the old password) then the KeyStoreManager will be informed of a change password event.
  4. It goes through its list of keystores (which is why you are strongly suggested to register your keystore with the KeyStoreManager) and tells all of them that there is a changePassword operation occuring now.
  5. All of the KeyStores loop through the elements in the KeyStore and tell each of the KeyStoreData records to change the password regarding any of the sensitive material in the KeyStore.
  6. The KeyStoreData objects call the KeyStorePassword.changePassword( ... ) method that will decrypt and re-encrypt any encrypted objects with the new password.

As you can see it is imperative that you maintain involvement in this process or else you run the risk of losing access to the keys stored in the KeyStore.

General Notes

There are two major types of key stores: Non-persistable and persistable.

It is highly suggested that you register your KeyStore with the KeyStoreManager when your KeyStore is created. If not, you run the risk of losing access to the encrypted objects stored inside your KeyStoreData objects. See the ChangePassword section for more information.

Developers of KeyStores should respect the security level setting. High security means that the user will always be prompted (except in the case of tickets) for the password. Low security means that the user will never be prompted. Note that prompting refers only to accessing the private key or encrypted KeyStoreData contents. A KeyStore should *always* prompt when adding and removing records from the KeyStore.