< prev index next >

src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp

Print this page
rev 15549 : [mq]: 8165463-Native-implementation-of-sunmscapi-should-use-operator-new-nothrow-for-allocations


  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 //=--------------------------------------------------------------------------=
  27 // security.cpp    by Stanley Man-Kit Ho
  28 //=--------------------------------------------------------------------------=
  29 //
  30 
  31 #include <jni.h>
  32 #include "jni_util.h"
  33 #include <stdlib.h>
  34 #include <string.h>
  35 #include <windows.h>
  36 #include <BaseTsd.h>
  37 #include <wincrypt.h>
  38 #include <stdio.h>

  39 
  40 
  41 #define OID_EKU_ANY         "2.5.29.37.0"
  42 
  43 #define CERTIFICATE_PARSING_EXCEPTION \
  44                             "java/security/cert/CertificateParsingException"
  45 #define INVALID_KEY_EXCEPTION \
  46                             "java/security/InvalidKeyException"
  47 #define KEY_EXCEPTION       "java/security/KeyException"
  48 #define KEYSTORE_EXCEPTION  "java/security/KeyStoreException"
  49 #define PROVIDER_EXCEPTION  "java/security/ProviderException"
  50 #define SIGNATURE_EXCEPTION "java/security/SignatureException"

  51 
  52 extern "C" {
  53 
  54 /*
  55  * Declare library specific JNI_Onload entry if static build
  56  */
  57 DEF_STATIC_JNI_OnLoad
  58 
  59 /*












  60  * Throws an arbitrary Java exception.
  61  * The exception message is a Windows system error message.
  62  */
  63 void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError)
  64 {
  65     char szMessage[1024];
  66     szMessage[0] = '\0';
  67 
  68     DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
  69         NULL, szMessage, sizeof(szMessage), NULL);
  70     if (res == 0) {
  71         strcpy(szMessage, "Unknown error");
  72     }
  73 
  74     jclass exceptionClazz = env->FindClass(exceptionName);
  75     if (exceptionClazz != NULL) {
  76         env->ThrowNew(exceptionClazz, szMessage);
  77     }
  78 }
  79 













  80 
  81 /*
  82  * Maps the name of a hash algorithm to an algorithm identifier.
  83  */
  84 ALG_ID MapHashAlgorithm(JNIEnv *env, jstring jHashAlgorithm) {
  85 
  86     const char* pszHashAlgorithm = NULL;
  87     ALG_ID algId = 0;
  88 
  89     if ((pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL))
  90         == NULL) {
  91         return algId;
  92     }
  93 
  94     if ((strcmp("SHA", pszHashAlgorithm) == 0) ||
  95         (strcmp("SHA1", pszHashAlgorithm) == 0) ||
  96         (strcmp("SHA-1", pszHashAlgorithm) == 0)) {
  97 
  98         algId = CALG_SHA1;
  99     } else if (strcmp("SHA1+MD5", pszHashAlgorithm) == 0) {


 194          */
 195         if (length < 0) {
 196             length = env->GetArrayLength(seed);
 197             if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
 198                 __leave;
 199             }
 200 
 201             if (::CryptGenRandom(
 202                 hCryptProv,
 203                 length,
 204                 (BYTE *) reseedBytes) == FALSE) {
 205 
 206                 ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
 207                 __leave;
 208             }
 209 
 210             result = NULL;
 211 
 212         } else if (length > 0) {
 213 
 214             pbData = new BYTE[length];



 215 
 216             if (::CryptGenRandom(
 217                 hCryptProv,
 218                 length,
 219                 pbData) == FALSE) {
 220 
 221                 ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
 222                 __leave;
 223             }
 224 
 225             result = env->NewByteArray(length);
 226             env->SetByteArrayRegion(result, 0, length, (jbyte*) pbData);
 227 
 228         } else { // length == 0
 229 
 230             length = env->GetArrayLength(seed);
 231             if ((seedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
 232                 __leave;
 233             }
 234 


 424                     {
 425                         PCERT_CHAIN_ELEMENT rgpElement =
 426                             rgpChain->rgpElement[j];
 427                         PCCERT_CONTEXT pc = rgpElement->pCertContext;
 428 
 429                         // Retrieve the friendly name of the first certificate
 430                         // in the chain
 431                         if (j == 0) {
 432 
 433                             // If the cert's name cannot be retrieved then
 434                             // pszNameString remains set to NULL.
 435                             // (An alias name will be generated automatically
 436                             // when storing this cert in the keystore.)
 437 
 438                             // Get length of friendly name
 439                             if ((cchNameString = CertGetNameString(pc,
 440                                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
 441                                 NULL, 0)) > 1) {
 442 
 443                                 // Found friendly name
 444                                 pszNameString = new char[cchNameString];




 445                                 CertGetNameString(pc,
 446                                     CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
 447                                     pszNameString, cchNameString);
 448                             }
 449                         }
 450 
 451                         BYTE* pbCertEncoded = pc->pbCertEncoded;
 452                         DWORD cbCertEncoded = pc->cbCertEncoded;
 453 
 454                         // Allocate and populate byte array
 455                         jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
 456                         env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
 457                             (jbyte*) pbCertEncoded);
 458 
 459                         // Generate certificate from byte array and store into
 460                         // cert collection
 461                         env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
 462                     }
 463 
 464                     if (bHasNoPrivateKey)


 561 
 562             // Acquire an alternative CSP handle
 563             if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
 564                 PROV_RSA_AES, 0) == FALSE)
 565             {
 566 
 567                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 568                 __leave;
 569             }
 570 
 571             // Acquire a hash object handle.
 572             if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
 573                 &hHash) == FALSE)
 574             {
 575                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 576                 __leave;
 577             }
 578         }
 579 
 580         // Copy hash from Java to native buffer
 581         pHashBuffer = new jbyte[jHashSize];



 582         env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
 583 
 584         // Set hash value in the hash object
 585         if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE)
 586         {
 587             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 588             __leave;
 589         }
 590 
 591         // Determine key spec.
 592         DWORD dwKeySpec = AT_SIGNATURE;
 593         ALG_ID dwAlgId;
 594         DWORD dwAlgIdLen = sizeof(ALG_ID);
 595 
 596         if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
 597             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 598             __leave;
 599 
 600         }
 601         if (CALG_RSA_KEYX == dwAlgId) {
 602             dwKeySpec = AT_KEYEXCHANGE;
 603         }
 604 
 605         // Determine size of buffer
 606         DWORD dwBufLen = 0;
 607         DWORD dwFlags = 0;
 608 
 609         if (noHashOID == JNI_TRUE) {
 610             dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature
 611         }
 612 
 613         if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE)
 614         {
 615             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 616             __leave;
 617         }
 618 
 619         pSignedHashBuffer = new jbyte[dwBufLen];



 620         if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
 621         {
 622             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 623             __leave;
 624         }
 625 
 626         // Create new byte array
 627         jbyteArray temp = env->NewByteArray(dwBufLen);
 628 
 629         // Copy data from native buffer
 630         env->SetByteArrayRegion(temp, 0, dwBufLen, pSignedHashBuffer);
 631 
 632         jSignedHash = temp;
 633     }
 634     __finally
 635     {
 636         if (pSignedHashBuffer)
 637             delete [] pSignedHashBuffer;
 638 
 639         if (pHashBuffer)


 687 
 688             // Acquire an alternative CSP handle
 689             if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
 690                 PROV_RSA_AES, 0) == FALSE)
 691             {
 692 
 693                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 694                 __leave;
 695             }
 696 
 697             // Acquire a hash object handle.
 698             if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
 699                 &hHash) == FALSE)
 700             {
 701                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 702                 __leave;
 703             }
 704         }
 705 
 706         // Copy hash and signedHash from Java to native buffer
 707         pHashBuffer = new jbyte[jHashSize];



 708         env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
 709         pSignedHashBuffer = new jbyte[jSignedHashSize];




 710         env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
 711             pSignedHashBuffer);
 712 
 713         // Set hash value in the hash object
 714         if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL)
 715             == FALSE)
 716         {
 717             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 718             __leave;
 719         }
 720 
 721         // For RSA, the hash encryption algorithm is normally the same as the
 722         // public key algorithm, so AT_SIGNATURE is used.
 723 
 724         // Verify the signature
 725         if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer,
 726             dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE)
 727         {
 728             result = JNI_TRUE;
 729         }


 902     jbyte* pbCertEncoding = NULL;
 903     const jchar* jCertAliasChars = NULL;
 904     const char* pszContainerName = NULL;
 905     const char* pszProviderName = NULL;
 906     WCHAR * pwszContainerName = NULL;
 907     WCHAR * pwszProviderName = NULL;
 908 
 909     __try
 910     {
 911         // Open a system certificate store.
 912         if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
 913             == NULL) {
 914             __leave;
 915         }
 916         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
 917             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 918             __leave;
 919         }
 920 
 921         // Copy encoding from Java to native buffer
 922         pbCertEncoding = new jbyte[jCertEncodingSize];



 923         env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
 924 
 925         // Create a certificate context from the encoded cert
 926         if (!(pCertContext = ::CertCreateCertificateContext(X509_ASN_ENCODING,
 927             (BYTE*) pbCertEncoding, jCertEncodingSize))) {
 928 
 929             ThrowException(env, CERTIFICATE_PARSING_EXCEPTION, GetLastError());
 930             __leave;
 931         }
 932 
 933         // Set the certificate's friendly name
 934         int size = env->GetStringLength(jCertAliasName);
 935         pszCertAliasName = new WCHAR[size + 1];



 936 
 937         jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
 938         memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
 939         pszCertAliasName[size] = 0; // append the string terminator
 940 
 941         CRYPT_DATA_BLOB friendlyName = {
 942             sizeof(WCHAR) * (size + 1),
 943             (BYTE *) pszCertAliasName
 944         };
 945 
 946         env->ReleaseStringChars(jCertAliasName, jCertAliasChars);
 947 
 948         if (! ::CertSetCertificateContextProperty(pCertContext,
 949             CERT_FRIENDLY_NAME_PROP_ID, 0, &friendlyName)) {
 950 
 951             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 952             __leave;
 953         }
 954 
 955         // Attach the certificate's private key (if supplied)
 956         if (hCryptProv != 0 && hCryptKey != 0) {
 957 
 958             CRYPT_KEY_PROV_INFO keyProviderInfo;
 959             DWORD dwDataLen;
 960 
 961             // Get the name of the key container
 962             if (! ::CryptGetProvParam(
 963                 (HCRYPTPROV) hCryptProv,
 964                 PP_CONTAINER,
 965                 NULL,
 966                 &dwDataLen,
 967                 0)) {
 968 
 969                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 970                 __leave;
 971             }
 972 
 973             pszContainerName = new char[dwDataLen];



 974 
 975             if (! ::CryptGetProvParam(
 976                 (HCRYPTPROV) hCryptProv,
 977                 PP_CONTAINER,
 978                 (BYTE *) pszContainerName,
 979                 &dwDataLen,
 980                 0)) {
 981 
 982                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 983                 __leave;
 984             }
 985 
 986             // Convert to a wide char string
 987             pwszContainerName = new WCHAR[dwDataLen];



 988 
 989             if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) {
 990                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 991                 __leave;
 992             }
 993 
 994             // Set the name of the key container
 995             keyProviderInfo.pwszContainerName = pwszContainerName;
 996 
 997 
 998             // Get the name of the provider
 999             if (! ::CryptGetProvParam(
1000                 (HCRYPTPROV) hCryptProv,
1001                 PP_NAME,
1002                 NULL,
1003                 &dwDataLen,
1004                 0)) {
1005 
1006                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1007                 __leave;
1008             }
1009 
1010             pszProviderName = new char[dwDataLen];



