8031340: Better TLS/EC management
Make sure private key structure is freed for EC key pair generation Reviewed-by: vinnie
This commit is contained in:
parent
e7bd13ff88
commit
9eec94e88c
@ -28,10 +28,9 @@
|
|||||||
SUNWprivate_1.1 {
|
SUNWprivate_1.1 {
|
||||||
global:
|
global:
|
||||||
Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
|
Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
|
||||||
Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes;
|
Java_sun_security_ec_ECDSASignature_signDigest;
|
||||||
Java_sun_security_ec_ECDSASignature_signDigest;
|
Java_sun_security_ec_ECDSASignature_verifySignedDigest;
|
||||||
Java_sun_security_ec_ECDSASignature_verifySignedDigest;
|
Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
|
||||||
Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
|
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
|
@ -125,19 +125,18 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
long[] handles = generateECKeyPair(keySize, encodedParams, seed);
|
Object[] keyBytes = generateECKeyPair(keySize, encodedParams, seed);
|
||||||
|
|
||||||
// The 'params' object supplied above is equivalent to the native
|
// The 'params' object supplied above is equivalent to the native
|
||||||
// one so there is no need to fetch it.
|
// one so there is no need to fetch it.
|
||||||
|
// keyBytes[0] is the encoding of the native private key
|
||||||
// handles[0] points to the native private key
|
BigInteger s = new BigInteger(1, (byte[])keyBytes[0]);
|
||||||
BigInteger s = new BigInteger(1, getEncodedBytes(handles[0]));
|
|
||||||
|
|
||||||
PrivateKey privateKey =
|
PrivateKey privateKey =
|
||||||
new ECPrivateKeyImpl(s, (ECParameterSpec)params);
|
new ECPrivateKeyImpl(s, (ECParameterSpec)params);
|
||||||
|
|
||||||
// handles[1] points to the native public key
|
// keyBytes[1] is the encoding of the native public key
|
||||||
ECPoint w = ECUtil.decodePoint(getEncodedBytes(handles[1]),
|
ECPoint w = ECUtil.decodePoint((byte[])keyBytes[1],
|
||||||
((ECParameterSpec)params).getCurve());
|
((ECParameterSpec)params).getCurve());
|
||||||
PublicKey publicKey =
|
PublicKey publicKey =
|
||||||
new ECPublicKeyImpl(w, (ECParameterSpec)params);
|
new ECPublicKeyImpl(w, (ECParameterSpec)params);
|
||||||
@ -162,14 +161,9 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates the keypair and returns a 2-element array of handles.
|
* Generates the keypair and returns a 2-element array of encoding bytes.
|
||||||
* The first handle points to the private key, the second to the public key.
|
* The first one is for the private key, the second for the public key.
|
||||||
*/
|
*/
|
||||||
private static native long[] generateECKeyPair(int keySize,
|
private static native Object[] generateECKeyPair(int keySize,
|
||||||
byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
|
byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
|
||||||
|
|
||||||
/*
|
|
||||||
* Extracts the encoded key data using the supplied handle.
|
|
||||||
*/
|
|
||||||
private static native byte[] getEncodedBytes(long handle);
|
|
||||||
}
|
}
|
||||||
|
@ -66,22 +66,39 @@ void FreeECParams(ECParams *ecparams, jboolean freeStruct)
|
|||||||
free(ecparams);
|
free(ecparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem)
|
||||||
|
{
|
||||||
|
SECItem *s = (SECItem *)hSECItem;
|
||||||
|
|
||||||
|
jbyteArray jEncodedBytes = env->NewByteArray(s->len);
|
||||||
|
if (jEncodedBytes == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Copy bytes from a native SECItem buffer to Java byte array
|
||||||
|
env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
|
||||||
|
if (env->ExceptionCheck()) { // should never happen
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return jEncodedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_security_ec_ECKeyPairGenerator
|
* Class: sun_security_ec_ECKeyPairGenerator
|
||||||
* Method: generateECKeyPair
|
* Method: generateECKeyPair
|
||||||
* Signature: (I[B[B)[J
|
* Signature: (I[B[B)[[B
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jlongArray
|
JNIEXPORT jobjectArray
|
||||||
JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
|
JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
|
||||||
(JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed)
|
(JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed)
|
||||||
{
|
{
|
||||||
ECPrivateKey *privKey = NULL; /* contains both public and private values */
|
ECPrivateKey *privKey = NULL; // contains both public and private values
|
||||||
ECParams *ecparams = NULL;
|
ECParams *ecparams = NULL;
|
||||||
SECKEYECParams params_item;
|
SECKEYECParams params_item;
|
||||||
jint jSeedLength;
|
jint jSeedLength;
|
||||||
jbyte* pSeedBuffer = NULL;
|
jbyte* pSeedBuffer = NULL;
|
||||||
jlongArray result = NULL;
|
jobjectArray result = NULL;
|
||||||
jlong* resultElements = NULL;
|
jclass baCls = NULL;
|
||||||
|
jbyteArray jba;
|
||||||
|
|
||||||
// Initialize the ECParams struct
|
// Initialize the ECParams struct
|
||||||
params_item.len = env->GetArrayLength(encodedParams);
|
params_item.len = env->GetArrayLength(encodedParams);
|
||||||
@ -111,70 +128,61 @@ JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
|
|||||||
}
|
}
|
||||||
|
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
result = env->NewLongArray(2);
|
baCls = env->FindClass("[B");
|
||||||
|
if (baCls == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
result = env->NewObjectArray(2, baCls, NULL);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
jba = getEncodedBytes(env, &(privKey->privateValue));
|
||||||
resultElements = env->GetLongArrayElements(result, &isCopy);
|
if (jba == NULL) {
|
||||||
if (resultElements == NULL) {
|
result = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
env->SetObjectArrayElement(result, 0, jba); // big integer
|
||||||
|
if (env->ExceptionCheck()) { // should never happen
|
||||||
|
result = NULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
resultElements[0] = (jlong) &(privKey->privateValue); // private big integer
|
jba = getEncodedBytes(env, &(privKey->publicValue));
|
||||||
resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point
|
if (jba == NULL) {
|
||||||
|
result = NULL;
|
||||||
// If the array is a copy then we must write back our changes
|
goto cleanup;
|
||||||
if (isCopy == JNI_TRUE) {
|
}
|
||||||
env->ReleaseLongArrayElements(result, resultElements, 0);
|
env->SetObjectArrayElement(result, 1, jba); // encoded ec point
|
||||||
|
if (env->ExceptionCheck()) { // should never happen
|
||||||
|
result = NULL;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
{
|
{
|
||||||
if (params_item.data)
|
if (params_item.data) {
|
||||||
env->ReleaseByteArrayElements(encodedParams,
|
env->ReleaseByteArrayElements(encodedParams,
|
||||||
(jbyte *) params_item.data, JNI_ABORT);
|
(jbyte *) params_item.data, JNI_ABORT);
|
||||||
|
}
|
||||||
if (ecparams)
|
if (ecparams) {
|
||||||
FreeECParams(ecparams, true);
|
FreeECParams(ecparams, true);
|
||||||
|
}
|
||||||
if (privKey) {
|
if (privKey) {
|
||||||
FreeECParams(&privKey->ecParams, false);
|
FreeECParams(&privKey->ecParams, false);
|
||||||
SECITEM_FreeItem(&privKey->version, B_FALSE);
|
SECITEM_FreeItem(&privKey->version, B_FALSE);
|
||||||
// Don't free privKey->privateValue and privKey->publicValue
|
SECITEM_FreeItem(&privKey->privateValue, B_FALSE);
|
||||||
|
SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
|
||||||
|
free(privKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSeedBuffer)
|
if (pSeedBuffer) {
|
||||||
delete [] pSeedBuffer;
|
delete [] pSeedBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Class: sun_security_ec_ECKeyPairGenerator
|
|
||||||
* Method: getEncodedBytes
|
|
||||||
* Signature: (J)[B
|
|
||||||
*/
|
|
||||||
JNIEXPORT jbyteArray
|
|
||||||
JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes
|
|
||||||
(JNIEnv *env, jclass clazz, jlong hSECItem)
|
|
||||||
{
|
|
||||||
SECItem *s = (SECItem *)hSECItem;
|
|
||||||
jbyteArray jEncodedBytes = env->NewByteArray(s->len);
|
|
||||||
if (jEncodedBytes == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy bytes from a native SECItem buffer to Java byte array
|
|
||||||
env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
|
|
||||||
|
|
||||||
// Use B_FALSE to free only the SECItem->data
|
|
||||||
SECITEM_FreeItem(s, B_FALSE);
|
|
||||||
|
|
||||||
return jEncodedBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_security_ec_ECDSASignature
|
* Class: sun_security_ec_ECDSASignature
|
||||||
* Method: signDigest
|
* Method: signDigest
|
||||||
@ -258,21 +266,26 @@ JNICALL Java_sun_security_ec_ECDSASignature_signDigest
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
{
|
{
|
||||||
if (params_item.data)
|
if (params_item.data) {
|
||||||
env->ReleaseByteArrayElements(encodedParams,
|
env->ReleaseByteArrayElements(encodedParams,
|
||||||
(jbyte *) params_item.data, JNI_ABORT);
|
(jbyte *) params_item.data, JNI_ABORT);
|
||||||
|
}
|
||||||
if (pDigestBuffer)
|
if (privKey.privateValue.data) {
|
||||||
|
env->ReleaseByteArrayElements(privateKey,
|
||||||
|
(jbyte *) privKey.privateValue.data, JNI_ABORT);
|
||||||
|
}
|
||||||
|
if (pDigestBuffer) {
|
||||||
delete [] pDigestBuffer;
|
delete [] pDigestBuffer;
|
||||||
|
}
|
||||||
if (pSignedDigestBuffer)
|
if (pSignedDigestBuffer) {
|
||||||
delete [] pSignedDigestBuffer;
|
delete [] pSignedDigestBuffer;
|
||||||
|
}
|
||||||
if (pSeedBuffer)
|
if (pSeedBuffer) {
|
||||||
delete [] pSeedBuffer;
|
delete [] pSeedBuffer;
|
||||||
|
}
|
||||||
if (ecparams)
|
if (ecparams) {
|
||||||
FreeECParams(ecparams, true);
|
FreeECParams(ecparams, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return jSignedDigest;
|
return jSignedDigest;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user