diff --git a/jdk/make/mapfiles/libj2ucrypto/mapfile-vers b/jdk/make/mapfiles/libj2ucrypto/mapfile-vers index 2a5c2a5f83f..833da53297e 100644 --- a/jdk/make/mapfiles/libj2ucrypto/mapfile-vers +++ b/jdk/make/mapfiles/libj2ucrypto/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ SUNWprivate_1.1 { Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal; Java_com_oracle_security_ucrypto_NativeKey_nativeFree; + Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; @@ -56,6 +57,7 @@ SUNWprivate_1.1 { JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal; JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree; + JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeKey.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeKey.java index 7f88f92ab4c..6e0f15bbe8a 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeKey.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,19 +31,9 @@ import java.util.concurrent.ConcurrentSkipListSet; import java.lang.ref.*; import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Key; -import java.security.PublicKey; -import java.security.PrivateKey; -import java.security.KeyFactorySpi; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPublicKey; - -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; +import java.security.*; +import java.security.interfaces.*; +import java.security.spec.*; /** * Wrapper class for native keys needed for using ucrypto APIs. @@ -87,6 +77,41 @@ abstract class NativeKey implements Key { return b; } + static final class RSAPrivate extends NativeKey implements RSAPrivateKey { + + private static final long serialVersionUID = 1622705588904302831L; + + private final RSAPrivateKeySpec keySpec; + private final long keyId; + + RSAPrivate(KeySpec keySpec) throws InvalidKeySpecException { + super(2); + long pKey = 0L; + if (keySpec instanceof RSAPrivateKeySpec) { + RSAPrivateKeySpec ks = (RSAPrivateKeySpec) keySpec; + BigInteger mod = ks.getModulus(); + BigInteger privateExp = ks.getPrivateExponent(); + pKey = nativeInit(NativeKey.getMagnitude(mod), + NativeKey.getMagnitude(privateExp)); + } else { + throw new InvalidKeySpecException("Only supports RSAPrivateKeySpec"); + } + if (pKey == 0L) { + throw new UcryptoException("Error constructing RSA PrivateKey"); + } + // track native resource clean up + new KeyRef(this, pKey); + this.keySpec = (RSAPrivateKeySpec) keySpec; + this.keyId = pKey; + } + + long value() { return keyId; } + public BigInteger getModulus() { return keySpec.getModulus(); }; + public BigInteger getPrivateExponent() { return keySpec.getPrivateExponent(); }; + + private native static long nativeInit(byte[] mod, byte[] privExp); + } + static final class RSAPrivateCrt extends NativeKey implements RSAPrivateCrtKey { private static final long serialVersionUID = 6812507588904302831L; @@ -119,7 +144,7 @@ abstract class NativeKey implements Key { throw new InvalidKeySpecException("Only supports RSAPrivateCrtKeySpec"); } if (pKey == 0L) { - throw new UcryptoException("Error constructing RSA PrivateKey"); + throw new UcryptoException("Error constructing RSA PrivateCrtKey"); } // track native resource clean up new KeyRef(this, pKey); diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSACipher.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSACipher.java index df538c87c39..9169106b602 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSACipher.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,9 +37,11 @@ import java.security.Key; import java.security.PublicKey; import java.security.PrivateKey; import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.interfaces.RSAKey; import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.KeyFactory; @@ -205,8 +207,8 @@ public class NativeRSACipher extends CipherSpi { // Make sure the proper opmode uses the proper key if (doEncrypt && (!(newKey instanceof RSAPublicKey))) { throw new InvalidKeyException("RSAPublicKey required for encryption"); - } else if (!doEncrypt && (!(newKey instanceof RSAPrivateCrtKey))) { - throw new InvalidKeyException("RSAPrivateCrtKey required for decryption"); + } else if (!doEncrypt && (!(newKey instanceof RSAPrivateKey))) { + throw new InvalidKeyException("RSAPrivateKey required for decryption"); } NativeKey nativeKey = null; @@ -223,17 +225,26 @@ public class NativeRSACipher extends CipherSpi { throw new InvalidKeyException(ikse); } } else { - RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) newKey; try { - nativeKey = (NativeKey) keyFactory.engineGeneratePrivate - (new RSAPrivateCrtKeySpec(privateKey.getModulus(), - privateKey.getPublicExponent(), - privateKey.getPrivateExponent(), - privateKey.getPrimeP(), - privateKey.getPrimeQ(), - privateKey.getPrimeExponentP(), - privateKey.getPrimeExponentQ(), - privateKey.getCrtCoefficient())); + if (newKey instanceof RSAPrivateCrtKey) { + RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) newKey; + nativeKey = (NativeKey) keyFactory.engineGeneratePrivate + (new RSAPrivateCrtKeySpec(privateKey.getModulus(), + privateKey.getPublicExponent(), + privateKey.getPrivateExponent(), + privateKey.getPrimeP(), + privateKey.getPrimeQ(), + privateKey.getPrimeExponentP(), + privateKey.getPrimeExponentQ(), + privateKey.getCrtCoefficient())); + } else if (newKey instanceof RSAPrivateKey) { + RSAPrivateKey privateKey = (RSAPrivateKey) newKey; + nativeKey = (NativeKey) keyFactory.engineGeneratePrivate + (new RSAPrivateKeySpec(privateKey.getModulus(), + privateKey.getPrivateExponent())); + } else { + throw new InvalidKeyException("Unsupported type of RSAPrivateKey"); + } } catch (InvalidKeySpecException ikse) { throw new InvalidKeyException(ikse); } diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSAKeyFactory.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSAKeyFactory.java index 80cc1d9b224..591cdee62ea 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSAKeyFactory.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSAKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,16 +38,11 @@ import java.security.PublicKey; import java.security.PrivateKey; import java.security.KeyFactorySpi; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; +import java.security.spec.*; /** * Ucrypto-private KeyFactory class for generating native keys - * needed for using ucrypto APIs. Given that it's not used - * externally, it only needs to support RSAPrivateCrtKeySpec - * and RSAPublicKeySpec objects. + * needed for using ucrypto APIs. * * @since 1.9 */ @@ -56,7 +51,13 @@ public final class NativeRSAKeyFactory extends KeyFactorySpi { @Override protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { - return new NativeKey.RSAPrivateCrt(keySpec); + if (keySpec instanceof RSAPrivateCrtKeySpec) { + return new NativeKey.RSAPrivateCrt(keySpec); + } else if (keySpec instanceof RSAPrivateKeySpec) { + return new NativeKey.RSAPrivate(keySpec); + } else { + throw new InvalidKeySpecException("Unsupported key spec"); + } } @Override diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java index 392d686bb30..ea7930c429b 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeRSASignature.java @@ -43,9 +43,8 @@ import java.security.PublicKey; import java.security.*; import java.security.interfaces.*; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; -import java.security.spec.InvalidKeySpecException; +import java.security.spec.*; + import sun.nio.ch.DirectBuffer; import java.nio.ByteBuffer; @@ -192,25 +191,31 @@ class NativeRSASignature extends SignatureSpi { int newSigLength = sigLength; // Need to check RSA key length whenever a new private key is set if (privateKey != key) { - if (privateKey instanceof RSAPrivateCrtKey) { - RSAPrivateCrtKey rsaPrivKey = (RSAPrivateCrtKey) privateKey; - BigInteger mod = rsaPrivKey.getModulus(); - newSigLength = checkRSAKeyLength(mod); - try { + if (!(privateKey instanceof RSAPrivateKey)) { + throw new InvalidKeyException("RSAPrivateKey required"); + } + RSAPrivateKey rsaPrivKey = (RSAPrivateKey) privateKey; + BigInteger mod = rsaPrivKey.getModulus(); + newSigLength = checkRSAKeyLength(mod); + BigInteger pe = rsaPrivKey.getPrivateExponent(); + try { + if (rsaPrivKey instanceof RSAPrivateCrtKey) { + RSAPrivateCrtKey rsaPrivCrtKey = (RSAPrivateCrtKey) rsaPrivKey; newKey = (NativeKey) keyFactory.engineGeneratePrivate (new RSAPrivateCrtKeySpec(mod, - rsaPrivKey.getPublicExponent(), - rsaPrivKey.getPrivateExponent(), - rsaPrivKey.getPrimeP(), - rsaPrivKey.getPrimeQ(), - rsaPrivKey.getPrimeExponentP(), - rsaPrivKey.getPrimeExponentQ(), - rsaPrivKey.getCrtCoefficient())); - } catch (InvalidKeySpecException ikse) { - throw new InvalidKeyException(ikse); + rsaPrivCrtKey.getPublicExponent(), + pe, + rsaPrivCrtKey.getPrimeP(), + rsaPrivCrtKey.getPrimeQ(), + rsaPrivCrtKey.getPrimeExponentP(), + rsaPrivCrtKey.getPrimeExponentQ(), + rsaPrivCrtKey.getCrtCoefficient())); + } else { + newKey = (NativeKey) keyFactory.engineGeneratePrivate + (new RSAPrivateKeySpec(mod, pe)); } - } else { - throw new InvalidKeyException("RSAPrivateCrtKey required"); + } catch (InvalidKeySpecException ikse) { + throw new InvalidKeyException(ikse); } } init(true, newKey, newSigLength); diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c index ddb8f0b4404..a65eaca3f50 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -696,6 +696,86 @@ JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeKey_nativeFree JavaCritical_com_oracle_security_ucrypto_NativeKey_nativeFree(id, numOfComponents); } +/* + * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivate + * Method: nativeInit + * Signature: ([B[B)J + */ +jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit +(int modLen, jbyte* jMod, int privLen, jbyte* jPriv) { + + unsigned char *mod, *priv; + crypto_object_attribute_t* pKey = NULL; + + pKey = calloc(2, sizeof(crypto_object_attribute_t)); + if (pKey == NULL) { + return 0L; + } + mod = priv = NULL; + mod = malloc(modLen); + priv = malloc(privLen); + if (mod == NULL || priv == NULL) { + free(pKey); + free(mod); + free(priv); + return 0L; + } else { + memcpy(mod, jMod, modLen); + memcpy(priv, jPriv, privLen); + } + + // NOTE: numOfComponents should be 2 + pKey[0].oa_type = SUN_CKA_MODULUS; + pKey[0].oa_value = (char*) mod; + pKey[0].oa_value_len = (size_t) modLen; + pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; + pKey[1].oa_value = (char*) priv; + pKey[1].oa_value_len = (size_t) privLen; + + return (jlong) pKey; +} + +JNIEXPORT jlong JNICALL +Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit + (JNIEnv *env, jclass jCls, jbyteArray jMod, jbyteArray jPriv) { + + int modLen, privLen; + jbyte *bufMod, *bufPriv; + crypto_object_attribute_t* pKey = NULL; + + bufMod = bufPriv = NULL; + + modLen = (*env)->GetArrayLength(env, jMod); + bufMod = getBytes(env, jMod, 0, modLen); + if ((*env)->ExceptionCheck(env)) goto cleanup; + + privLen = (*env)->GetArrayLength(env, jPriv); + bufPriv = getBytes(env, jPriv, 0, privLen); + if ((*env)->ExceptionCheck(env)) goto cleanup; + + // proceed if no error; otherwise free allocated memory + pKey = calloc(2, sizeof(crypto_object_attribute_t)); + if (pKey == NULL) { + throwOutOfMemoryError(env, NULL); + goto cleanup; + } + + // NOTE: numOfComponents should be 2 + pKey[0].oa_type = SUN_CKA_MODULUS; + pKey[0].oa_value = (char*) bufMod; + pKey[0].oa_value_len = (size_t) modLen; + pKey[1].oa_type = SUN_CKA_PRIVATE_EXPONENT; + pKey[1].oa_value = (char*) bufPriv; + pKey[1].oa_value_len = (size_t) privLen; + return (jlong) pKey; + +cleanup: + free(bufMod); + free(bufPriv); + + return 0L; +} + /* * Class: com_oracle_security_ucrypto_NativeKey_RSAPrivateCrt * Method: nativeInit diff --git a/jdk/test/com/oracle/security/ucrypto/CipherSignNotSupported.java b/jdk/test/com/oracle/security/ucrypto/CipherSignNotSupported.java index 7e141b615b5..47ef8b8e380 100644 --- a/jdk/test/com/oracle/security/ucrypto/CipherSignNotSupported.java +++ b/jdk/test/com/oracle/security/ucrypto/CipherSignNotSupported.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8029849 + * @bug 8029849 8132082 * @summary Make sure signing via encrypt and verifying via decrypt are not * supported by OracleUcrypto provider. * @author Anthony Scarpino @@ -31,12 +31,10 @@ */ import java.util.Random; -import java.security.KeyPairGenerator; -import java.security.KeyPair; +import java.security.*; +import java.security.interfaces.*; +import java.security.spec.RSAPrivateKeySpec; import javax.crypto.Cipher; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Provider; public class CipherSignNotSupported extends UcryptoTest { @@ -69,27 +67,43 @@ public class CipherSignNotSupported extends UcryptoTest { c.init(Cipher.ENCRYPT_MODE, kp.getPublic()); ct = c.doFinal(pt); // Decryption - c.init(Cipher.DECRYPT_MODE, kp.getPrivate()); - c.doFinal(ct); - // Sign - try { - c.init(Cipher.ENCRYPT_MODE, kp.getPrivate()); - ct = c.doFinal(pt); - throw new RuntimeException("Encrypt operation should have failed."); - } catch (InvalidKeyException e) { - if (e.getMessage().compareTo("RSAPublicKey required for " + - "encryption") != 0) { - System.out.println("Wrong exception thrown."); - throw e; + PrivateKey[] privKeys = new PrivateKey[2]; + privKeys[0] = kp.getPrivate(); + if (privKeys[0] instanceof RSAPrivateCrtKey) { + RSAPrivateCrtKey k = (RSAPrivateCrtKey) privKeys[0]; + KeyFactory kf = KeyFactory.getInstance("RSA"); + privKeys[1] = kf.generatePrivate + (new RSAPrivateKeySpec(k.getModulus(), k.getPrivateExponent())); + } else { + privKeys = new PrivateKey[] {privKeys[0]}; + } + + for (PrivateKey pk : privKeys) { + System.out.println("Testing " + pk); + c.init(Cipher.DECRYPT_MODE, pk); + c.doFinal(ct); + + // Sign + try { + c.init(Cipher.ENCRYPT_MODE, pk); + ct = c.doFinal(pt); + throw new RuntimeException("Encrypt operation should have failed."); + } catch (InvalidKeyException e) { + if (e.getMessage().compareTo("RSAPublicKey required for " + + "encryption") != 0) { + System.out.println("Wrong exception thrown."); + throw e; + } } } + // Verify try { c.init(Cipher.DECRYPT_MODE, kp.getPublic()); c.doFinal(ct); throw new RuntimeException("Decrypt operation should have failed."); } catch (InvalidKeyException e) { - if (e.getMessage().compareTo("RSAPrivateCrtKey required for " + + if (e.getMessage().compareTo("RSAPrivateKey required for " + "decryption") != 0) { System.out.println("Wrong exception thrown."); throw e;