1011 
1012             if (! ::CryptGetProvParam(
1013                 (HCRYPTPROV) hCryptProv,
1014                 PP_NAME,
1015                 (BYTE *) pszProviderName,
1016                 &dwDataLen,
1017                 0)) {
1018 
1019                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1020                 __leave;
1021             }
1022 
1023             // Convert to a wide char string
1024             pwszProviderName = new WCHAR[dwDataLen];



1025 
1026             if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) {
1027                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1028                 __leave;
1029             }
1030 
1031             // Set the name of the provider
1032             keyProviderInfo.pwszProvName = pwszProviderName;
1033 
1034             // Get and set the type of the provider
1035             if (! ::CryptGetProvParam(
1036                 (HCRYPTPROV) hCryptProv,
1037                 PP_PROVTYPE,
1038                 (LPBYTE) &keyProviderInfo.dwProvType,
1039                 &dwDataLen,
1040                 0)) {
1041 
1042                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1043                 __leave;
1044             }


1144     PCCERT_CONTEXT pCertContext = NULL;
1145     PCCERT_CONTEXT pTBDCertContext = NULL;
1146     jbyte* pbCertEncoding = NULL;
1147     DWORD cchNameString = 0;
1148     char* pszNameString = NULL; // certificate's friendly name
1149     BOOL bDeleteAttempted = FALSE;
1150 
1151     __try
1152     {
1153         // Open a system certificate store.
1154         if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
1155             == NULL) {
1156             __leave;
1157         }
1158         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
1159             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1160             __leave;
1161         }
1162 
1163         // Copy encoding from Java to native buffer
1164         pbCertEncoding = new jbyte[jCertEncodingSize];



