Mercurial > hg > release > icedtea7-forest-2.6 > jdk
changeset 9698:0fdbcf2eb794
8165463: Native implementation of sunmscapi should use operator new (nothrow) for allocations
Reviewed-by: clanger, jnimeh, vinnie
author | igerasim |
---|---|
date | Thu, 31 Jan 2019 04:54:52 +0000 |
parents | 0a4a916e89ae |
children | e960bce2d584 |
files | src/windows/native/sun/security/mscapi/security.cpp |
diffstat | 1 files changed, 110 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/src/windows/native/sun/security/mscapi/security.cpp Thu Jan 31 04:33:24 2019 +0000 +++ b/src/windows/native/sun/security/mscapi/security.cpp Thu Jan 31 04:54:52 2019 +0000 @@ -35,6 +35,7 @@ #include <BaseTsd.h> #include <wincrypt.h> #include <stdio.h> +#include <memory> #define OID_EKU_ANY "2.5.29.37.0" @@ -47,14 +48,27 @@ #define KEYSTORE_EXCEPTION "java/security/KeyStoreException" #define PROVIDER_EXCEPTION "java/security/ProviderException" #define SIGNATURE_EXCEPTION "java/security/SignatureException" +#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError" extern "C" { /* + * Throws an arbitrary Java exception with the given message. + */ +void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName, + const char *szMessage) +{ + jclass exceptionClazz = env->FindClass(exceptionName); + if (exceptionClazz != NULL) { + env->ThrowNew(exceptionClazz, szMessage); + } +} + +/* * Throws an arbitrary Java exception. * The exception message is a Windows system error message. */ -void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError) +void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError) { char szMessage[1024]; szMessage[0] = '\0'; @@ -65,12 +79,22 @@ strcpy(szMessage, "Unknown error"); } - jclass exceptionClazz = env->FindClass(exceptionName); - if (exceptionClazz != NULL) { - env->ThrowNew(exceptionClazz, szMessage); - } + ThrowExceptionWithMessage(env, exceptionName, szMessage); } +/* + * Overloaded 'operator new[]' variant, which will raise Java's + * OutOfMemoryError in the case of a failure. + */ +static void* operator new[](std::size_t size, JNIEnv *env) +{ + void* buf = ::operator new[](size, std::nothrow); + if (buf == NULL) { + ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR, + "Native memory allocation failed"); + } + return buf; +} /* * Maps the name of a hash algorithm to an algorithm identifier. @@ -412,7 +436,11 @@ NULL, 0)) > 1) { // Found friendly name - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } + CertGetNameString(pc, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString); @@ -548,7 +576,10 @@ } // Copy hash from Java to native buffer - pHashBuffer = new jbyte[jHashSize]; + pHashBuffer = new (env) jbyte[jHashSize]; + if (pHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer); // Set hash value in the hash object @@ -586,7 +617,10 @@ __leave; } - pSignedHashBuffer = new jbyte[dwBufLen]; + pSignedHashBuffer = new (env) jbyte[dwBufLen]; + if (pSignedHashBuffer == NULL) { + __leave; + } if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE) { ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); @@ -674,9 +708,16 @@ } // Copy hash and signedHash from Java to native buffer - pHashBuffer = new jbyte[jHashSize]; + pHashBuffer = new (env) jbyte[jHashSize]; + if (pHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer); - pSignedHashBuffer = new jbyte[jSignedHashSize]; + + pSignedHashBuffer = new (env) jbyte[jSignedHashSize]; + if (pSignedHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize, pSignedHashBuffer); @@ -889,7 +930,10 @@ } // Copy encoding from Java to native buffer - pbCertEncoding = new jbyte[jCertEncodingSize]; + pbCertEncoding = new (env) jbyte[jCertEncodingSize]; + if (pbCertEncoding == NULL) { + __leave; + } env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding); // Create a certificate context from the encoded cert @@ -902,7 +946,10 @@ // Set the certificate's friendly name int size = env->GetStringLength(jCertAliasName); - pszCertAliasName = new WCHAR[size + 1]; + pszCertAliasName = new (env) WCHAR[size + 1]; + if (pszCertAliasName == NULL) { + __leave; + } jCertAliasChars = env->GetStringChars(jCertAliasName, NULL); memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR)); @@ -940,7 +987,10 @@ __leave; } - pszContainerName = new char[dwDataLen]; + pszContainerName = new (env) char[dwDataLen]; + if (pszContainerName == NULL) { + __leave; + } if (! ::CryptGetProvParam( (HCRYPTPROV) hCryptProv, @@ -954,7 +1004,10 @@ } // Convert to a wide char string - pwszContainerName = new WCHAR[dwDataLen]; + pwszContainerName = new (env) WCHAR[dwDataLen]; + if (pwszContainerName == NULL) { + __leave; + } if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) { ThrowException(env, KEYSTORE_EXCEPTION, GetLastError()); @@ -977,7 +1030,10 @@ __leave; } - pszProviderName = new char[dwDataLen]; + pszProviderName = new (env) char[dwDataLen]; + if (pszProviderName == NULL) { + __leave; + } if (! ::CryptGetProvParam( (HCRYPTPROV) hCryptProv, @@ -991,7 +1047,10 @@ } // Convert to a wide char string - pwszProviderName = new WCHAR[dwDataLen]; + pwszProviderName = new (env) WCHAR[dwDataLen]; + if (pwszProviderName == NULL) { + __leave; + } if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) { ThrowException(env, KEYSTORE_EXCEPTION, GetLastError()); @@ -1131,7 +1190,10 @@ } // Copy encoding from Java to native buffer - pbCertEncoding = new jbyte[jCertEncodingSize]; + pbCertEncoding = new (env) jbyte[jCertEncodingSize]; + if (pbCertEncoding == NULL) { + __leave; + } env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding); // Create a certificate context from the encoded cert @@ -1154,7 +1216,10 @@ if ((cchNameString = ::CertGetNameString(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) { - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } ::CertGetNameString(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, @@ -1304,7 +1369,10 @@ continue; // not found } - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } if (::CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, @@ -1466,7 +1534,10 @@ __try { // Copy data from Java buffer to native buffer - pData = new jbyte[dwBufLen]; + pData = new (env) jbyte[dwBufLen]; + if (pData == NULL) { + __leave; + } env->GetByteArrayRegion(jData, 0, dwBufLen, pData); if (doEncrypt == JNI_TRUE) { @@ -1540,7 +1611,10 @@ __leave; } - pbKeyBlob = new BYTE[dwBlobLen]; + pbKeyBlob = new (env) BYTE[dwBlobLen]; + if (pbKeyBlob == NULL) { + __leave; + } // Generate key blob if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, @@ -1594,8 +1668,12 @@ RSAPUBKEY* pRsaPubKey = (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC)); + int len = sizeof(pRsaPubKey->pubexp); - exponentBytes = new jbyte[len]; + exponentBytes = new (env) jbyte[len]; + if (exponentBytes == NULL) { + __leave; + } // convert from little-endian while copying from blob for (int i = 0, j = len - 1; i < len; i++, j--) { @@ -1646,9 +1724,12 @@ RSAPUBKEY* pRsaPubKey = (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC)); + int len = pRsaPubKey->bitlen / 8; - - modulusBytes = new jbyte[len]; + modulusBytes = new (env) jbyte[len]; + if (modulusBytes == NULL) { + __leave; + } BYTE * pbModulus = (BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY)); @@ -1769,12 +1850,16 @@ (jKeyBitLength / 8); } - jbyte* jBlobBytes = new jbyte[jBlobLength]; + jbyte* jBlobBytes = NULL; jbyte* jBlobElement; jbyteArray jBlob = NULL; jsize jElementLength; __try { + jBlobBytes = new (env) jbyte[jBlobLength]; + if (jBlobBytes == NULL) { + __leave; + } BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes; if (bGeneratePrivateKeyBlob) {