< prev index next >

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

Print this page
rev 13981 : imported patch 6483657-MSCAPI-provider-does-not-create-unique-alias-names
   1 /*
   2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  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


 255         if (pbData)
 256             delete [] pbData;
 257 
 258         if (seedBytes)
 259             env->ReleaseByteArrayElements(seed, seedBytes, 0); // update orig
 260 
 261         if (hCryptProv)
 262             ::CryptReleaseContext(hCryptProv, 0);
 263     }
 264 
 265     return result;
 266 }
 267 
 268 
 269 /*
 270  * Class:     sun_security_mscapi_KeyStore
 271  * Method:    loadKeysOrCertificateChains
 272  * Signature: (Ljava/lang/String;Ljava/util/Collection;)V
 273  */
 274 JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains
 275   (JNIEnv *env, jobject obj, jstring jCertStoreName, jobject jCollections)
 276 {
 277     /**
 278      * Certificate in cert store has enhanced key usage extension
 279      * property (or EKU property) that is not part of the certificate itself. To determine
 280      * if the certificate should be returned, both the enhanced key usage in certificate
 281      * extension block and the extension property stored along with the certificate in
 282      * certificate store should be examined. Otherwise, we won't be able to determine
 283      * the proper key usage from the Java side because the information is not stored as
 284      * part of the encoded certificate.
 285      */
 286 
 287     const char* pszCertStoreName = NULL;
 288     HCERTSTORE hCertStore = NULL;
 289     PCCERT_CONTEXT pCertContext = NULL;
 290     char* pszNameString = NULL; // certificate's friendly name
 291     DWORD cchNameString = 0;
 292 
 293 
 294     __try
 295     {


 314         jmethodID mNewArrayList = env->GetMethodID(clazzArrayList, "<init>", "()V");
 315         if (mNewArrayList == NULL) {
 316             __leave;
 317         }
 318 
 319         jclass clazzOfThis = env->GetObjectClass(obj);
 320         if (clazzOfThis == NULL) {
 321             __leave;
 322         }
 323 
 324         jmethodID mGenCert = env->GetMethodID(clazzOfThis,
 325                                               "generateCertificate",
 326                                               "([BLjava/util/Collection;)V");
 327         if (mGenCert == NULL) {
 328             __leave;
 329         }
 330 
 331         // Determine method ID to generate certificate chain
 332         jmethodID mGenCertChain = env->GetMethodID(clazzOfThis,
 333                                                    "generateCertificateChain",
 334                                                    "(Ljava/lang/String;Ljava/util/Collection;Ljava/util/Collection;)V");
 335         if (mGenCertChain == NULL) {
 336             __leave;
 337         }
 338 
 339         // Determine method ID to generate RSA certificate chain
 340         jmethodID mGenRSAKeyAndCertChain = env->GetMethodID(clazzOfThis,
 341                                                    "generateRSAKeyAndCertificateChain",
 342                                                    "(Ljava/lang/String;JJILjava/util/Collection;Ljava/util/Collection;)V");
 343         if (mGenRSAKeyAndCertChain == NULL) {
 344             __leave;
 345         }
 346 
 347         // Use CertEnumCertificatesInStore to get the certificates
 348         // from the open store. pCertContext must be reset to
 349         // NULL to retrieve the first certificate in the store.
 350         while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
 351         {
 352             // Check if private key available - client authentication certificate
 353             // must have private key available.
 354             HCRYPTPROV hCryptProv = NULL;
 355             DWORD dwKeySpec = 0;
 356             HCRYPTKEY hUserKey = NULL;
 357             BOOL bCallerFreeProv = FALSE;
 358             BOOL bHasNoPrivateKey = FALSE;
 359             DWORD dwPublicKeyLength = 0;
 360 
 361             if (::CryptAcquireCertificatePrivateKey(pCertContext, NULL, NULL,
 362                                                     &hCryptProv, &dwKeySpec, &bCallerFreeProv) == FALSE)


 373             {
 374                 if (bCallerFreeProv)
 375                     ::CryptReleaseContext(hCryptProv, NULL);
 376 
 377                 continue;
 378             }
 379 
 380             // Set cipher mode to ECB
 381             DWORD dwCipherMode = CRYPT_MODE_ECB;
 382             ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
 383 
 384 
 385             // If the private key is present in smart card, we may not be able to
 386             // determine the key length by using the private key handle. However,
 387             // since public/private key pairs must have the same length, we could
 388             // determine the key length of the private key by using the public key
 389             // in the certificate.
 390             dwPublicKeyLength = ::CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 391                                                                &(pCertContext->pCertInfo->SubjectPublicKeyInfo));
 392 
 393 }
 394             PCCERT_CHAIN_CONTEXT pCertChainContext = NULL;
 395 
 396             // Build certificate chain by using system certificate store.
 397             // Add cert chain into collection for any key usage.
 398             //
 399             if (GetCertificateChain(OID_EKU_ANY, pCertContext,
 400                 &pCertChainContext))
 401             {
 402 
 403                 for (unsigned int i=0; i < pCertChainContext->cChain; i++)
 404                 {
 405                     // Found cert chain
 406                     PCERT_SIMPLE_CHAIN rgpChain =
 407                         pCertChainContext->rgpChain[i];
 408 
 409                     // Create ArrayList to store certs in each chain
 410                     jobject jArrayList =
 411                         env->NewObject(clazzArrayList, mNewArrayList);
 412 
 413                     for (unsigned int j=0; j < rgpChain->cElement; j++)
 414                     {
 415                         PCERT_CHAIN_ELEMENT rgpElement =
 416                             rgpChain->rgpElement[j];
 417                         PCCERT_CONTEXT pc = rgpElement->pCertContext;
 418 
 419                         // Retrieve the friendly name of the first certificate
 420                         // in the chain


 439                         }
 440 
 441                         BYTE* pbCertEncoded = pc->pbCertEncoded;
 442                         DWORD cbCertEncoded = pc->cbCertEncoded;
 443 
 444                         // Allocate and populate byte array
 445                         jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
 446                         env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
 447                             (jbyte*) pbCertEncoded);
 448 
 449                         // Generate certificate from byte array and store into
 450                         // cert collection
 451                         env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
 452                     }
 453                     if (bHasNoPrivateKey)
 454                     {
 455                         // Generate certificate chain and store into cert chain
 456                         // collection
 457                         env->CallVoidMethod(obj, mGenCertChain,
 458                             env->NewStringUTF(pszNameString),
 459                             jArrayList, jCollections);
 460                     }
 461                     else
 462                     {
 463                     // Determine key type: RSA or DSA
 464                     DWORD dwData = CALG_RSA_KEYX;
 465                     DWORD dwSize = sizeof(DWORD);
 466                     ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
 467                         &dwSize, NULL);
 468 
 469                     if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
 470                     {
 471                         // Generate RSA certificate chain and store into cert
 472                         // chain collection
 473                         env->CallVoidMethod(obj, mGenRSAKeyAndCertChain,
 474                             env->NewStringUTF(pszNameString),
 475                             (jlong) hCryptProv, (jlong) hUserKey,
 476                             dwPublicKeyLength, jArrayList, jCollections);

 477                     }
 478 }
 479                 }
 480 
 481                 // Free cert chain
 482                 if (pCertChainContext)
 483                     ::CertFreeCertificateChain(pCertChainContext);
 484             }
 485         }
 486     }
 487     __finally
 488     {
 489         if (hCertStore)
 490             ::CertCloseStore(hCertStore, 0);
 491 
 492         if (pszCertStoreName)
 493             env->ReleaseStringUTFChars(jCertStoreName, pszCertStoreName);
 494 
 495         if (pszNameString)
 496             delete [] pszNameString;
 497     }
 498 }


   1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  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


 255         if (pbData)
 256             delete [] pbData;
 257 
 258         if (seedBytes)
 259             env->ReleaseByteArrayElements(seed, seedBytes, 0); // update orig
 260 
 261         if (hCryptProv)
 262             ::CryptReleaseContext(hCryptProv, 0);
 263     }
 264 
 265     return result;
 266 }
 267 
 268 
 269 /*
 270  * Class:     sun_security_mscapi_KeyStore
 271  * Method:    loadKeysOrCertificateChains
 272  * Signature: (Ljava/lang/String;Ljava/util/Collection;)V
 273  */
 274 JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateChains
 275   (JNIEnv *env, jobject obj, jstring jCertStoreName)
 276 {
 277     /**
 278      * Certificate in cert store has enhanced key usage extension
 279      * property (or EKU property) that is not part of the certificate itself. To determine
 280      * if the certificate should be returned, both the enhanced key usage in certificate
 281      * extension block and the extension property stored along with the certificate in
 282      * certificate store should be examined. Otherwise, we won't be able to determine
 283      * the proper key usage from the Java side because the information is not stored as
 284      * part of the encoded certificate.
 285      */
 286 
 287     const char* pszCertStoreName = NULL;
 288     HCERTSTORE hCertStore = NULL;
 289     PCCERT_CONTEXT pCertContext = NULL;
 290     char* pszNameString = NULL; // certificate's friendly name
 291     DWORD cchNameString = 0;
 292 
 293 
 294     __try
 295     {


 314         jmethodID mNewArrayList = env->GetMethodID(clazzArrayList, "<init>", "()V");
 315         if (mNewArrayList == NULL) {
 316             __leave;
 317         }
 318 
 319         jclass clazzOfThis = env->GetObjectClass(obj);
 320         if (clazzOfThis == NULL) {
 321             __leave;
 322         }
 323 
 324         jmethodID mGenCert = env->GetMethodID(clazzOfThis,
 325                                               "generateCertificate",
 326                                               "([BLjava/util/Collection;)V");
 327         if (mGenCert == NULL) {
 328             __leave;
 329         }
 330 
 331         // Determine method ID to generate certificate chain
 332         jmethodID mGenCertChain = env->GetMethodID(clazzOfThis,
 333                                                    "generateCertificateChain",
 334                                                    "(Ljava/lang/String;Ljava/util/Collection;)V");
 335         if (mGenCertChain == NULL) {
 336             __leave;
 337         }
 338 
 339         // Determine method ID to generate RSA certificate chain
 340         jmethodID mGenRSAKeyAndCertChain = env->GetMethodID(clazzOfThis,
 341                                                    "generateRSAKeyAndCertificateChain",
 342                                                    "(Ljava/lang/String;JJILjava/util/Collection;)V");
 343         if (mGenRSAKeyAndCertChain == NULL) {
 344             __leave;
 345         }
 346 
 347         // Use CertEnumCertificatesInStore to get the certificates
 348         // from the open store. pCertContext must be reset to
 349         // NULL to retrieve the first certificate in the store.
 350         while (pCertContext = ::CertEnumCertificatesInStore(hCertStore, pCertContext))
 351         {
 352             // Check if private key available - client authentication certificate
 353             // must have private key available.
 354             HCRYPTPROV hCryptProv = NULL;
 355             DWORD dwKeySpec = 0;
 356             HCRYPTKEY hUserKey = NULL;
 357             BOOL bCallerFreeProv = FALSE;
 358             BOOL bHasNoPrivateKey = FALSE;
 359             DWORD dwPublicKeyLength = 0;
 360 
 361             if (::CryptAcquireCertificatePrivateKey(pCertContext, NULL, NULL,
 362                                                     &hCryptProv, &dwKeySpec, &bCallerFreeProv) == FALSE)


 373                 {
 374                     if (bCallerFreeProv)
 375                         ::CryptReleaseContext(hCryptProv, NULL);
 376 
 377                     continue;
 378                 }
 379 
 380                 // Set cipher mode to ECB
 381                 DWORD dwCipherMode = CRYPT_MODE_ECB;
 382                 ::CryptSetKeyParam(hUserKey, KP_MODE, (BYTE*)&dwCipherMode, NULL);
 383 
 384 
 385                 // If the private key is present in smart card, we may not be able to
 386                 // determine the key length by using the private key handle. However,
 387                 // since public/private key pairs must have the same length, we could
 388                 // determine the key length of the private key by using the public key
 389                 // in the certificate.
 390                 dwPublicKeyLength = ::CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
 391                         &(pCertContext->pCertInfo->SubjectPublicKeyInfo));
 392 
 393             }
 394             PCCERT_CHAIN_CONTEXT pCertChainContext = NULL;
 395 
 396             // Build certificate chain by using system certificate store.
 397             // Add cert chain into collection for any key usage.
 398             //
 399             if (GetCertificateChain(OID_EKU_ANY, pCertContext, &pCertChainContext))

 400             {
 401 
 402                 for (unsigned int i=0; i < pCertChainContext->cChain; i++)
 403                 {
 404                     // Found cert chain
 405                     PCERT_SIMPLE_CHAIN rgpChain =
 406                         pCertChainContext->rgpChain[i];
 407 
 408                     // Create ArrayList to store certs in each chain
 409                     jobject jArrayList =
 410                         env->NewObject(clazzArrayList, mNewArrayList);
 411 
 412                     for (unsigned int j=0; j < rgpChain->cElement; j++)
 413                     {
 414                         PCERT_CHAIN_ELEMENT rgpElement =
 415                             rgpChain->rgpElement[j];
 416                         PCCERT_CONTEXT pc = rgpElement->pCertContext;
 417 
 418                         // Retrieve the friendly name of the first certificate
 419                         // in the chain


 438                         }
 439 
 440                         BYTE* pbCertEncoded = pc->pbCertEncoded;
 441                         DWORD cbCertEncoded = pc->cbCertEncoded;
 442 
 443                         // Allocate and populate byte array
 444                         jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
 445                         env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
 446                             (jbyte*) pbCertEncoded);
 447 
 448                         // Generate certificate from byte array and store into
 449                         // cert collection
 450                         env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
 451                     }
 452                     if (bHasNoPrivateKey)
 453                     {
 454                         // Generate certificate chain and store into cert chain
 455                         // collection
 456                         env->CallVoidMethod(obj, mGenCertChain,
 457                             env->NewStringUTF(pszNameString),
 458                             jArrayList);
 459                     }
 460                     else
 461                     {
 462                         // Determine key type: RSA or DSA
 463                         DWORD dwData = CALG_RSA_KEYX;
 464                         DWORD dwSize = sizeof(DWORD);
 465                         ::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData,
 466                                 &dwSize, NULL);
 467 
 468                         if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
 469                         {
 470                             // Generate RSA certificate chain and store into cert
 471                             // chain collection
 472                             env->CallVoidMethod(obj, mGenRSAKeyAndCertChain,
 473                                     env->NewStringUTF(pszNameString),
 474                                     (jlong) hCryptProv, (jlong) hUserKey,
 475                                     dwPublicKeyLength, jArrayList);
 476                         }
 477                     }

 478                 }
 479 
 480                 // Free cert chain
 481                 if (pCertChainContext)
 482                     ::CertFreeCertificateChain(pCertChainContext);
 483             }
 484         }
 485     }
 486     __finally
 487     {
 488         if (hCertStore)
 489             ::CertCloseStore(hCertStore, 0);
 490 
 491         if (pszCertStoreName)
 492             env->ReleaseStringUTFChars(jCertStoreName, pszCertStoreName);
 493 
 494         if (pszNameString)
 495             delete [] pszNameString;
 496     }
 497 }


< prev index next >