-
Bug
-
Resolution: Unresolved
-
P4
-
None
-
8u65, 10
-
x86
-
linux_redhat_6.0
FULL PRODUCT VERSION :
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux secomo 2.6.32-573.7.1.el6.x86_64 #1 SMP Tue Sep 22 22:00:00 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.7 (Final)
EXTRA RELEVANT SYSTEM CONFIGURATION :
For the test case, I used an Utimaco CryptoServer HSM. However, any PKCS11 provider can be used to execute the test case.
A DESCRIPTION OF THE PROBLEM :
Executing SecretKey.toString() for an instance that represents an HMAC-SHA256 with a length of 32 bytes returns the following output:
SunPKCS11-CryptoServer Generic Secret secret key, 32 bits (id 3, token object, sensitive, unextractable)
The output indicates a length of 32 bits. However, the key has a length of 256 bits. The PKCS11 attributes are as follows:
CKA_CLASS: CKO_SECRET_KEY
CKA_LABEL: test
CKA_ID: test
CKA_TOKEN: CK_TRUE
CKA_PRIVATE: CK_TRUE
CKA_MODIFIABLE: CK_TRUE
CKA_KEY_TYPE: CKK_GENERIC_SECRET
CKA_DERIVE: CK_FALSE
CKA_LOCAL: CK_TRUE
CKA_ENCRYPT: CK_FALSE
CKA_VERIFY: CK_TRUE
CKA_VERIFY_RECOVER: CK_FALSE
CKA_WRAP: CK_TRUE
CKA_TRUSTED: CK_FALSE
CKA_DECRYPT: CK_FALSE
CKA_SIGN: CK_TRUE
CKA_WRAP_WITH_TRUSTED: CK_FALSE
CKA_UNWRAP: CK_TRUE
CKA_SENSITIVE: CK_FALSE
CKA_ALWAYS_SENSITIVE: CK_FALSE
CKA_EXTRACTABLE: CK_TRUE
CKA_NEVER_EXTRACTABLE: CK_FALSE
CKA_CHECK_VALUE: 3 bytes (24 bits)
14 e0 db
CKA_VALUE: 32 bytes (256 bits)
85 c0 9d 06 f3 bb 49 19 2b 44 3a 9e 33 e9 fd 86
70 d4 db 4d 51 02 28 6e 7e ec dc f5 56 31 bc 79
The return value should indicate the correct length of 32 bits.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
SunPKCS11 provider = new SunPKCS11(/* config */);
TestCallbackHandler handler = new TestCallbackHandler(pin);
provider.login(null, /* callback handler */);
KeyStore keystore = KeyStore.Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(handler)).getKeyStore();
Key key = keystore.getKey(/* key label */, null);
System.out.println(key);
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
SunPKCS11-CryptoServer Generic Secret secret key, 256 bits (id 3, token object, sensitive, unextractable)
ACTUAL -
SunPKCS11-CryptoServer Generic Secret secret key, 32 bits (id 3, token object, sensitive, unextractable)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
The following test case assumes an Utimaco CryptoServer HSM. However, the provider initialization can be changed to work with any PKCS11 implementation.
java Test <pkcs11-pin> <pkcs11-key-label>
import java.io.*;
import java.security.*;
import java.util.*;
import javax.security.auth.callback.*;
import javax.crypto.*;
import sun.security.pkcs11.*;
public class Test
{
public static void main(String[] args) throws Exception
{
String pin = args[0];
String label = args[1];
Properties props = new Properties();
props.put("PKCS11_NATIVE_MODULE", "/usr/lib64/libcs_pkcs11_R2.so");
props.put("USE_UTF8_ENCODING", "true");
props.put("CHECK_MECHANISM_SUPPORTED", "true");
props.put("USER_PIN", pin);
String config = "name = CryptoServer\n" +
"library = /usr/lib64/libcs_pkcs11_R2.so\n" +
"slotListIndex = 0\n";
InputStream in = new ByteArrayInputStream(config.getBytes("UTF-8"));
SunPKCS11 provider = new SunPKCS11(in);
TestCallbackHandler handler = new TestCallbackHandler(pin);
provider.login(null, handler);
Security.addProvider(provider);
KeyStore keystore = KeyStore.Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(handler)).getKeyStore();
Key key = keystore.getKey(label, null);
System.out.println(key);
}
}
class TestCallbackHandler implements CallbackHandler
{
private String pin;
public TestCallbackHandler(String pin)
{
this.pin = pin;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
PasswordCallback pwcb = (PasswordCallback)callbacks[i];
pwcb.setPassword(pin.toCharArray());
}
}
}
---------- END SOURCE ----------
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux secomo 2.6.32-573.7.1.el6.x86_64 #1 SMP Tue Sep 22 22:00:00 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
CentOS release 6.7 (Final)
EXTRA RELEVANT SYSTEM CONFIGURATION :
For the test case, I used an Utimaco CryptoServer HSM. However, any PKCS11 provider can be used to execute the test case.
A DESCRIPTION OF THE PROBLEM :
Executing SecretKey.toString() for an instance that represents an HMAC-SHA256 with a length of 32 bytes returns the following output:
SunPKCS11-CryptoServer Generic Secret secret key, 32 bits (id 3, token object, sensitive, unextractable)
The output indicates a length of 32 bits. However, the key has a length of 256 bits. The PKCS11 attributes are as follows:
CKA_CLASS: CKO_SECRET_KEY
CKA_LABEL: test
CKA_ID: test
CKA_TOKEN: CK_TRUE
CKA_PRIVATE: CK_TRUE
CKA_MODIFIABLE: CK_TRUE
CKA_KEY_TYPE: CKK_GENERIC_SECRET
CKA_DERIVE: CK_FALSE
CKA_LOCAL: CK_TRUE
CKA_ENCRYPT: CK_FALSE
CKA_VERIFY: CK_TRUE
CKA_VERIFY_RECOVER: CK_FALSE
CKA_WRAP: CK_TRUE
CKA_TRUSTED: CK_FALSE
CKA_DECRYPT: CK_FALSE
CKA_SIGN: CK_TRUE
CKA_WRAP_WITH_TRUSTED: CK_FALSE
CKA_UNWRAP: CK_TRUE
CKA_SENSITIVE: CK_FALSE
CKA_ALWAYS_SENSITIVE: CK_FALSE
CKA_EXTRACTABLE: CK_TRUE
CKA_NEVER_EXTRACTABLE: CK_FALSE
CKA_CHECK_VALUE: 3 bytes (24 bits)
14 e0 db
CKA_VALUE: 32 bytes (256 bits)
85 c0 9d 06 f3 bb 49 19 2b 44 3a 9e 33 e9 fd 86
70 d4 db 4d 51 02 28 6e 7e ec dc f5 56 31 bc 79
The return value should indicate the correct length of 32 bits.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
SunPKCS11 provider = new SunPKCS11(/* config */);
TestCallbackHandler handler = new TestCallbackHandler(pin);
provider.login(null, /* callback handler */);
KeyStore keystore = KeyStore.Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(handler)).getKeyStore();
Key key = keystore.getKey(/* key label */, null);
System.out.println(key);
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
SunPKCS11-CryptoServer Generic Secret secret key, 256 bits (id 3, token object, sensitive, unextractable)
ACTUAL -
SunPKCS11-CryptoServer Generic Secret secret key, 32 bits (id 3, token object, sensitive, unextractable)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
The following test case assumes an Utimaco CryptoServer HSM. However, the provider initialization can be changed to work with any PKCS11 implementation.
java Test <pkcs11-pin> <pkcs11-key-label>
import java.io.*;
import java.security.*;
import java.util.*;
import javax.security.auth.callback.*;
import javax.crypto.*;
import sun.security.pkcs11.*;
public class Test
{
public static void main(String[] args) throws Exception
{
String pin = args[0];
String label = args[1];
Properties props = new Properties();
props.put("PKCS11_NATIVE_MODULE", "/usr/lib64/libcs_pkcs11_R2.so");
props.put("USE_UTF8_ENCODING", "true");
props.put("CHECK_MECHANISM_SUPPORTED", "true");
props.put("USER_PIN", pin);
String config = "name = CryptoServer\n" +
"library = /usr/lib64/libcs_pkcs11_R2.so\n" +
"slotListIndex = 0\n";
InputStream in = new ByteArrayInputStream(config.getBytes("UTF-8"));
SunPKCS11 provider = new SunPKCS11(in);
TestCallbackHandler handler = new TestCallbackHandler(pin);
provider.login(null, handler);
Security.addProvider(provider);
KeyStore keystore = KeyStore.Builder.newInstance("PKCS11", provider, new KeyStore.CallbackHandlerProtection(handler)).getKeyStore();
Key key = keystore.getKey(label, null);
System.out.println(key);
}
}
class TestCallbackHandler implements CallbackHandler
{
private String pin;
public TestCallbackHandler(String pin)
{
this.pin = pin;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
PasswordCallback pwcb = (PasswordCallback)callbacks[i];
pwcb.setPassword(pin.toCharArray());
}
}
}
---------- END SOURCE ----------