提交 28e8bc14 编写于 作者: V valeriep

8031340: Better TLS/EC management

Summary: Make sure private key structure is freed for EC key pair generation
Reviewed-by: vinnie
上级 6d3e5208
# #
# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -28,10 +28,9 @@ ...@@ -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:
*; *;
}; };
/* /*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -125,19 +125,18 @@ public final class ECKeyPairGenerator extends KeyPairGeneratorSpi { ...@@ -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 { ...@@ -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);
} }
/* /*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -64,22 +64,40 @@ void FreeECParams(ECParams *ecparams, jboolean freeStruct) ...@@ -64,22 +64,40 @@ 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; /* 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);
...@@ -106,60 +124,60 @@ JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair ...@@ -106,60 +124,60 @@ JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
} }
jboolean isCopy; jboolean isCopy;
result = env->NewLongArray(2); baCls = env->FindClass("[B");
resultElements = env->GetLongArrayElements(result, &isCopy); if (baCls == NULL) {
goto cleanup;
resultElements[0] = (jlong) &(privKey->privateValue); // private big integer }
resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point result = env->NewObjectArray(2, baCls, NULL);
if (result == NULL) {
goto cleanup;
}
jba = getEncodedBytes(env, &(privKey->privateValue));
if (jba == NULL) {
result = NULL;
goto cleanup;
}
env->SetObjectArrayElement(result, 0, jba); // big integer
if (env->ExceptionCheck()) { // should never happen
result = NULL;
goto cleanup;
}
// If the array is a copy then we must write back our changes jba = getEncodedBytes(env, &(privKey->publicValue));
if (isCopy == JNI_TRUE) { if (jba == NULL) {
env->ReleaseLongArrayElements(result, resultElements, 0); result = NULL;
goto cleanup;
}
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);
// 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
...@@ -234,21 +252,26 @@ JNICALL Java_sun_security_ec_ECDSASignature_signDigest ...@@ -234,21 +252,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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册