1165         env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
1166 
1167         // Create a certificate context from the encoded cert
1168         if (!(pCertContext = ::CertCreateCertificateContext(X509_ASN_ENCODING,
1169             (BYTE*) pbCertEncoding, jCertEncodingSize))) {
1170 
1171             ThrowException(env, CERTIFICATE_PARSING_EXCEPTION, GetLastError());
1172             __leave;
1173         }
1174 
1175         // Find the certificate to be deleted
1176         if (!(pTBDCertContext = ::CertFindCertificateInStore(hCertStore,
1177             X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL))) {
1178 
1179             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1180             __leave;
1181         }
1182 
1183         // Check that its friendly name matches the supplied alias
1184         if ((cchNameString = ::CertGetNameString(pTBDCertContext,
1185                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) {
1186 
1187             pszNameString = new char[cchNameString];



1188 
1189             ::CertGetNameString(pTBDCertContext,
1190                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
1191                 cchNameString);
1192 
1193             // Compare the certificate's friendly name with supplied alias name
1194             if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
1195                 == NULL) {
1196                 __leave;
1197             }
1198             if (strcmp(pszCertAliasName, pszNameString) == 0) {
1199 
1200                 // Only delete the certificate if the alias names matches
1201                 if (! ::CertDeleteCertificateFromStore(pTBDCertContext)) {
1202 
1203                     // pTBDCertContext is always freed by the
1204                     //  CertDeleteCertificateFromStore method
1205                     bDeleteAttempted = TRUE;
1206 
1207                     ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());


1317             __leave;
1318         }
1319 
1320         // Open a system certificate store.
1321         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
1322             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1323             __leave;
1324         }
1325 
1326         // Use CertEnumCertificatesInStore to get the certificates
1327         // from the open store. pCertContext must be reset to
1328         // NULL to retrieve the first certificate in the store.
1329         while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
1330         {
1331             if ((cchNameString = ::CertGetNameString(pCertContext,
1332                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) == 1) {
1333 
1334                 continue; // not found
1335             }
1336 
1337             pszNameString = new char[cchNameString];



1338 
1339             if (::CertGetNameString(pCertContext,
1340                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
1341                 cchNameString) == 1) {
1342 
1343                 continue; // not found
1344             }
1345 
1346             // Compare the certificate's friendly name with supplied alias name
1347             if (strcmp(pszCertAliasName, pszNameString) == 0) {
1348                 delete [] pszNameString;
1349                 break;
1350 
1351             } else {
1352                 delete [] pszNameString;
1353             }
1354         }
1355     }
1356     __finally
1357     {


1493 
1494 /*
1495  * Class:     sun_security_mscapi_RSACipher
1496  * Method:    encryptDecrypt
1497  * Signature: ([BIJZ)[B
1498  */
1499 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
1500   (JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
1501    jboolean doEncrypt)
1502 {
1503     jbyteArray result = NULL;
1504     jbyte* pData = NULL;
1505     DWORD dwDataLen = jDataSize;
1506     DWORD dwBufLen = env->GetArrayLength(jData);
1507     DWORD i;
1508     BYTE tmp;
1509 
1510     __try
1511     {
1512         // Copy data from Java buffer to native buffer
1513         pData = new jbyte[dwBufLen];



1514         env->GetByteArrayRegion(jData, 0, dwBufLen, pData);
1515 
1516         if (doEncrypt == JNI_TRUE) {
1517             // encrypt
1518             if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
1519                 &dwDataLen, dwBufLen)) {
1520 
1521                 ThrowException(env, KEY_EXCEPTION, GetLastError());
1522                 __leave;
1523             }
1524             dwBufLen = dwDataLen;
1525 
1526             // convert from little-endian
1527             for (i = 0; i < dwBufLen / 2; i++) {
1528                 tmp = pData[i];
1529                 pData[i] = pData[dwBufLen - i -1];
1530                 pData[dwBufLen - i - 1] = tmp;
1531             }
1532         } else {
1533             // convert to little-endian


1567  * Signature: (J)[B
1568  */
1569 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyBlob
1570     (JNIEnv *env, jclass clazz, jlong hCryptKey) {
1571 
1572     jbyteArray blob = NULL;
1573     DWORD dwBlobLen;
1574     BYTE* pbKeyBlob = NULL;
1575 
1576     __try
1577     {
1578 
1579         // Determine the size of the blob
1580         if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL,
1581             &dwBlobLen)) {
1582 
1583             ThrowException(env, KEY_EXCEPTION, GetLastError());
1584             __leave;
1585         }
1586 
1587         pbKeyBlob = new BYTE[dwBlobLen];



1588 
1589         // Generate key blob
1590         if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
1591             pbKeyBlob, &dwBlobLen)) {
1592 
1593             ThrowException(env, KEY_EXCEPTION, GetLastError());
1594             __leave;
1595         }
1596 
1597         // Create new byte array
1598         blob = env->NewByteArray(dwBlobLen);
1599 
1600         // Copy data from native buffer to Java buffer
1601         env->SetByteArrayRegion(blob, 0, dwBlobLen, (jbyte*) pbKeyBlob);
1602     }
1603     __finally
1604     {
1605         if (pbKeyBlob)
1606             delete [] pbKeyBlob;
1607     }


1621     jbyte*     exponentBytes = NULL;
1622     jbyte*     keyBlob = NULL;
1623 
1624     __try {
1625 
1626         jsize length = env->GetArrayLength(jKeyBlob);
1627         if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
1628             __leave;
1629         }
1630 
1631         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
1632 
1633         // Check BLOB type
1634         if (pPublicKeyStruc->bType != PUBLICKEYBLOB) {
1635             ThrowException(env, KEY_EXCEPTION, NTE_BAD_TYPE);
1636             __leave;
1637         }
1638 
1639         RSAPUBKEY* pRsaPubKey =
1640             (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));

