1 /* 2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3 */ 4 5 /* Copyright (c) 2002 Graz University of Technology. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * 3. The end-user documentation included with the redistribution, if any, must 18 * include the following acknowledgment: 19 * 20 * "This product includes software developed by IAIK of Graz University of 21 * Technology." 22 * 23 * Alternately, this acknowledgment may appear in the software itself, if 24 * and wherever such third-party acknowledgments normally appear. 25 * 26 * 4. The names "Graz University of Technology" and "IAIK of Graz University of 27 * Technology" must not be used to endorse or promote products derived from 28 * this software without prior written permission. 29 * 30 * 5. Products derived from this software may not be called 31 * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior 32 * written permission of Graz University of Technology. 33 * 34 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE 38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 39 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 40 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 41 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 42 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 * POSSIBILITY OF SUCH DAMAGE. 46 */ 47 48 #include "pkcs11wrapper.h" 49 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <assert.h> 54 55 #include "sun_security_pkcs11_wrapper_PKCS11.h" 56 57 #ifdef P11_ENABLE_C_GENERATEKEY 58 /* 59 * Class: sun_security_pkcs11_wrapper_PKCS11 60 * Method: C_GenerateKey 61 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J 62 * Parametermapping: *PKCS11* 63 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession 64 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism 65 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate 66 * CK_ULONG ulCount 67 * @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey 68 */ 69 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey 70 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate) 71 { 72 CK_SESSION_HANDLE ckSessionHandle; 73 CK_MECHANISM ckMechanism; 74 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; 75 CK_ULONG ckAttributesLength; 76 CK_OBJECT_HANDLE ckKeyHandle = 0; 77 jlong jKeyHandle = 0L; 78 CK_RV rv; 79 80 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); 81 if (ckpFunctions == NULL) { return 0L; } 82 83 ckSessionHandle = jLongToCKULong(jSessionHandle); 84 jMechanismToCKMechanism(env, jMechanism, &ckMechanism); 85 if ((*env)->ExceptionCheck(env)) { return 0L ; } 86 87 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); 88 if ((*env)->ExceptionCheck(env)) { 89 if (ckMechanism.pParameter != NULL_PTR) { 90 free(ckMechanism.pParameter); 91 } 92 return 0L; 93 } 94 95 rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle); 96 97 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { 98 jKeyHandle = ckULongToJLong(ckKeyHandle); 99 100 /* cheack, if we must give a initialization vector back to Java */ 101 switch (ckMechanism.mechanism) { 102 case CKM_PBE_MD2_DES_CBC: 103 case CKM_PBE_MD5_DES_CBC: 104 case CKM_PBE_MD5_CAST_CBC: 105 case CKM_PBE_MD5_CAST3_CBC: 106 case CKM_PBE_MD5_CAST128_CBC: 107 /* case CKM_PBE_MD5_CAST5_CBC: the same as CKM_PBE_MD5_CAST128_CBC */ 108 case CKM_PBE_SHA1_CAST128_CBC: 109 /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */ 110 /* we must copy back the initialization vector to the jMechanism object */ 111 copyBackPBEInitializationVector(env, &ckMechanism, jMechanism); 112 break; 113 } 114 } 115 116 if (ckMechanism.pParameter != NULL_PTR) { 117 free(ckMechanism.pParameter); 118 } 119 freeCKAttributeArray(ckpAttributes, ckAttributesLength); 120 121 return jKeyHandle ; 122 } 123 #endif 124 125 #ifdef P11_ENABLE_C_GENERATEKEYPAIR 126 /* 127 * Class: sun_security_pkcs11_wrapper_PKCS11 128 * Method: C_GenerateKeyPair 129 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J 130 * Parametermapping: *PKCS11* 131 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession 132 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism 133 * @param jobjectArray jPublicKeyTemplate CK_ATTRIBUTE_PTR pPublicKeyTemplate 134 * CK_ULONG ulPublicKeyAttributeCount 135 * @param jobjectArray jPrivateKeyTemplate CK_ATTRIBUTE_PTR pPrivateKeyTemplate 136 * CK_ULONG ulPrivateKeyAttributeCount 137 * @return jlongArray jKeyHandles CK_OBJECT_HANDLE_PTR phPublicKey 138 * CK_OBJECT_HANDLE_PTR phPublicKey 139 */ 140 JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair 141 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, 142 jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate) 143 { 144 CK_SESSION_HANDLE ckSessionHandle; 145 CK_MECHANISM ckMechanism; 146 CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR; 147 CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR; 148 CK_ULONG ckPublicKeyAttributesLength; 149 CK_ULONG ckPrivateKeyAttributesLength; 150 CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle; /* pointer to Public Key */ 151 CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */ 152 CK_OBJECT_HANDLE_PTR ckpKeyHandles; /* pointer to array with Public and Private Key */ 153 jlongArray jKeyHandles = NULL; 154 CK_RV rv; 155 int attempts; 156 const int MAX_ATTEMPTS = 3; 157 158 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); 159 if (ckpFunctions == NULL) { return NULL; } 160 161 ckSessionHandle = jLongToCKULong(jSessionHandle); 162 jMechanismToCKMechanism(env, jMechanism, &ckMechanism); 163 if ((*env)->ExceptionCheck(env)) { return NULL; } 164 165 ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE)); 166 if (ckpKeyHandles == NULL) { 167 if (ckMechanism.pParameter != NULL_PTR) { 168 free(ckMechanism.pParameter); 169 } 170 throwOutOfMemoryError(env, 0); 171 return NULL; 172 } 173 ckpPublicKeyHandle = ckpKeyHandles; /* first element of array is Public Key */ 174 ckpPrivateKeyHandle = (ckpKeyHandles + 1); /* second element of array is Private Key */ 175 176 jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength); 177 if ((*env)->ExceptionCheck(env)) { 178 if (ckMechanism.pParameter != NULL_PTR) { 179 free(ckMechanism.pParameter); 180 } 181 free(ckpKeyHandles); 182 return NULL; 183 } 184 185 jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength); 186 if ((*env)->ExceptionCheck(env)) { 187 if (ckMechanism.pParameter != NULL_PTR) { 188 free(ckMechanism.pParameter); 189 } 190 free(ckpKeyHandles); 191 freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength); 192 return NULL; 193 } 194 195 /* 196 * Workaround for NSS bug 1012786: 197 * 198 * Key generation may fail with CKR_FUNCTION_FAILED error 199 * if there is insufficient entropy to generate a random key. 200 * 201 * PKCS11 spec says the following about CKR_FUNCTION_FAILED error 202 * (see section 11.1.1): 203 * 204 * ... In any event, although the function call failed, the situation 205 * is not necessarily totally hopeless, as it is likely to be 206 * when CKR_GENERAL_ERROR is returned. Depending on what the root cause of 207 * the error actually was, it is possible that an attempt 208 * to make the exact same function call again would succeed. 209 * 210 * Call C_GenerateKeyPair() several times if CKR_FUNCTION_FAILED occurs. 211 */ 212 for (attempts = 0; attempts < MAX_ATTEMPTS; attempts++) { 213 rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism, 214 ckpPublicKeyAttributes, ckPublicKeyAttributesLength, 215 ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength, 216 ckpPublicKeyHandle, ckpPrivateKeyHandle); 217 if (rv == CKR_FUNCTION_FAILED) { 218 printDebug("C_1GenerateKeyPair(): C_GenerateKeyPair() failed \ 219 with CKR_FUNCTION_FAILED error, try again\n"); 220 } else { 221 break; 222 } 223 } 224 225 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { 226 jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2); 227 } 228 229 if(ckMechanism.pParameter != NULL_PTR) { 230 free(ckMechanism.pParameter); 231 } 232 free(ckpKeyHandles); 233 freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength); 234 freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength); 235 236 return jKeyHandles ; 237 } 238 #endif 239 240 #ifdef P11_ENABLE_C_WRAPKEY 241 /* 242 * Class: sun_security_pkcs11_wrapper_PKCS11 243 * Method: C_WrapKey 244 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B 245 * Parametermapping: *PKCS11* 246 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession 247 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism 248 * @param jlong jWrappingKeyHandle CK_OBJECT_HANDLE hWrappingKey 249 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey 250 * @return jbyteArray jWrappedKey CK_BYTE_PTR pWrappedKey 251 * CK_ULONG_PTR pulWrappedKeyLen 252 */ 253 JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey 254 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle) 255 { 256 CK_SESSION_HANDLE ckSessionHandle; 257 CK_MECHANISM ckMechanism; 258 CK_OBJECT_HANDLE ckWrappingKeyHandle; 259 CK_OBJECT_HANDLE ckKeyHandle; 260 jbyteArray jWrappedKey = NULL; 261 CK_RV rv; 262 CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; 263 CK_BYTE_PTR ckpWrappedKey = BUF; 264 CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN; 265 266 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); 267 if (ckpFunctions == NULL) { return NULL; } 268 269 ckSessionHandle = jLongToCKULong(jSessionHandle); 270 jMechanismToCKMechanism(env, jMechanism, &ckMechanism); 271 if ((*env)->ExceptionCheck(env)) { return NULL; } 272 273 ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle); 274 ckKeyHandle = jLongToCKULong(jKeyHandle); 275 276 rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength); 277 if (rv == CKR_BUFFER_TOO_SMALL) { 278 ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength); 279 if (ckpWrappedKey == NULL) { 280 if (ckMechanism.pParameter != NULL_PTR) { 281 free(ckMechanism.pParameter); 282 } 283 throwOutOfMemoryError(env, 0); 284 return NULL; 285 } 286 287 rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength); 288 } 289 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { 290 jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength); 291 } 292 293 if (ckpWrappedKey != BUF) { free(ckpWrappedKey); } 294 if (ckMechanism.pParameter != NULL_PTR) { 295 free(ckMechanism.pParameter); 296 } 297 return jWrappedKey ; 298 } 299 #endif 300 301 #ifdef P11_ENABLE_C_UNWRAPKEY 302 /* 303 * Class: sun_security_pkcs11_wrapper_PKCS11 304 * Method: C_UnwrapKey 305 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J 306 * Parametermapping: *PKCS11* 307 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession 308 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism 309 * @param jlong jUnwrappingKeyHandle CK_OBJECT_HANDLE hUnwrappingKey 310 * @param jbyteArray jWrappedKey CK_BYTE_PTR pWrappedKey 311 * CK_ULONG_PTR pulWrappedKeyLen 312 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate 313 * CK_ULONG ulCount 314 * @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey 315 */ 316 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey 317 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle, 318 jbyteArray jWrappedKey, jobjectArray jTemplate) 319 { 320 CK_SESSION_HANDLE ckSessionHandle; 321 CK_MECHANISM ckMechanism; 322 CK_OBJECT_HANDLE ckUnwrappingKeyHandle; 323 CK_BYTE_PTR ckpWrappedKey = NULL_PTR; 324 CK_ULONG ckWrappedKeyLength; 325 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; 326 CK_ULONG ckAttributesLength; 327 CK_OBJECT_HANDLE ckKeyHandle = 0; 328 jlong jKeyHandle = 0L; 329 CK_RV rv; 330 331 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); 332 if (ckpFunctions == NULL) { return 0L; } 333 334 ckSessionHandle = jLongToCKULong(jSessionHandle); 335 jMechanismToCKMechanism(env, jMechanism, &ckMechanism); 336 if ((*env)->ExceptionCheck(env)) { return 0L; } 337 338 ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle); 339 jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength); 340 if ((*env)->ExceptionCheck(env)) { 341 if (ckMechanism.pParameter != NULL_PTR) { 342 free(ckMechanism.pParameter); 343 } 344 return 0L; 345 } 346 347 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); 348 if ((*env)->ExceptionCheck(env)) { 349 if (ckMechanism.pParameter != NULL_PTR) { 350 free(ckMechanism.pParameter); 351 } 352 free(ckpWrappedKey); 353 return 0L; 354 } 355 356 357 rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle, 358 ckpWrappedKey, ckWrappedKeyLength, 359 ckpAttributes, ckAttributesLength, &ckKeyHandle); 360 361 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { 362 jKeyHandle = ckLongToJLong(ckKeyHandle); 363 364 #if 0 365 /* cheack, if we must give a initialization vector back to Java */ 366 if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) { 367 /* we must copy back the unwrapped key info to the jMechanism object */ 368 copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism); 369 } 370 #endif 371 } 372 373 if (ckMechanism.pParameter != NULL_PTR) { 374 free(ckMechanism.pParameter); 375 } 376 freeCKAttributeArray(ckpAttributes, ckAttributesLength); 377 free(ckpWrappedKey); 378 379 return jKeyHandle ; 380 } 381 #endif 382 383 #ifdef P11_ENABLE_C_DERIVEKEY 384 385 void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) { 386 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter; 387 if (params == NULL) { 388 return; 389 } 390 391 if (params->RandomInfo.pClientRandom != NULL) { 392 free(params->RandomInfo.pClientRandom); 393 } 394 if (params->RandomInfo.pServerRandom != NULL) { 395 free(params->RandomInfo.pServerRandom); 396 } 397 if (params->pVersion != NULL) { 398 free(params->pVersion); 399 } 400 } 401 402 void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) { 403 CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter; 404 if (params == NULL) { 405 return; 406 } 407 408 if (params->pSharedData != NULL) { 409 free(params->pSharedData); 410 } 411 if (params->pPublicData != NULL) { 412 free(params->pPublicData); 413 } 414 } 415 416 /* 417 * Copy back the PRF output to Java. 418 */ 419 void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) 420 { 421 jclass jMechanismClass, jTLSPrfParamsClass; 422 CK_TLS_PRF_PARAMS *ckTLSPrfParams; 423 jobject jTLSPrfParams; 424 jfieldID fieldID; 425 CK_MECHANISM_TYPE ckMechanismType; 426 jlong jMechanismType; 427 CK_BYTE_PTR output; 428 jobject jOutput; 429 jint jLength; 430 jbyte* jBytes; 431 int i; 432 433 /* get mechanism */ 434 jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM); 435 if (jMechanismClass == NULL) { return; } 436 fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); 437 if (fieldID == NULL) { return; } 438 jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); 439 ckMechanismType = jLongToCKULong(jMechanismType); 440 if (ckMechanismType != ckMechanism->mechanism) { 441 /* we do not have maching types, this should not occur */ 442 return; 443 } 444 445 /* get the native CK_TLS_PRF_PARAMS */ 446 ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter; 447 if (ckTLSPrfParams != NULL_PTR) { 448 /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */ 449 fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); 450 if (fieldID == NULL) { return; } 451 jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID); 452 453 /* copy back the client IV */ 454 jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS); 455 if (jTLSPrfParamsClass == NULL) { return; } 456 fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B"); 457 if (fieldID == NULL) { return; } 458 jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID); 459 output = ckTLSPrfParams->pOutput; 460 461 // Note: we assume that the token returned exactly as many bytes as we 462 // requested. Anything else would not make sense. 463 if (jOutput != NULL) { 464 jLength = (*env)->GetArrayLength(env, jOutput); 465 jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL); 466 if (jBytes == NULL) { return; } 467 468 /* copy the bytes to the Java buffer */ 469 for (i=0; i < jLength; i++) { 470 jBytes[i] = ckByteToJByte(output[i]); 471 } 472 /* copy back the Java buffer to the object */ 473 (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0); 474 } 475 476 // free malloc'd data 477 free(ckTLSPrfParams->pSeed); 478 free(ckTLSPrfParams->pLabel); 479 free(ckTLSPrfParams->pulOutputLen); 480 free(ckTLSPrfParams->pOutput); 481 } 482 } 483 484 /* 485 * Class: sun_security_pkcs11_wrapper_PKCS11 486 * Method: C_DeriveKey 487 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J 488 * Parametermapping: *PKCS11* 489 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession 490 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism 491 * @param jlong jBaseKeyHandle CK_OBJECT_HANDLE hBaseKey 492 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate 493 * CK_ULONG ulCount 494 * @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey 495 */ 496 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey 497 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate) 498 { 499 CK_SESSION_HANDLE ckSessionHandle; 500 CK_MECHANISM ckMechanism; 501 CK_OBJECT_HANDLE ckBaseKeyHandle; 502 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; 503 CK_ULONG ckAttributesLength; 504 CK_OBJECT_HANDLE ckKeyHandle = 0; 505 jlong jKeyHandle = 0L; 506 CK_RV rv; 507 CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle; 508 509 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); 510 if (ckpFunctions == NULL) { return 0L; } 511 512 ckSessionHandle = jLongToCKULong(jSessionHandle); 513 jMechanismToCKMechanism(env, jMechanism, &ckMechanism); 514 if ((*env)->ExceptionCheck(env)) { return 0L; } 515 516 ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle); 517 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); 518 if ((*env)->ExceptionCheck(env)) { 519 if (ckMechanism.pParameter != NULL_PTR) { 520 free(ckMechanism.pParameter); 521 } 522 return 0L; 523 } 524 525 switch (ckMechanism.mechanism) { 526 case CKM_SSL3_KEY_AND_MAC_DERIVE: 527 case CKM_TLS_KEY_AND_MAC_DERIVE: 528 case CKM_TLS_PRF: 529 // these mechanism do not return a key handle via phKey 530 // set to NULL in case pedantic implementations check for it 531 phKey = NULL; 532 break; 533 default: 534 // empty 535 break; 536 } 537 538 rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle, 539 ckpAttributes, ckAttributesLength, phKey); 540 541 jKeyHandle = ckLongToJLong(ckKeyHandle); 542 543 freeCKAttributeArray(ckpAttributes, ckAttributesLength); 544 545 switch (ckMechanism.mechanism) { 546 case CKM_SSL3_MASTER_KEY_DERIVE: 547 case CKM_TLS_MASTER_KEY_DERIVE: 548 /* we must copy back the client version */ 549 copyBackClientVersion(env, &ckMechanism, jMechanism); 550 freeMasterKeyDeriveParams(&ckMechanism); 551 break; 552 case CKM_SSL3_MASTER_KEY_DERIVE_DH: 553 case CKM_TLS_MASTER_KEY_DERIVE_DH: 554 freeMasterKeyDeriveParams(&ckMechanism); 555 break; 556 case CKM_SSL3_KEY_AND_MAC_DERIVE: 557 case CKM_TLS_KEY_AND_MAC_DERIVE: 558 /* we must copy back the unwrapped key info to the jMechanism object */ 559 copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism); 560 break; 561 case CKM_TLS_PRF: 562 copyBackTLSPrfParams(env, &ckMechanism, jMechanism); 563 break; 564 case CKM_ECDH1_DERIVE: 565 freeEcdh1DeriveParams(&ckMechanism); 566 break; 567 default: 568 // empty 569 break; 570 } 571 572 if (ckMechanism.pParameter != NULL_PTR) { 573 free(ckMechanism.pParameter); 574 } 575 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; } 576 577 return jKeyHandle ; 578 } 579 580 /* 581 * Copy back the client version information from the native 582 * structure to the Java object. This is only used for the 583 * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key. 584 * 585 */ 586 void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) 587 { 588 jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass; 589 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams; 590 CK_VERSION *ckVersion; 591 jfieldID fieldID; 592 CK_MECHANISM_TYPE ckMechanismType; 593 jlong jMechanismType; 594 jobject jSSL3MasterKeyDeriveParams; 595 jobject jVersion; 596 597 /* get mechanism */ 598 jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM); 599 if (jMechanismClass == NULL) { return; } 600 fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); 601 if (fieldID == NULL) { return; } 602 jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); 603 ckMechanismType = jLongToCKULong(jMechanismType); 604 if (ckMechanismType != ckMechanism->mechanism) { 605 /* we do not have maching types, this should not occur */ 606 return; 607 } 608 609 /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */ 610 ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter; 611 if (ckSSL3MasterKeyDeriveParams != NULL_PTR) { 612 /* get the native CK_VERSION */ 613 ckVersion = ckSSL3MasterKeyDeriveParams->pVersion; 614 if (ckVersion != NULL_PTR) { 615 /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */ 616 fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); 617 if (fieldID == NULL) { return; } 618 619 jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID); 620 621 /* get the Java CK_VERSION */ 622 jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); 623 if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; } 624 fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";"); 625 if (fieldID == NULL) { return; } 626 jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID); 627 628 /* now copy back the version from the native structure to the Java structure */ 629 630 /* copy back the major version */ 631 jVersionClass = (*env)->FindClass(env, CLASS_VERSION); 632 if (jVersionClass == NULL) { return; } 633 fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B"); 634 if (fieldID == NULL) { return; } 635 (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major)); 636 637 /* copy back the minor version */ 638 fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B"); 639 if (fieldID == NULL) { return; } 640 (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor)); 641 } 642 } 643 } 644 645 646 /* 647 * Copy back the derived keys and initialization vectors from the native 648 * structure to the Java object. This is only used for the 649 * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key. 650 * 651 */ 652 void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) 653 { 654 jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass; 655 CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam; 656 CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut; 657 jfieldID fieldID; 658 CK_MECHANISM_TYPE ckMechanismType; 659 jlong jMechanismType; 660 CK_BYTE_PTR iv; 661 jobject jSSL3KeyMatParam; 662 jobject jSSL3KeyMatOut; 663 jobject jIV; 664 jint jLength; 665 jbyte* jBytes; 666 int i; 667 668 /* get mechanism */ 669 jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM); 670 if (jMechanismClass == NULL) { return; } 671 fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); 672 if (fieldID == NULL) { return; } 673 jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); 674 ckMechanismType = jLongToCKULong(jMechanismType); 675 if (ckMechanismType != ckMechanism->mechanism) { 676 /* we do not have maching types, this should not occur */ 677 return; 678 } 679 680 /* get the native CK_SSL3_KEY_MAT_PARAMS */ 681 ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter; 682 if (ckSSL3KeyMatParam != NULL_PTR) { 683 // free malloc'd data 684 if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) { 685 free(ckSSL3KeyMatParam->RandomInfo.pClientRandom); 686 } 687 if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) { 688 free(ckSSL3KeyMatParam->RandomInfo.pServerRandom); 689 } 690 691 /* get the native CK_SSL3_KEY_MAT_OUT */ 692 ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial; 693 if (ckSSL3KeyMatOut != NULL_PTR) { 694 /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */ 695 fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); 696 if (fieldID == NULL) { return; } 697 jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID); 698 699 /* get the Java CK_SSL3_KEY_MAT_OUT */ 700 jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS); 701 if (jSSL3KeyMatParamsClass == NULL) { return; } 702 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";"); 703 if (fieldID == NULL) { return; } 704 jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID); 705 706 /* now copy back all the key handles and the initialization vectors */ 707 /* copy back client MAC secret handle */ 708 jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT); 709 if (jSSL3KeyMatOutClass == NULL) { return; } 710 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J"); 711 if (fieldID == NULL) { return; } 712 (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret)); 713 714 /* copy back server MAC secret handle */ 715 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J"); 716 if (fieldID == NULL) { return; } 717 (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret)); 718 719 /* copy back client secret key handle */ 720 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J"); 721 if (fieldID == NULL) { return; } 722 (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey)); 723 724 /* copy back server secret key handle */ 725 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J"); 726 if (fieldID == NULL) { return; } 727 (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey)); 728 729 /* copy back the client IV */ 730 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B"); 731 if (fieldID == NULL) { return; } 732 jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID); 733 iv = ckSSL3KeyMatOut->pIVClient; 734 735 if (jIV != NULL) { 736 jLength = (*env)->GetArrayLength(env, jIV); 737 jBytes = (*env)->GetByteArrayElements(env, jIV, NULL); 738 if (jBytes == NULL) { return; } 739 /* copy the bytes to the Java buffer */ 740 for (i=0; i < jLength; i++) { 741 jBytes[i] = ckByteToJByte(iv[i]); 742 } 743 /* copy back the Java buffer to the object */ 744 (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0); 745 } 746 // free malloc'd data 747 free(ckSSL3KeyMatOut->pIVClient); 748 749 /* copy back the server IV */ 750 fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B"); 751 if (fieldID == NULL) { return; } 752 jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID); 753 iv = ckSSL3KeyMatOut->pIVServer; 754 755 if (jIV != NULL) { 756 jLength = (*env)->GetArrayLength(env, jIV); 757 jBytes = (*env)->GetByteArrayElements(env, jIV, NULL); 758 if (jBytes == NULL) { return; } 759 /* copy the bytes to the Java buffer */ 760 for (i=0; i < jLength; i++) { 761 jBytes[i] = ckByteToJByte(iv[i]); 762 } 763 /* copy back the Java buffer to the object */ 764 (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0); 765 } 766 // free malloc'd data 767 free(ckSSL3KeyMatOut->pIVServer); 768 free(ckSSL3KeyMatOut); 769 } 770 } 771 } 772 773 #endif