[Opendnssec-user] Creating keys on SoftHSM with Java

Adam Knight adam at aotea.co.nz
Wed Apr 13 23:15:22 UTC 2011


Hi,

I am trying to write keys into SoftHSM using Java but have come across a little problem.  It seems this is a common issue when using PKCS11 key stores with Java (Discussed in depth with a different HSM here: http://comments.gmane.org/gmane.comp.java.openjdk.security.devel/1772) but unfortunately since SoftHSM doesn't implement C_CopyObject, I'm a little stuck.

Java's Keystore API allows you to access PKCS11 keystores just as you would a Java Key Store (JKS).  To create a RSA key on a JKS or PKCS11 store, you follow the same steps:

1) Create a Key pair
2) Put the key in the key store
3) Save the key store

When you use JKS, creating the key makes a in-memory object, which has no connection to the key store.  When you add the key to the store in step 2, that's the first time the key store and key are associated.  Java refers to keys by Aliases, so when you add the key to the store you specify an Alias, that you will use from now on.  PKCS11 keys are handled a little differently.

When you generate a PKCS11 key, you are actually generating the key on the HSM, so the key data isn't available to you.  The key is stored in a session, but isn't persisted to the key store.  The Java APIs don't allow you to generate keys with an alias - there's no need for this on JKS since the key isn't associated with a store yet.  Then when you come to add the key to the store to make it permanent, you need to give it an alias.  This causes a failure in C_CopyObject, since the Java API seems to send a copy command to persist the session key.  C_CopyObject in SoftHSM is

CK_RV C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) {
  DEBUG_MSG("C_CopyObject", "Calling");
  DEBUG_MSG("C_CopyObject", "The function is not implemented.");

  return CKR_FUNCTION_NOT_SUPPORTED;
}

So my questions are, has anyone successfully created an RSA key on SoftHSM using Java?  Am I missing anything?  Is there a reason C_CopyObject isn't implemented (I suspect it's just not a core function and OpenDNSSEC works fine without it)?  

Here is the code that I am using for my testing:

    @Test
    public void testCreateKey() throws Exception {
	// Set up the Sun PKCS 11 provider
        String configName = "/tmp/softhsm.cfg";
        Provider p = new SunPKCS11(configName);

        if (-1 == Security.addProvider(p)) {
            throw new RuntimeException("could not add security provider");
        }

	// Load the key store
        char[] pin = "1111".toCharArray();
        KeyStore ks = KeyStore.getInstance("PKCS11", p);
        ks.load(null, pin);

	// Generate the key
        SecureRandom sr = new SecureRandom();
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", p);
        keyGen.initialize(1024, sr);
        KeyPair keyPair = keyGen.generateKeyPair();
        PrivateKey pk = keyPair.getPrivate();

	// Java API requires a certificate chain, rather than a Public Key
        X509Certificate[] chain = makeCertificateChain(keyPair);

	// This is the line that fails - gives me CKR_FUNCTION_NOT_SUPPORTED
        ks.setKeyEntry("ALIAS-GOES-HERE", pk, "1111".toCharArray(), chain);

        ks.store(null);
    }


Any suggestions or hints would be greatly appreciated!

Many thanks,
	Adam Knight




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opendnssec.org/pipermail/opendnssec-user/attachments/20110414/82f09a84/attachment.htm>


More information about the Opendnssec-user mailing list