1641         int len = sizeof(pRsaPubKey->pubexp);
1642         exponentBytes = new jbyte[len];



1643 
1644         // convert from little-endian while copying from blob
1645         for (int i = 0, j = len - 1; i < len; i++, j--) {
1646             exponentBytes[i] = ((BYTE*) &pRsaPubKey->pubexp)[j];
1647         }
1648 
1649         exponent = env->NewByteArray(len);
1650         env->SetByteArrayRegion(exponent, 0, len, exponentBytes);
1651     }
1652     __finally
1653     {
1654         if (keyBlob)
1655             env->ReleaseByteArrayElements(jKeyBlob, keyBlob, JNI_ABORT);
1656 
1657         if (exponentBytes)
1658             delete [] exponentBytes;
1659     }
1660 
1661     return exponent;
1662 }


1673     jbyte*     modulusBytes = NULL;
1674     jbyte*     keyBlob = NULL;
1675 
1676     __try {
1677 
1678         jsize length = env->GetArrayLength(jKeyBlob);
1679         if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
1680             __leave;
1681         }
1682 
1683         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
1684 
1685         // Check BLOB type
1686         if (pPublicKeyStruc->bType != PUBLICKEYBLOB) {
1687             ThrowException(env, KEY_EXCEPTION, NTE_BAD_TYPE);
1688             __leave;
1689         }
1690 
1691         RSAPUBKEY* pRsaPubKey =
1692             (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
1693         int len = pRsaPubKey->bitlen / 8;
1694 
1695         modulusBytes = new jbyte[len];




1696         BYTE * pbModulus =
1697             (BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
1698 
1699         // convert from little-endian while copying from blob
1700         for (int i = 0, j = len - 1; i < len; i++, j--) {
1701             modulusBytes[i] = pbModulus[j];
1702         }
1703 
1704         modulus = env->NewByteArray(len);
1705         env->SetByteArrayRegion(modulus, 0, len, modulusBytes);
1706     }
1707     __finally
1708     {
1709         if (keyBlob)
1710             env->ReleaseByteArrayElements(jKeyBlob, keyBlob, JNI_ABORT);
1711 
1712         if (modulusBytes)
1713             delete [] modulusBytes;
1714     }
1715 


1796     if (jPrivateExponent != NULL &&
1797         jPrimeP != NULL &&
1798         jPrimeQ != NULL &&
1799         jExponentP != NULL &&
1800         jExponentQ != NULL &&
1801         jCrtCoefficient != NULL) {
1802 
1803         bGeneratePrivateKeyBlob = TRUE;
1804         jBlobLength = sizeof(BLOBHEADER) +
1805                         sizeof(RSAPUBKEY) +
1806                         ((jKeyBitLength / 8) * 4) +
1807                         (jKeyBitLength / 16);
1808 
1809     } else {
1810         bGeneratePrivateKeyBlob = FALSE;
1811         jBlobLength = sizeof(BLOBHEADER) +
1812                         sizeof(RSAPUBKEY) +
1813                         (jKeyBitLength / 8);
1814     }
1815 
1816     jbyte* jBlobBytes = new jbyte[jBlobLength];
1817     jbyte* jBlobElement;
1818     jbyteArray jBlob = NULL;
1819     jsize  jElementLength;
1820 
1821     __try {




1822 
1823         BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes;
1824         if (bGeneratePrivateKeyBlob) {
1825             pBlobHeader->bType = PRIVATEKEYBLOB;  // 0x07
1826         } else {
1827             pBlobHeader->bType = PUBLICKEYBLOB;   // 0x06
1828         }
1829         pBlobHeader->bVersion = CUR_BLOB_VERSION; // 0x02
1830         pBlobHeader->reserved = 0;                // 0x0000
1831         pBlobHeader->aiKeyAlg = CALG_RSA_KEYX;    // 0x0000a400
1832 
1833         RSAPUBKEY *pRsaPubKey =
1834             (RSAPUBKEY *) (jBlobBytes + sizeof(PUBLICKEYSTRUC));
1835         if (bGeneratePrivateKeyBlob) {
1836             pRsaPubKey->magic = 0x32415352;       // "RSA2"
1837         } else {
1838             pRsaPubKey->magic = 0x31415352;       // "RSA1"
1839         }
1840         pRsaPubKey->bitlen = jKeyBitLength;
1841         pRsaPubKey->pubexp = 0; // init




  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 //=--------------------------------------------------------------------------=
  27 // security.cpp    by Stanley Man-Kit Ho
  28 //=--------------------------------------------------------------------------=
  29 //
  30 
  31 #include <jni.h>
  32 #include "jni_util.h"
  33 #include <stdlib.h>
  34 #include <string.h>
  35 #include <windows.h>
  36 #include <BaseTsd.h>
  37 #include <wincrypt.h>
  38 #include <stdio.h>
  39 #include <memory>
  40 
  41 
  42 #define OID_EKU_ANY         "2.5.29.37.0"
  43 
  44 #define CERTIFICATE_PARSING_EXCEPTION \
  45                             "java/security/cert/CertificateParsingException"
  46 #define INVALID_KEY_EXCEPTION \
  47                             "java/security/InvalidKeyException"
  48 #define KEY_EXCEPTION       "java/security/KeyException"
  49 #define KEYSTORE_EXCEPTION  "java/security/KeyStoreException"
  50 #define PROVIDER_EXCEPTION  "java/security/ProviderException"
  51 #define SIGNATURE_EXCEPTION "java/security/SignatureException"
  52 #define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"
  53 
  54 extern "C" {
  55 
  56 /*
  57  * Declare library specific JNI_Onload entry if static build
  58  */
  59 DEF_STATIC_JNI_OnLoad
  60 
  61 /*
  62  * Throws an arbitrary Java exception with the given message.
  63  */
  64 void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName,
  65                                const char *szMessage)
  66 {
  67     jclass exceptionClazz = env->FindClass(exceptionName);
  68     if (exceptionClazz != NULL) {
  69         env->ThrowNew(exceptionClazz, szMessage);
  70     }
  71 }
  72 
  73 /*
  74  * Throws an arbitrary Java exception.
  75  * The exception message is a Windows system error message.
  76  */
  77 void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError)
  78 {
  79     char szMessage[1024];
  80     szMessage[0] = '\0';
  81 
  82     DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError,
  83         NULL, szMessage, sizeof(szMessage), NULL);
  84     if (res == 0) {
  85         strcpy(szMessage, "Unknown error");
  86     }
  87 
  88     ThrowExceptionWithMessage(env, exceptionName, szMessage);



  89 }
  90 
  91 /*
  92  * Overloaded 'operator new[]' variant, which will raise Java's
  93  * OutOfMemoryError in a case of the failure.
  94  */
  95 static void* operator new[](std::size_t size, JNIEnv *env)
  96 {
  97     void* buf = ::operator new[](size, std::nothrow);
  98     if (buf == NULL) {
  99         ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR,
 100                 "native memory allocation failed");
 101     }
 102     return buf;
 103 }
 104 
 105 /*
 106  * Maps the name of a hash algorithm to an algorithm identifier.
 107  */
 108 ALG_ID MapHashAlgorithm(JNIEnv *env, jstring jHashAlgorithm) {
 109 
 110     const char* pszHashAlgorithm = NULL;
 111     ALG_ID algId = 0;
 112 
 113     if ((pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL))
 114         == NULL) {
 115         return algId;
 116     }
 117 
 118     if ((strcmp("SHA", pszHashAlgorithm) == 0) ||
 119         (strcmp("SHA1", pszHashAlgorithm) == 0) ||
 120         (strcmp("SHA-1", pszHashAlgorithm) == 0)) {
 121 
 122         algId = CALG_SHA1;
 123     } else if (strcmp("SHA1+MD5", pszHashAlgorithm) == 0) {


 218          */
 219         if (length < 0) {
 220             length = env->GetArrayLength(seed);
 221             if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
 222                 __leave;
 223             }
 224 
 225             if (::CryptGenRandom(
 226                 hCryptProv,
 227                 length,
 228                 (BYTE *) reseedBytes) == FALSE) {
 229 
 230                 ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
 231                 __leave;
 232             }
 233 
 234             result = NULL;
 235 
 236         } else if (length > 0) {
 237 
 238             pbData = new (env) BYTE[length];
 239             if (pbData == NULL) {
 240                 __leave;
 241             }
 242 
 243             if (::CryptGenRandom(
 244                 hCryptProv,
 245                 length,
 246                 pbData) == FALSE) {
 247 
 248                 ThrowException(env, PROVIDER_EXCEPTION, GetLastError());
 249                 __leave;
 250             }
 251 
 252             result = env->NewByteArray(length);
 253             env->SetByteArrayRegion(result, 0, length, (jbyte*) pbData);
 254 
 255         } else { // length == 0
 256 
 257             length = env->GetArrayLength(seed);
 258             if ((seedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
 259                 __leave;
 260             }
 261 


 451                     {
 452                         PCERT_CHAIN_ELEMENT rgpElement =
 453                             rgpChain->rgpElement[j];
 454                         PCCERT_CONTEXT pc = rgpElement->pCertContext;
 455 
 456                         // Retrieve the friendly name of the first certificate
 457                         // in the chain
 458                         if (j == 0) {
 459 
 460                             // If the cert's name cannot be retrieved then
 461                             // pszNameString remains set to NULL.
 462                             // (An alias name will be generated automatically
 463                             // when storing this cert in the keystore.)
 464 
 465                             // Get length of friendly name
 466                             if ((cchNameString = CertGetNameString(pc,
 467                                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
 468                                 NULL, 0)) > 1) {
 469 
 470                                 // Found friendly name
 471                                 pszNameString = new (env) char[cchNameString];
 472                                 if (pszNameString == NULL) {
 473                                     __leave;
 474                                 }
 475 
 476                                 CertGetNameString(pc,
 477                                     CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
 478                                     pszNameString, cchNameString);
 479                             }
 480                         }
 481 
 482                         BYTE* pbCertEncoded = pc->pbCertEncoded;
 483                         DWORD cbCertEncoded = pc->cbCertEncoded;
 484 
 485                         // Allocate and populate byte array
 486                         jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
 487                         env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
 488                             (jbyte*) pbCertEncoded);
 489 
 490                         // Generate certificate from byte array and store into
 491                         // cert collection
 492                         env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
 493                     }
 494 
 495                     if (bHasNoPrivateKey)


 592 
 593             // Acquire an alternative CSP handle
 594             if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
 595                 PROV_RSA_AES, 0) == FALSE)
 596             {
 597 
 598                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 599                 __leave;
 600             }
 601 
 602             // Acquire a hash object handle.
 603             if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
 604                 &hHash) == FALSE)
 605             {
 606                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 607                 __leave;
 608             }
 609         }
 610 
 611         // Copy hash from Java to native buffer
 612         pHashBuffer = new (env) jbyte[jHashSize];
 613         if (pHashBuffer == NULL) {
 614             __leave;
 615         }
 616         env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
 617 
 618         // Set hash value in the hash object
 619         if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)pHashBuffer, NULL) == FALSE)
 620         {
 621             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 622             __leave;
 623         }
 624 
 625         // Determine key spec.
 626         DWORD dwKeySpec = AT_SIGNATURE;
 627         ALG_ID dwAlgId;
 628         DWORD dwAlgIdLen = sizeof(ALG_ID);
 629 
 630         if (! ::CryptGetKeyParam((HCRYPTKEY) hCryptKey, KP_ALGID, (BYTE*)&dwAlgId, &dwAlgIdLen, 0)) {
 631             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 632             __leave;
 633 
 634         }
 635         if (CALG_RSA_KEYX == dwAlgId) {
 636             dwKeySpec = AT_KEYEXCHANGE;
 637         }
 638 
 639         // Determine size of buffer
 640         DWORD dwBufLen = 0;
 641         DWORD dwFlags = 0;
 642 
 643         if (noHashOID == JNI_TRUE) {
 644             dwFlags = CRYPT_NOHASHOID; // omit hash OID in NONEwithRSA signature
 645         }
 646 
 647         if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, NULL, &dwBufLen) == FALSE)
 648         {
 649             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 650             __leave;
 651         }
 652 
 653         pSignedHashBuffer = new (env) jbyte[dwBufLen];
 654         if (pSignedHashBuffer == NULL) {
 655             __leave;
 656         }
 657         if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
 658         {
 659             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 660             __leave;
 661         }
 662 
 663         // Create new byte array
 664         jbyteArray temp = env->NewByteArray(dwBufLen);
 665 
 666         // Copy data from native buffer
 667         env->SetByteArrayRegion(temp, 0, dwBufLen, pSignedHashBuffer);
 668 
 669         jSignedHash = temp;
 670     }
 671     __finally
 672     {
 673         if (pSignedHashBuffer)
 674             delete [] pSignedHashBuffer;
 675 
 676         if (pHashBuffer)


 724 
 725             // Acquire an alternative CSP handle
 726             if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
 727                 PROV_RSA_AES, 0) == FALSE)
 728             {
 729 
 730                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 731                 __leave;
 732             }
 733 
 734             // Acquire a hash object handle.
 735             if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
 736                 &hHash) == FALSE)
 737             {
 738                 ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 739                 __leave;
 740             }
 741         }
 742 
 743         // Copy hash and signedHash from Java to native buffer
 744         pHashBuffer = new (env) jbyte[jHashSize];
 745         if (pHashBuffer == NULL) {
 746             __leave;
 747         }
 748         env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
 749 
 750         pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
 751         if (pSignedHashBuffer == NULL) {
 752             __leave;
 753         }
 754         env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
 755             pSignedHashBuffer);
 756 
 757         // Set hash value in the hash object
 758         if (::CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*) pHashBuffer, NULL)
 759             == FALSE)
 760         {
 761             ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
 762             __leave;
 763         }
 764 
 765         // For RSA, the hash encryption algorithm is normally the same as the
 766         // public key algorithm, so AT_SIGNATURE is used.
 767 
 768         // Verify the signature
 769         if (::CryptVerifySignatureA(hHash, (BYTE *) pSignedHashBuffer,
 770             dwSignedHashBufferLen, (HCRYPTKEY) hCryptKey, NULL, 0) == TRUE)
 771         {
 772             result = JNI_TRUE;
 773         }


 946     jbyte* pbCertEncoding = NULL;
 947     const jchar* jCertAliasChars = NULL;
 948     const char* pszContainerName = NULL;
 949     const char* pszProviderName = NULL;
 950     WCHAR * pwszContainerName = NULL;
 951     WCHAR * pwszProviderName = NULL;
 952 
 953     __try
 954     {
 955         // Open a system certificate store.
 956         if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
 957             == NULL) {
 958             __leave;
 959         }
 960         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
 961             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
 962             __leave;
 963         }
 964 
 965         // Copy encoding from Java to native buffer
 966         pbCertEncoding = new (env) jbyte[jCertEncodingSize];
 967         if (pbCertEncoding == NULL) {
 968             __leave;
 969         }
 970         env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
 971 
 972         // Create a certificate context from the encoded cert
 973         if (!(pCertContext = ::CertCreateCertificateContext(X509_ASN_ENCODING,
 974             (BYTE*) pbCertEncoding, jCertEncodingSize))) {
 975 
 976             ThrowException(env, CERTIFICATE_PARSING_EXCEPTION, GetLastError());
 977             __leave;
 978         }
 979 
 980         // Set the certificate's friendly name
 981         int size = env->GetStringLength(jCertAliasName);
 982         pszCertAliasName = new (env) WCHAR[size + 1];
 983         if (pszCertAliasName == NULL) {
 984             __leave;
 985         }
 986 
 987         jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
 988         memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
 989         pszCertAliasName[size] = 0; // append the string terminator
 990 
 991         CRYPT_DATA_BLOB friendlyName = {
 992             sizeof(WCHAR) * (size + 1),
 993             (BYTE *) pszCertAliasName
 994         };
 995 
 996         env->ReleaseStringChars(jCertAliasName, jCertAliasChars);
 997 
 998         if (! ::CertSetCertificateContextProperty(pCertContext,
 999             CERT_FRIENDLY_NAME_PROP_ID, 0, &friendlyName)) {
1000 
1001             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1002             __leave;
1003         }
1004 
1005         // Attach the certificate's private key (if supplied)
1006         if (hCryptProv != 0 && hCryptKey != 0) {
1007 
1008             CRYPT_KEY_PROV_INFO keyProviderInfo;
1009             DWORD dwDataLen;
1010 
1011             // Get the name of the key container
1012             if (! ::CryptGetProvParam(
1013                 (HCRYPTPROV) hCryptProv,
1014                 PP_CONTAINER,
1015                 NULL,
1016                 &dwDataLen,
1017                 0)) {
1018 
1019                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1020                 __leave;
1021             }
1022 
1023             pszContainerName = new (env) char[dwDataLen];
1024             if (pszContainerName == NULL) {
1025                 __leave;
1026             }
1027 
1028             if (! ::CryptGetProvParam(
1029                 (HCRYPTPROV) hCryptProv,
1030                 PP_CONTAINER,
1031                 (BYTE *) pszContainerName,
1032                 &dwDataLen,
1033                 0)) {
1034 
1035                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1036                 __leave;
1037             }
1038 
1039             // Convert to a wide char string
1040             pwszContainerName = new (env) WCHAR[dwDataLen];
1041             if (pwszContainerName == NULL) {
1042                 __leave;
1043             }
1044 
1045             if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) {
1046                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1047                 __leave;
1048             }
1049 
1050             // Set the name of the key container
1051             keyProviderInfo.pwszContainerName = pwszContainerName;
1052 
1053 
1054             // Get the name of the provider
1055             if (! ::CryptGetProvParam(
1056                 (HCRYPTPROV) hCryptProv,
1057                 PP_NAME,
1058                 NULL,
1059                 &dwDataLen,
1060                 0)) {
1061 
1062                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1063                 __leave;
1064             }
1065 
1066             pszProviderName = new (env) char[dwDataLen];
1067             if (pszProviderName == NULL) {
1068                 __leave;
1069             }
1070 
1071             if (! ::CryptGetProvParam(
1072                 (HCRYPTPROV) hCryptProv,
1073                 PP_NAME,
1074                 (BYTE *) pszProviderName,
1075                 &dwDataLen,
1076                 0)) {
1077 
1078                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1079                 __leave;
1080             }
1081 
1082             // Convert to a wide char string
1083             pwszProviderName = new (env) WCHAR[dwDataLen];
1084             if (pwszProviderName == NULL) {
1085                 __leave;
1086             }
1087 
1088             if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) {
1089                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1090                 __leave;
1091             }
1092 
1093             // Set the name of the provider
1094             keyProviderInfo.pwszProvName = pwszProviderName;
1095 
1096             // Get and set the type of the provider
1097             if (! ::CryptGetProvParam(
1098                 (HCRYPTPROV) hCryptProv,
1099                 PP_PROVTYPE,
1100                 (LPBYTE) &keyProviderInfo.dwProvType,
1101                 &dwDataLen,
1102                 0)) {
1103 
1104                 ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1105                 __leave;
1106             }


