<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi,<div><br></div><div>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: <a href="http://comments.gmane.org/gmane.comp.java.openjdk.security.devel/1772">http://comments.gmane.org/gmane.comp.java.openjdk.security.devel/1772</a>) but unfortunately since SoftHSM doesn't implement C_CopyObject, I'm a little stuck.</div><div><br></div><div>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:</div><div><br></div><div>1) Create a Key pair</div><div>2) Put the key in the key store</div><div>3) Save the key store</div><div><br></div><div>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.</div><div><br></div><div>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</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">CK_RV C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) {</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(206, 47, 36); "><span style="color: #000000"> DEBUG_MSG(</span>"C_CopyObject"<span style="color: #000000">, </span>"Calling"<span style="color: #000000">);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; color: rgb(206, 47, 36); "><span style="color: #000000"> DEBUG_MSG(</span>"C_CopyObject"<span style="color: #000000">, </span>"The function is not implemented."<span style="color: #000000">);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; min-height: 13px; "><br></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; "> <span style="color: #b930a1">return</span> CKR_FUNCTION_NOT_SUPPORTED;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 11px/normal Menlo; ">}</div></div><div><br></div><div>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)? </div><div><br></div><div>Here is the code that I am using for my testing:</div><div><br></div><div><div> @Test</div><div> public void testCreateKey() throws Exception {</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// Set up the Sun PKCS 11 provider</div><div> String configName = "/tmp/softhsm.cfg";</div><div> Provider p = new SunPKCS11(configName);</div><div><br></div><div> if (-1 == Security.addProvider(p)) {</div><div> throw new RuntimeException("could not add security provider");</div><div> }</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// Load the key store</div><div> char[] pin = "1111".toCharArray();</div><div> KeyStore ks = KeyStore.getInstance("PKCS11", p);</div><div> ks.load(null, pin);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// Generate the key</div><div> SecureRandom sr = new SecureRandom();</div><div> KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", p);</div><div> keyGen.initialize(1024, sr);</div><div> KeyPair keyPair = keyGen.generateKeyPair();</div><div> PrivateKey pk = keyPair.getPrivate();</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// Java API requires a certificate chain, rather than a Public Key</div><div> X509Certificate[] chain = makeCertificateChain(keyPair);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// This is the line that fails - gives me CKR_FUNCTION_NOT_SUPPORTED</div><div> ks.setKeyEntry("ALIAS-GOES-HERE", pk, "1111".toCharArray(), chain);</div><div><br></div><div> ks.store(null);</div><div> }</div></div><div><br></div><div><br></div><div>Any suggestions or hints would be greatly appreciated!</div><div><br></div><div>Many thanks,</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>Adam Knight</div><div><br></div><div><br></div><div><br><div><br></div></div></body></html>