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 }
|