1206     PCCERT_CONTEXT pCertContext = NULL;
1207     PCCERT_CONTEXT pTBDCertContext = NULL;
1208     jbyte* pbCertEncoding = NULL;
1209     DWORD cchNameString = 0;
1210     char* pszNameString = NULL; // certificate's friendly name
1211     BOOL bDeleteAttempted = FALSE;
1212 
1213     __try
1214     {
1215         // Open a system certificate store.
1216         if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
1217             == NULL) {
1218             __leave;
1219         }
1220         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
1221             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1222             __leave;
1223         }
1224 
1225         // Copy encoding from Java to native buffer
1226         pbCertEncoding = new (env) jbyte[jCertEncodingSize];
1227         if (pbCertEncoding == NULL) {
1228             __leave;
1229         }
1230         env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
1231 
1232         // Create a certificate context from the encoded cert
1233         if (!(pCertContext = ::CertCreateCertificateContext(X509_ASN_ENCODING,
1234             (BYTE*) pbCertEncoding, jCertEncodingSize))) {
1235 
1236             ThrowException(env, CERTIFICATE_PARSING_EXCEPTION, GetLastError());
1237             __leave;
1238         }
1239 
1240         // Find the certificate to be deleted
1241         if (!(pTBDCertContext = ::CertFindCertificateInStore(hCertStore,
1242             X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL))) {
1243 
1244             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1245             __leave;
1246         }
1247 
1248         // Check that its friendly name matches the supplied alias
1249         if ((cchNameString = ::CertGetNameString(pTBDCertContext,
1250                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) {
1251 
1252             pszNameString = new (env) char[cchNameString];
1253             if (pszNameString == NULL) {
1254                 __leave;
1255             }
1256 
1257             ::CertGetNameString(pTBDCertContext,
1258                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
1259                 cchNameString);
1260 
1261             // Compare the certificate's friendly name with supplied alias name
1262             if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
1263                 == NULL) {
1264                 __leave;
1265             }
1266             if (strcmp(pszCertAliasName, pszNameString) == 0) {
1267 
1268                 // Only delete the certificate if the alias names matches
1269                 if (! ::CertDeleteCertificateFromStore(pTBDCertContext)) {
1270 
1271                     // pTBDCertContext is always freed by the
1272                     //  CertDeleteCertificateFromStore method
1273                     bDeleteAttempted = TRUE;
1274 
1275                     ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());


1385             __leave;
1386         }
1387 
1388         // Open a system certificate store.
1389         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
1390             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
1391             __leave;
1392         }
1393 
1394         // Use CertEnumCertificatesInStore to get the certificates
1395         // from the open store. pCertContext must be reset to
1396         // NULL to retrieve the first certificate in the store.
1397         while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
1398         {
1399             if ((cchNameString = ::CertGetNameString(pCertContext,
1400                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) == 1) {
1401 
1402                 continue; // not found
1403             }
1404 
1405             pszNameString = new (env) char[cchNameString];
1406             if (pszNameString == NULL) {
1407                 __leave;
1408             }
1409 
1410             if (::CertGetNameString(pCertContext,
1411                 CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
1412                 cchNameString) == 1) {
1413 
1414                 continue; // not found
1415             }
1416 
1417             // Compare the certificate's friendly name with supplied alias name
1418             if (strcmp(pszCertAliasName, pszNameString) == 0) {
1419                 delete [] pszNameString;
1420                 break;
1421 
1422             } else {
1423                 delete [] pszNameString;
1424             }
1425         }
1426     }
1427     __finally
1428     {


1564 
1565 /*
1566  * Class:     sun_security_mscapi_RSACipher
1567  * Method:    encryptDecrypt
1568  * Signature: ([BIJZ)[B
1569  */
1570 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt
1571   (JNIEnv *env, jclass clazz, jbyteArray jData, jint jDataSize, jlong hKey,
1572    jboolean doEncrypt)
1573 {
1574     jbyteArray result = NULL;
1575     jbyte* pData = NULL;
1576     DWORD dwDataLen = jDataSize;
1577     DWORD dwBufLen = env->GetArrayLength(jData);
1578     DWORD i;
1579     BYTE tmp;
1580 
1581     __try
1582     {
1583         // Copy data from Java buffer to native buffer
1584         pData = new (env) jbyte[dwBufLen];
1585         if (pData == NULL) {
1586             __leave;
1587         }
1588         env->GetByteArrayRegion(jData, 0, dwBufLen, pData);
1589 
1590         if (doEncrypt == JNI_TRUE) {
1591             // encrypt
1592             if (! ::CryptEncrypt((HCRYPTKEY) hKey, 0, TRUE, 0, (BYTE *)pData,
1593                 &dwDataLen, dwBufLen)) {
1594 
1595                 ThrowException(env, KEY_EXCEPTION, GetLastError());
1596                 __leave;
1597             }
1598             dwBufLen = dwDataLen;
1599 
1600             // convert from little-endian
1601             for (i = 0; i < dwBufLen / 2; i++) {
1602                 tmp = pData[i];
1603                 pData[i] = pData[dwBufLen - i -1];
1604                 pData[dwBufLen - i - 1] = tmp;
1605             }
1606         } else {
1607             // convert to little-endian


1641  * Signature: (J)[B
1642  */
1643 JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyBlob
1644     (JNIEnv *env, jclass clazz, jlong hCryptKey) {
1645 
1646     jbyteArray blob = NULL;
1647     DWORD dwBlobLen;
1648     BYTE* pbKeyBlob = NULL;
1649 
1650     __try
1651     {
1652 
1653         // Determine the size of the blob
1654         if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, NULL,
1655             &dwBlobLen)) {
1656 
1657             ThrowException(env, KEY_EXCEPTION, GetLastError());
1658             __leave;
1659         }
1660 
1661         pbKeyBlob = new (env) BYTE[dwBlobLen];
1662         if (pbKeyBlob == NULL) {
1663             __leave;
1664         }
1665 
1666         // Generate key blob
1667         if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
1668             pbKeyBlob, &dwBlobLen)) {
1669 
1670             ThrowException(env, KEY_EXCEPTION, GetLastError());
1671             __leave;
1672         }
1673 
1674         // Create new byte array
1675         blob = env->NewByteArray(dwBlobLen);
1676 
1677         // Copy data from native buffer to Java buffer
1678         env->SetByteArrayRegion(blob, 0, dwBlobLen, (jbyte*) pbKeyBlob);
1679     }
1680     __finally
1681     {
1682         if (pbKeyBlob)
1683             delete [] pbKeyBlob;
1684     }


1698     jbyte*     exponentBytes = NULL;
1699     jbyte*     keyBlob = NULL;
1700 
1701     __try {
1702 
1703         jsize length = env->GetArrayLength(jKeyBlob);
1704         if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
1705             __leave;
1706         }
1707 
1708         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
1709 
1710         // Check BLOB type
1711         if (pPublicKeyStruc->bType != PUBLICKEYBLOB) {
1712             ThrowException(env, KEY_EXCEPTION, NTE_BAD_TYPE);
1713             __leave;
1714         }
1715 
1716         RSAPUBKEY* pRsaPubKey =
1717             (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
1718 
1719         int len = sizeof(pRsaPubKey->pubexp);
1720         exponentBytes = new (env) jbyte[len];
1721         if (exponentBytes == NULL) {
1722             __leave;
1723         }
1724 
1725         // convert from little-endian while copying from blob
1726         for (int i = 0, j = len - 1; i < len; i++, j--) {
1727             exponentBytes[i] = ((BYTE*) &pRsaPubKey->pubexp)[j];
1728         }
1729 
1730         exponent = env->NewByteArray(len);
1731         env->SetByteArrayRegion(exponent, 0, len, exponentBytes);
1732     }
1733     __finally
1734     {
1735         if (keyBlob)
1736             env->ReleaseByteArrayElements(jKeyBlob, keyBlob, JNI_ABORT);
1737 
1738         if (exponentBytes)
1739             delete [] exponentBytes;
1740     }
1741 
1742     return exponent;
1743 }


1754     jbyte*     modulusBytes = NULL;
1755     jbyte*     keyBlob = NULL;
1756 
1757     __try {
1758 
1759         jsize length = env->GetArrayLength(jKeyBlob);
1760         if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
1761             __leave;
1762         }
1763 
1764         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
1765 
1766         // Check BLOB type
1767         if (pPublicKeyStruc->bType != PUBLICKEYBLOB) {
1768             ThrowException(env, KEY_EXCEPTION, NTE_BAD_TYPE);
1769             __leave;
1770         }
1771 
1772         RSAPUBKEY* pRsaPubKey =
1773             (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));

1774 
1775         int len = pRsaPubKey->bitlen / 8;
1776         modulusBytes = new (env) jbyte[len];
1777         if (modulusBytes == NULL) {
1778             __leave;
1779         }
1780         BYTE * pbModulus =
1781             (BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
1782 
1783         // convert from little-endian while copying from blob
1784         for (int i = 0, j = len - 1; i < len; i++, j--) {
1785             modulusBytes[i] = pbModulus[j];
1786         }
1787 
1788         modulus = env->NewByteArray(len);
1789         env->SetByteArrayRegion(modulus, 0, len, modulusBytes);
1790     }
1791     __finally
1792     {
1793         if (keyBlob)
1794             env->ReleaseByteArrayElements(jKeyBlob, keyBlob, JNI_ABORT);
1795 
1796         if (modulusBytes)
1797             delete [] modulusBytes;
1798     }
1799 


1880     if (jPrivateExponent != NULL &&
1881         jPrimeP != NULL &&
1882         jPrimeQ != NULL &&
1883         jExponentP != NULL &&
1884         jExponentQ != NULL &&
1885         jCrtCoefficient != NULL) {
1886 
1887         bGeneratePrivateKeyBlob = TRUE;
1888         jBlobLength = sizeof(BLOBHEADER) +
1889                         sizeof(RSAPUBKEY) +
1890                         ((jKeyBitLength / 8) * 4) +
1891                         (jKeyBitLength / 16);
1892 
1893     } else {
1894         bGeneratePrivateKeyBlob = FALSE;
1895         jBlobLength = sizeof(BLOBHEADER) +
1896                         sizeof(RSAPUBKEY) +
1897                         (jKeyBitLength / 8);
1898     }
1899 
1900     jbyte* jBlobBytes;
1901     jbyte* jBlobElement;
1902     jbyteArray jBlob = NULL;
1903     jsize  jElementLength;
1904 
1905     __try {
1906         jBlobBytes = new (env) jbyte[jBlobLength];
1907         if (jBlobBytes == NULL) {
1908             __leave;
1909         }
1910 
1911         BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes;
1912         if (bGeneratePrivateKeyBlob) {
1913             pBlobHeader->bType = PRIVATEKEYBLOB;  // 0x07
1914         } else {
1915             pBlobHeader->bType = PUBLICKEYBLOB;   // 0x06
1916         }
1917         pBlobHeader->bVersion = CUR_BLOB_VERSION; // 0x02
1918         pBlobHeader->reserved = 0;                // 0x0000
1919         pBlobHeader->aiKeyAlg = CALG_RSA_KEYX;    // 0x0000a400
1920 
1921         RSAPUBKEY *pRsaPubKey =
1922             (RSAPUBKEY *) (jBlobBytes + sizeof(PUBLICKEYSTRUC));
1923         if (bGeneratePrivateKeyBlob) {
1924             pRsaPubKey->magic = 0x32415352;       // "RSA2"
1925         } else {
1926             pRsaPubKey->magic = 0x31415352;       // "RSA1"
1927         }
1928         pRsaPubKey->bitlen = jKeyBitLength;
1929         pRsaPubKey->pubexp = 0; // init


< prev index next >