1 /*
2  * Copyright (c) 2003, 2019, 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_GETNATIVEKEYINFO
58 
59 #define CK_ATTRIBUTES_TEMPLATE_LENGTH (CK_ULONG)61U
60 
61 static CK_ATTRIBUTE ckpAttributesTemplate[CK_ATTRIBUTES_TEMPLATE_LENGTH] = {
62         {CKA_CLASS, 0, 0},
63         {CKA_TOKEN, 0, 0},
64         {CKA_PRIVATE, 0, 0},
65         {CKA_LABEL, 0, 0},
66         {CKA_APPLICATION, 0, 0},
67         {CKA_VALUE, 0, 0},
68         {CKA_OBJECT_ID, 0, 0},
69         {CKA_CERTIFICATE_TYPE, 0, 0},
70         {CKA_ISSUER, 0, 0},
71         {CKA_SERIAL_NUMBER, 0, 0},
72         {CKA_AC_ISSUER, 0, 0},
73         {CKA_OWNER, 0, 0},
74         {CKA_ATTR_TYPES, 0, 0},
75         {CKA_TRUSTED, 0, 0},
76         {CKA_KEY_TYPE, 0, 0},
77         {CKA_SUBJECT, 0, 0},
78         {CKA_ID, 0, 0},
79         {CKA_SENSITIVE, 0, 0},
80         {CKA_ENCRYPT, 0, 0},
81         {CKA_DECRYPT, 0, 0},
82         {CKA_WRAP, 0, 0},
83         {CKA_UNWRAP, 0, 0},
84         {CKA_SIGN, 0, 0},
85         {CKA_SIGN_RECOVER, 0, 0},
86         {CKA_VERIFY, 0, 0},
87         {CKA_VERIFY_RECOVER, 0, 0},
88         {CKA_DERIVE, 0, 0},
89         {CKA_START_DATE, 0, 0},
90         {CKA_END_DATE, 0, 0},
91         {CKA_MODULUS, 0, 0},
92         {CKA_MODULUS_BITS, 0, 0},
93         {CKA_PUBLIC_EXPONENT, 0, 0},
94         {CKA_PRIVATE_EXPONENT, 0, 0},
95         {CKA_PRIME_1, 0, 0},
96         {CKA_PRIME_2, 0, 0},
97         {CKA_EXPONENT_1, 0, 0},
98         {CKA_EXPONENT_2, 0, 0},
99         {CKA_COEFFICIENT, 0, 0},
100         {CKA_PRIME, 0, 0},
101         {CKA_SUBPRIME, 0, 0},
102         {CKA_BASE, 0, 0},
103         {CKA_PRIME_BITS, 0, 0},
104         {CKA_SUB_PRIME_BITS, 0, 0},
105         {CKA_VALUE_BITS, 0, 0},
106         {CKA_VALUE_LEN, 0, 0},
107         {CKA_EXTRACTABLE, 0, 0},
108         {CKA_LOCAL, 0, 0},
109         {CKA_NEVER_EXTRACTABLE, 0, 0},
110         {CKA_ALWAYS_SENSITIVE, 0, 0},
111         {CKA_KEY_GEN_MECHANISM, 0, 0},
112         {CKA_MODIFIABLE, 0, 0},
113         {CKA_ECDSA_PARAMS, 0, 0},
114         {CKA_EC_PARAMS, 0, 0},
115         {CKA_EC_POINT, 0, 0},
116         {CKA_SECONDARY_AUTH, 0, 0},
117         {CKA_AUTH_PIN_FLAGS, 0, 0},
118         {CKA_HW_FEATURE_TYPE, 0, 0},
119         {CKA_RESET_ON_INIT, 0, 0},
120         {CKA_HAS_RESET, 0, 0},
121         {CKA_VENDOR_DEFINED, 0, 0},
122         {CKA_NETSCAPE_DB, 0, 0},
123 };
124 
125 /*
126  * Class:     sun_security_pkcs11_wrapper_PKCS11
127  * Method:    getNativeKeyInfo
128  * Signature: (JJJLsun/security/pkcs11/wrapper/CK_MECHANISM;)[B
129  * Parametermapping:                         *PKCS11*
130  * @param   jlong         jSessionHandle     CK_SESSION_HANDLE hSession
131  * @param   jlong         jKeyHandle         CK_OBJECT_HANDLE hObject
132  * @param   jlong         jWrappingKeyHandle CK_OBJECT_HANDLE hObject
133  * @param   jobject       jWrappingMech      CK_MECHANISM_PTR pMechanism
134  * @return  jbyteArray    jNativeKeyInfo     -
135  */
136 JNIEXPORT jbyteArray JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_getNativeKeyInfo(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jKeyHandle,jlong jWrappingKeyHandle,jobject jWrappingMech)137 Java_sun_security_pkcs11_wrapper_PKCS11_getNativeKeyInfo
138     (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle,
139     jlong jWrappingKeyHandle, jobject jWrappingMech)
140 {
141     jbyteArray returnValue = NULL;
142     CK_SESSION_HANDLE ckSessionHandle = jLongToCKULong(jSessionHandle);
143     CK_OBJECT_HANDLE ckObjectHandle = jLongToCKULong(jKeyHandle);
144     CK_ATTRIBUTE_PTR ckpAttributes = NULL;
145     CK_RV rv;
146     jbyteArray nativeKeyInfoArray = NULL;
147     jbyteArray nativeKeyInfoWrappedKeyArray = NULL;
148     jbyte* nativeKeyInfoArrayRaw = NULL;
149     jbyte* nativeKeyInfoWrappedKeyArrayRaw = NULL;
150     unsigned int sensitiveAttributePosition = (unsigned int)-1;
151     unsigned int i = 0U;
152     unsigned long totalDataSize = 0UL, attributesCount = 0UL;
153     unsigned long totalCkAttributesSize = 0UL, totalNativeKeyInfoArraySize = 0UL;
154     jbyte* wrappedKeySizePtr = NULL;
155     jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
156     jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
157     jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
158     CK_MECHANISM_PTR ckpMechanism = NULL;
159     char iv[16] = {0x0};
160     CK_ULONG ckWrappedKeyLength = 0U;
161     jbyte* wrappedKeySizeWrappedKeyArrayPtr = NULL;
162     CK_BYTE_PTR wrappedKeyBufferPtr = NULL;
163     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
164     CK_OBJECT_CLASS class;
165     CK_KEY_TYPE keyType;
166     CK_BBOOL sensitive;
167     CK_BBOOL netscapeAttributeValueNeeded = CK_FALSE;
168     CK_ATTRIBUTE ckNetscapeAttributesTemplate[4];
169     ckNetscapeAttributesTemplate[0].type = CKA_CLASS;
170     ckNetscapeAttributesTemplate[1].type = CKA_KEY_TYPE;
171     ckNetscapeAttributesTemplate[2].type = CKA_SENSITIVE;
172     ckNetscapeAttributesTemplate[3].type = CKA_NETSCAPE_DB;
173     ckNetscapeAttributesTemplate[0].pValue = &class;
174     ckNetscapeAttributesTemplate[1].pValue = &keyType;
175     ckNetscapeAttributesTemplate[2].pValue = &sensitive;
176     ckNetscapeAttributesTemplate[3].pValue = 0;
177     ckNetscapeAttributesTemplate[0].ulValueLen = sizeof(class);
178     ckNetscapeAttributesTemplate[1].ulValueLen = sizeof(keyType);
179     ckNetscapeAttributesTemplate[2].ulValueLen = sizeof(sensitive);
180     ckNetscapeAttributesTemplate[3].ulValueLen = 0;
181 
182     if (ckpFunctions == NULL) { goto cleanup; }
183 
184     // If key is private and of DSA or EC type, NSS may require CKA_NETSCAPE_DB
185     // attribute to unwrap it.
186     rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
187             ckNetscapeAttributesTemplate,
188             sizeof(ckNetscapeAttributesTemplate)/sizeof(CK_ATTRIBUTE));
189 
190     if (rv == CKR_OK && class == CKO_PRIVATE_KEY &&
191             (keyType == CKK_EC || keyType == CKK_DSA) &&
192             sensitive == CK_TRUE &&
193             ckNetscapeAttributesTemplate[3].ulValueLen == CK_UNAVAILABLE_INFORMATION) {
194         // We cannot set the attribute through C_SetAttributeValue here
195         // because it might be read-only. However, we can add it to
196         // the extracted buffer.
197         netscapeAttributeValueNeeded = CK_TRUE;
198         TRACE0("DEBUG: override CKA_NETSCAPE_DB attr value to TRUE\n");
199     }
200 
201     ckpAttributes = (CK_ATTRIBUTE_PTR) calloc(
202             CK_ATTRIBUTES_TEMPLATE_LENGTH, sizeof(CK_ATTRIBUTE));
203     if (ckpAttributes == NULL) {
204         throwOutOfMemoryError(env, 0);
205         goto cleanup;
206     }
207     memcpy(ckpAttributes, ckpAttributesTemplate,
208             CK_ATTRIBUTES_TEMPLATE_LENGTH * sizeof(CK_ATTRIBUTE));
209 
210     // Get sizes for value buffers
211     // NOTE: may return an error code but length values are filled anyways
212     (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
213             ckpAttributes, CK_ATTRIBUTES_TEMPLATE_LENGTH);
214 
215     for (i = 0; i < CK_ATTRIBUTES_TEMPLATE_LENGTH; i++) {
216         if ((ckpAttributes+i)->ulValueLen != CK_UNAVAILABLE_INFORMATION) {
217             totalDataSize += (ckpAttributes+i)->ulValueLen;
218             if ((ckpAttributes+i)->type == CKA_SENSITIVE) {
219                  sensitiveAttributePosition = attributesCount;
220                  TRACE0("DEBUG: GetNativeKeyInfo key is sensitive");
221             }
222             attributesCount++;
223         }
224     }
225 
226     if (netscapeAttributeValueNeeded) {
227         attributesCount++;
228     }
229 
230     // Allocate a single buffer to hold valid attributes and attribute's values
231     // Buffer structure: [ attributes-size, [ ... attributes ... ],
232     //                   values-size, [ ... values ... ], wrapped-key-size,
233     //                   [ ... wrapped-key ... ] ]
234     //     * sizes are expressed in bytes and data type is unsigned long
235     totalCkAttributesSize = attributesCount * sizeof(CK_ATTRIBUTE);
236     TRACE1("DEBUG: GetNativeKeyInfo attributesCount = %lu\n", attributesCount);
237     TRACE1("DEBUG: GetNativeKeyInfo sizeof CK_ATTRIBUTE = %zu\n", sizeof(CK_ATTRIBUTE));
238     TRACE1("DEBUG: GetNativeKeyInfo totalCkAttributesSize = %lu\n", totalCkAttributesSize);
239     TRACE1("DEBUG: GetNativeKeyInfo totalDataSize = %lu\n", totalDataSize);
240 
241     totalNativeKeyInfoArraySize =
242             totalCkAttributesSize + sizeof(unsigned long) * 3 + totalDataSize;
243 
244     TRACE1("DEBUG: GetNativeKeyInfo totalNativeKeyInfoArraySize = %lu\n", totalNativeKeyInfoArraySize);
245 
246     nativeKeyInfoArray = (*env)->NewByteArray(env, totalNativeKeyInfoArraySize);
247     if (nativeKeyInfoArray == NULL) {
248         goto cleanup;
249     }
250 
251     nativeKeyInfoArrayRaw = (*env)->GetByteArrayElements(env, nativeKeyInfoArray,
252             NULL);
253     if (nativeKeyInfoArrayRaw == NULL) {
254         goto cleanup;
255     }
256 
257     wrappedKeySizePtr = nativeKeyInfoArrayRaw +
258             sizeof(unsigned long)*2 + totalCkAttributesSize + totalDataSize;
259     memcpy(nativeKeyInfoArrayRaw, &totalCkAttributesSize, sizeof(unsigned long));
260 
261     memcpy(nativeKeyInfoArrayRaw + sizeof(unsigned long) + totalCkAttributesSize,
262         &totalDataSize, sizeof(unsigned long));
263 
264     memset(wrappedKeySizePtr, 0, sizeof(unsigned long));
265 
266     nativeKeyInfoArrayRawCkAttributes = nativeKeyInfoArrayRaw +
267             sizeof(unsigned long);
268     nativeKeyInfoArrayRawCkAttributesPtr = nativeKeyInfoArrayRawCkAttributes;
269     nativeKeyInfoArrayRawDataPtr = nativeKeyInfoArrayRaw +
270             totalCkAttributesSize + sizeof(unsigned long) * 2;
271 
272     for (i = 0; i < CK_ATTRIBUTES_TEMPLATE_LENGTH; i++) {
273         if ((ckpAttributes+i)->ulValueLen != CK_UNAVAILABLE_INFORMATION) {
274             (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).type =
275                     (ckpAttributes+i)->type;
276             (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen =
277                     (ckpAttributes+i)->ulValueLen;
278             if ((ckpAttributes+i)->ulValueLen != 0) {
279                 (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue =
280                         nativeKeyInfoArrayRawDataPtr;
281             } else {
282                 (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue = 0;
283             }
284             nativeKeyInfoArrayRawDataPtr +=
285                     (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen;
286             nativeKeyInfoArrayRawCkAttributesPtr += sizeof(CK_ATTRIBUTE);
287         }
288     }
289 
290     TRACE0("DEBUG: GetNativeKeyInfo finished prepping nativeKeyInfoArray\n");
291 
292     // Get attribute's values
293     rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
294             (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
295             attributesCount);
296     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
297         goto cleanup;
298     }
299 
300     TRACE0("DEBUG: GetNativeKeyInfo 1st C_GetAttributeValue call passed\n");
301 
302     if (netscapeAttributeValueNeeded) {
303         (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).type = CKA_NETSCAPE_DB;
304         // Value is not needed, public key is not used
305     }
306 
307     if ((sensitiveAttributePosition != (unsigned int)-1) &&
308         *(CK_BBOOL*)(((CK_ATTRIBUTE_PTR)(((CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes)
309                 +sensitiveAttributePosition))->pValue) == CK_TRUE) {
310         // Key is sensitive. Need to extract it wrapped.
311         if (jWrappingKeyHandle != 0) {
312 
313             ckpMechanism = jMechanismToCKMechanismPtr(env, jWrappingMech);
314             rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, ckpMechanism,
315                     jLongToCKULong(jWrappingKeyHandle), ckObjectHandle,
316                     NULL_PTR, &ckWrappedKeyLength);
317             if (ckWrappedKeyLength != 0) {
318                 // Allocate space for getting the wrapped key
319                 nativeKeyInfoWrappedKeyArray = (*env)->NewByteArray(env,
320                         totalNativeKeyInfoArraySize + ckWrappedKeyLength);
321                 if (nativeKeyInfoWrappedKeyArray == NULL) {
322                     goto cleanup;
323                 }
324                 nativeKeyInfoWrappedKeyArrayRaw =
325                         (*env)->GetByteArrayElements(env,
326                                 nativeKeyInfoWrappedKeyArray, NULL);
327                 if (nativeKeyInfoWrappedKeyArrayRaw == NULL) {
328                     goto cleanup;
329                 }
330                 memcpy(nativeKeyInfoWrappedKeyArrayRaw, nativeKeyInfoArrayRaw,
331                         totalNativeKeyInfoArraySize);
332                 wrappedKeySizeWrappedKeyArrayPtr =
333                         nativeKeyInfoWrappedKeyArrayRaw +
334                         sizeof(unsigned long)*2 + totalCkAttributesSize +
335                         totalDataSize;
336                 memcpy(wrappedKeySizeWrappedKeyArrayPtr, &ckWrappedKeyLength, sizeof(unsigned long));
337                 TRACE1("DEBUG: GetNativeKeyInfo 1st C_WrapKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
338 
339                 wrappedKeyBufferPtr =
340                         (CK_BYTE_PTR) (wrappedKeySizeWrappedKeyArrayPtr +
341                         sizeof(unsigned long));
342                 rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, ckpMechanism,
343                         jLongToCKULong(jWrappingKeyHandle),ckObjectHandle,
344                         wrappedKeyBufferPtr, &ckWrappedKeyLength);
345                 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
346                     goto cleanup;
347                 }
348                 memcpy(wrappedKeySizeWrappedKeyArrayPtr, &ckWrappedKeyLength, sizeof(unsigned long));
349                 TRACE1("DEBUG: GetNativeKeyInfo 2nd C_WrapKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
350             } else {
351                 goto cleanup;
352             }
353         } else {
354             ckAssertReturnValueOK(env, CKR_KEY_HANDLE_INVALID);
355             goto cleanup;
356         }
357         returnValue = nativeKeyInfoWrappedKeyArray;
358     } else {
359         returnValue = nativeKeyInfoArray;
360     }
361 
362 cleanup:
363     if (ckpAttributes != NULL) {
364         free(ckpAttributes);
365     }
366 
367     if (nativeKeyInfoArrayRaw != NULL) {
368         (*env)->ReleaseByteArrayElements(env, nativeKeyInfoArray,
369                 nativeKeyInfoArrayRaw, 0);
370     }
371 
372     if (nativeKeyInfoWrappedKeyArrayRaw != NULL) {
373         (*env)->ReleaseByteArrayElements(env, nativeKeyInfoWrappedKeyArray,
374                 nativeKeyInfoWrappedKeyArrayRaw, 0);
375     }
376 
377     if (nativeKeyInfoArray != NULL && returnValue != nativeKeyInfoArray) {
378         (*env)->DeleteLocalRef(env, nativeKeyInfoArray);
379     }
380 
381     if (nativeKeyInfoWrappedKeyArray != NULL
382             && returnValue != nativeKeyInfoWrappedKeyArray) {
383         (*env)->DeleteLocalRef(env, nativeKeyInfoWrappedKeyArray);
384     }
385     freeCKMechanismPtr(ckpMechanism);
386 
387     return returnValue;
388 }
389 #endif
390 
391 #ifdef P11_ENABLE_CREATENATIVEKEY
392 /*
393  * Class:     sun_security_pkcs11_wrapper_PKCS11
394  * Method:    createNativeKey
395  * Signature: (J[BJLsun/security/pkcs11/wrapper/CK_MECHANISM;)J
396  * Parametermapping:                          *PKCS11*
397  * @param   jlong         jSessionHandle      CK_SESSION_HANDLE hSession
398  * @param   jbyteArray    jNativeKeyInfo      -
399  * @param   jlong         jWrappingKeyHandle  CK_OBJECT_HANDLE hObject
400  * @param   jobject       jWrappingMech       CK_MECHANISM_PTR pMechanism
401  * @return  jlong         jKeyHandle          CK_OBJECT_HANDLE hObject
402  */
403 JNIEXPORT jlong JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_createNativeKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jNativeKeyInfo,jlong jWrappingKeyHandle,jobject jWrappingMech)404 Java_sun_security_pkcs11_wrapper_PKCS11_createNativeKey
405     (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jNativeKeyInfo,
406     jlong jWrappingKeyHandle, jobject jWrappingMech)
407 {
408     CK_OBJECT_HANDLE ckObjectHandle;
409     CK_RV rv;
410     CK_SESSION_HANDLE ckSessionHandle = jLongToCKULong(jSessionHandle);
411     jbyte* nativeKeyInfoArrayRaw = NULL;
412     jlong jObjectHandle = 0L;
413     unsigned long totalCkAttributesSize = 0UL;
414     unsigned long nativeKeyInfoCkAttributesCount = 0UL;
415     jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
416     jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
417     jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
418     unsigned long totalDataSize = 0UL;
419     jbyte* wrappedKeySizePtr = NULL;
420     unsigned int i = 0U;
421     CK_MECHANISM_PTR ckpMechanism = NULL;
422     char iv[16] = {0x0};
423     CK_ULONG ckWrappedKeyLength = 0UL;
424     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
425 
426     if (ckpFunctions == NULL) { goto cleanup; }
427 
428     nativeKeyInfoArrayRaw =
429             (*env)->GetByteArrayElements(env, jNativeKeyInfo, NULL);
430     if (nativeKeyInfoArrayRaw == NULL) {
431         goto cleanup;
432     }
433 
434     memcpy(&totalCkAttributesSize, nativeKeyInfoArrayRaw, sizeof(unsigned long));
435     TRACE1("DEBUG: createNativeKey totalCkAttributesSize = %lu\n", totalCkAttributesSize);
436     nativeKeyInfoCkAttributesCount = totalCkAttributesSize/sizeof(CK_ATTRIBUTE);
437     TRACE1("DEBUG: createNativeKey nativeKeyInfoCkAttributesCount = %lu\n", nativeKeyInfoCkAttributesCount);
438 
439     nativeKeyInfoArrayRawCkAttributes = nativeKeyInfoArrayRaw +
440             sizeof(unsigned long);
441     nativeKeyInfoArrayRawCkAttributesPtr = nativeKeyInfoArrayRawCkAttributes;
442     nativeKeyInfoArrayRawDataPtr = nativeKeyInfoArrayRaw +
443             totalCkAttributesSize + sizeof(unsigned long) * 2;
444     memcpy(&totalDataSize, (nativeKeyInfoArrayRaw + totalCkAttributesSize + sizeof(unsigned long)),
445             sizeof(unsigned long));
446     TRACE1("DEBUG: createNativeKey totalDataSize = %lu\n", totalDataSize);
447 
448     wrappedKeySizePtr = nativeKeyInfoArrayRaw +
449             sizeof(unsigned long)*2 + totalCkAttributesSize + totalDataSize;
450 
451     memcpy(&ckWrappedKeyLength, wrappedKeySizePtr, sizeof(unsigned long));
452     TRACE1("DEBUG: createNativeKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
453 
454     for (i = 0; i < nativeKeyInfoCkAttributesCount; i++) {
455         if ((*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen
456                 > 0) {
457             (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue =
458                     nativeKeyInfoArrayRawDataPtr;
459         }
460         nativeKeyInfoArrayRawDataPtr +=
461                 (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen;
462         nativeKeyInfoArrayRawCkAttributesPtr += sizeof(CK_ATTRIBUTE);
463     }
464 
465     if (ckWrappedKeyLength == 0) {
466         // Not a wrapped key
467         rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle,
468                 (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
469                 jLongToCKULong(nativeKeyInfoCkAttributesCount), &ckObjectHandle);
470     } else {
471         // Wrapped key
472         ckpMechanism = jMechanismToCKMechanismPtr(env, jWrappingMech);
473         rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, ckpMechanism,
474                 jLongToCKULong(jWrappingKeyHandle),
475                 (CK_BYTE_PTR)(wrappedKeySizePtr + sizeof(unsigned long)),
476                 ckWrappedKeyLength,
477                 (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
478                 jLongToCKULong(nativeKeyInfoCkAttributesCount),
479                 &ckObjectHandle);
480     }
481     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
482         goto cleanup;
483     }
484 
485     jObjectHandle = ckULongToJLong(ckObjectHandle);
486 
487 cleanup:
488 
489     if (nativeKeyInfoArrayRaw != NULL) {
490         (*env)->ReleaseByteArrayElements(env, jNativeKeyInfo,
491                 nativeKeyInfoArrayRaw, JNI_ABORT);
492     }
493 
494     freeCKMechanismPtr(ckpMechanism);
495     return jObjectHandle;
496 }
497 #endif
498 
499 #ifdef P11_ENABLE_C_GENERATEKEY
500 /*
501  * Class:     sun_security_pkcs11_wrapper_PKCS11
502  * Method:    C_GenerateKey
503  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
504  * Parametermapping:                    *PKCS11*
505  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
506  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
507  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
508  *                                      CK_ULONG ulCount
509  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
510  */
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jobjectArray jTemplate)511 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
512     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
513 {
514     CK_SESSION_HANDLE ckSessionHandle;
515     CK_MECHANISM_PTR ckpMechanism = NULL;
516     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
517     CK_ULONG ckAttributesLength = 0;
518     CK_OBJECT_HANDLE ckKeyHandle = 0;
519     jlong jKeyHandle = 0L;
520     CK_RV rv;
521 
522     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
523     if (ckpFunctions == NULL) { return 0L; }
524 
525     ckSessionHandle = jLongToCKULong(jSessionHandle);
526     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
527     if ((*env)->ExceptionCheck(env)) { return 0L ; }
528 
529     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
530     if ((*env)->ExceptionCheck(env)) {
531         goto cleanup;
532     }
533 
534     rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, ckpMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
535 
536     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
537         jKeyHandle = ckULongToJLong(ckKeyHandle);
538 
539         /* cheack, if we must give a initialization vector back to Java */
540         switch (ckpMechanism->mechanism) {
541         case CKM_PBE_MD2_DES_CBC:
542         case CKM_PBE_MD5_DES_CBC:
543         case CKM_PBE_MD5_CAST_CBC:
544         case CKM_PBE_MD5_CAST3_CBC:
545         case CKM_PBE_MD5_CAST128_CBC:
546         /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
547         case CKM_PBE_SHA1_CAST128_CBC:
548         /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
549             /* we must copy back the initialization vector to the jMechanism object */
550             copyBackPBEInitializationVector(env, ckpMechanism, jMechanism);
551             break;
552         }
553     }
554 cleanup:
555     freeCKMechanismPtr(ckpMechanism);
556     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
557 
558     return jKeyHandle ;
559 }
560 #endif
561 
562 #ifdef P11_ENABLE_C_GENERATEKEYPAIR
563 /*
564  * Class:     sun_security_pkcs11_wrapper_PKCS11
565  * Method:    C_GenerateKeyPair
566  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J
567  * Parametermapping:                          *PKCS11*
568  * @param   jlong jSessionHandle              CK_SESSION_HANDLE hSession
569  * @param   jobject jMechanism                CK_MECHANISM_PTR pMechanism
570  * @param   jobjectArray jPublicKeyTemplate   CK_ATTRIBUTE_PTR pPublicKeyTemplate
571  *                                            CK_ULONG ulPublicKeyAttributeCount
572  * @param   jobjectArray jPrivateKeyTemplate  CK_ATTRIBUTE_PTR pPrivateKeyTemplate
573  *                                            CK_ULONG ulPrivateKeyAttributeCount
574  * @return  jlongArray jKeyHandles            CK_OBJECT_HANDLE_PTR phPublicKey
575  *                                            CK_OBJECT_HANDLE_PTR phPublicKey
576  */
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jobjectArray jPublicKeyTemplate,jobjectArray jPrivateKeyTemplate)577 JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair
578     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
579      jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
580 {
581     CK_SESSION_HANDLE ckSessionHandle;
582     CK_MECHANISM_PTR ckpMechanism = NULL;
583     CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
584     CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
585     CK_ULONG ckPublicKeyAttributesLength = 0;
586     CK_ULONG ckPrivateKeyAttributesLength = 0;
587     CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle;  /* pointer to Public Key */
588     CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */
589     CK_OBJECT_HANDLE_PTR ckpKeyHandles = NULL; /* pointer to array with Public and Private Key */
590     jlongArray jKeyHandles = NULL;
591     CK_RV rv;
592 
593     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
594     if (ckpFunctions == NULL) { return NULL; }
595 
596     ckSessionHandle = jLongToCKULong(jSessionHandle);
597     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
598     if ((*env)->ExceptionCheck(env)) { return NULL; }
599 
600     ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) calloc(2, sizeof(CK_OBJECT_HANDLE));
601     if (ckpKeyHandles == NULL) {
602         throwOutOfMemoryError(env, 0);
603         goto cleanup;
604     }
605     ckpPublicKeyHandle = ckpKeyHandles;   /* first element of array is Public Key */
606     ckpPrivateKeyHandle = (ckpKeyHandles + 1);  /* second element of array is Private Key */
607 
608     jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength);
609     if ((*env)->ExceptionCheck(env)) {
610         goto cleanup;
611     }
612 
613     jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength);
614     if ((*env)->ExceptionCheck(env)) {
615         goto cleanup;
616     }
617 
618     rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, ckpMechanism,
619                      ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
620                      ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
621                      ckpPublicKeyHandle, ckpPrivateKeyHandle);
622 
623     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
624         jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
625     }
626 
627 cleanup:
628     freeCKMechanismPtr(ckpMechanism);
629     free(ckpKeyHandles);
630     freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
631     freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength);
632     return jKeyHandles ;
633 }
634 #endif
635 
636 #ifdef P11_ENABLE_C_WRAPKEY
637 /*
638  * Class:     sun_security_pkcs11_wrapper_PKCS11
639  * Method:    C_WrapKey
640  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B
641  * Parametermapping:                    *PKCS11*
642  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
643  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
644  * @param   jlong jWrappingKeyHandle    CK_OBJECT_HANDLE hWrappingKey
645  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
646  * @return  jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
647  *                                      CK_ULONG_PTR pulWrappedKeyLen
648  */
Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jWrappingKeyHandle,jlong jKeyHandle)649 JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey
650     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
651 {
652     CK_SESSION_HANDLE ckSessionHandle;
653     CK_MECHANISM_PTR ckpMechanism = NULL;
654     CK_OBJECT_HANDLE ckWrappingKeyHandle;
655     CK_OBJECT_HANDLE ckKeyHandle;
656     jbyteArray jWrappedKey = NULL;
657     CK_RV rv;
658     CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
659     CK_BYTE_PTR ckpWrappedKey = BUF;
660     CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN;
661 
662     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
663     if (ckpFunctions == NULL) { return NULL; }
664 
665     ckSessionHandle = jLongToCKULong(jSessionHandle);
666     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
667     if ((*env)->ExceptionCheck(env)) { return NULL; }
668 
669     ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
670     ckKeyHandle = jLongToCKULong(jKeyHandle);
671 
672     rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, ckpMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
673     if (rv == CKR_BUFFER_TOO_SMALL) {
674         ckpWrappedKey = (CK_BYTE_PTR)
675                 calloc(ckWrappedKeyLength, sizeof(CK_BYTE));
676         if (ckpWrappedKey == NULL) {
677             throwOutOfMemoryError(env, 0);
678             goto cleanup;
679         }
680 
681         rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, ckpMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
682     }
683     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
684         jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
685     }
686 
687 cleanup:
688     if (ckpWrappedKey != BUF) { free(ckpWrappedKey); }
689     freeCKMechanismPtr(ckpMechanism);
690 
691     return jWrappedKey ;
692 }
693 #endif
694 
695 #ifdef P11_ENABLE_C_UNWRAPKEY
696 /*
697  * Class:     sun_security_pkcs11_wrapper_PKCS11
698  * Method:    C_UnwrapKey
699  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
700  * Parametermapping:                    *PKCS11*
701  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
702  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
703  * @param   jlong jUnwrappingKeyHandle  CK_OBJECT_HANDLE hUnwrappingKey
704  * @param   jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
705  *                                      CK_ULONG_PTR pulWrappedKeyLen
706  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
707  *                                      CK_ULONG ulCount
708  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
709  */
Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jUnwrappingKeyHandle,jbyteArray jWrappedKey,jobjectArray jTemplate)710 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey
711     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
712      jbyteArray jWrappedKey, jobjectArray jTemplate)
713 {
714     CK_SESSION_HANDLE ckSessionHandle;
715     CK_MECHANISM_PTR ckpMechanism = NULL;
716     CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
717     CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
718     CK_ULONG ckWrappedKeyLength;
719     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
720     CK_ULONG ckAttributesLength = 0;
721     CK_OBJECT_HANDLE ckKeyHandle = 0;
722     jlong jKeyHandle = 0L;
723     CK_RV rv;
724 
725     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
726     if (ckpFunctions == NULL) { return 0L; }
727 
728     ckSessionHandle = jLongToCKULong(jSessionHandle);
729     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
730     if ((*env)->ExceptionCheck(env)) { return 0L; }
731 
732     ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
733     jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength);
734     if ((*env)->ExceptionCheck(env)) {
735         goto cleanup;
736     }
737 
738     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
739     if ((*env)->ExceptionCheck(env)) {
740         goto cleanup;
741     }
742 
743 
744     rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, ckpMechanism, ckUnwrappingKeyHandle,
745                  ckpWrappedKey, ckWrappedKeyLength,
746                  ckpAttributes, ckAttributesLength, &ckKeyHandle);
747 
748     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
749         jKeyHandle = ckLongToJLong(ckKeyHandle);
750 
751 #if 0
752         /* cheack, if we must give a initialization vector back to Java */
753         if (ckpMechanism->mechanism == CKM_KEY_WRAP_SET_OAEP) {
754             /* we must copy back the unwrapped key info to the jMechanism object */
755             copyBackSetUnwrappedKey(env, ckpMechanism, jMechanism);
756         }
757 #endif
758     }
759 cleanup:
760     freeCKMechanismPtr(ckpMechanism);
761     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
762     free(ckpWrappedKey);
763 
764     return jKeyHandle ;
765 }
766 #endif
767 
768 #ifdef P11_ENABLE_C_DERIVEKEY
769 
770 /*
771  * Copy back the PRF output to Java.
772  */
copyBackTLSPrfParams(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism)773 void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism, jobject jMechanism)
774 {
775     jclass jMechanismClass, jTLSPrfParamsClass;
776     CK_TLS_PRF_PARAMS *ckTLSPrfParams;
777     jobject jTLSPrfParams;
778     jfieldID fieldID;
779     CK_MECHANISM_TYPE ckMechanismType;
780     jlong jMechanismType;
781     CK_BYTE_PTR output;
782     jobject jOutput;
783     jint jLength;
784     jbyte* jBytes;
785     int i;
786 
787     /* get mechanism */
788     jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
789     if (jMechanismClass == NULL) { return; }
790     fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
791     if (fieldID == NULL) { return; }
792     jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
793     ckMechanismType = jLongToCKULong(jMechanismType);
794     if (ckMechanismType != ckpMechanism->mechanism) {
795         /* we do not have maching types, this should not occur */
796         return;
797     }
798 
799     /* get the native CK_TLS_PRF_PARAMS */
800     ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckpMechanism->pParameter;
801     if (ckTLSPrfParams != NULL_PTR) {
802         /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */
803         fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
804         if (fieldID == NULL) { return; }
805         jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID);
806 
807         /* copy back the client IV */
808         jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
809         if (jTLSPrfParamsClass == NULL) { return; }
810         fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B");
811         if (fieldID == NULL) { return; }
812         jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID);
813         output = ckTLSPrfParams->pOutput;
814 
815         // Note: we assume that the token returned exactly as many bytes as we
816         // requested. Anything else would not make sense.
817         if (jOutput != NULL) {
818             jLength = (*env)->GetArrayLength(env, jOutput);
819             jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL);
820             if (jBytes == NULL) { return; }
821 
822             /* copy the bytes to the Java buffer */
823             for (i=0; i < jLength; i++) {
824                 jBytes[i] = ckByteToJByte(output[i]);
825             }
826             /* copy back the Java buffer to the object */
827             (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
828         }
829     }
830 }
831 
832 /*
833  * Class:     sun_security_pkcs11_wrapper_PKCS11
834  * Method:    C_DeriveKey
835  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
836  * Parametermapping:                    *PKCS11*
837  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
838  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
839  * @param   jlong jBaseKeyHandle        CK_OBJECT_HANDLE hBaseKey
840  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
841  *                                      CK_ULONG ulCount
842  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
843  */
Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jBaseKeyHandle,jobjectArray jTemplate)844 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey
845     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
846 {
847     CK_SESSION_HANDLE ckSessionHandle;
848     CK_MECHANISM_PTR ckpMechanism = NULL;
849     CK_OBJECT_HANDLE ckBaseKeyHandle;
850     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
851     CK_ULONG ckAttributesLength = 0;
852     CK_OBJECT_HANDLE ckKeyHandle = 0;
853     jlong jKeyHandle = 0L;
854     CK_RV rv;
855     CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle;
856 
857     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
858     if (ckpFunctions == NULL) { return 0L; }
859 
860     ckSessionHandle = jLongToCKULong(jSessionHandle);
861     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
862     if ((*env)->ExceptionCheck(env)) { return 0L; }
863 
864     ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
865     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
866     if ((*env)->ExceptionCheck(env)) {
867         goto cleanup;
868     }
869 
870     switch (ckpMechanism->mechanism) {
871     case CKM_SSL3_KEY_AND_MAC_DERIVE:
872     case CKM_TLS_KEY_AND_MAC_DERIVE:
873     case CKM_TLS12_KEY_AND_MAC_DERIVE:
874     case CKM_TLS_PRF:
875         // these mechanism do not return a key handle via phKey
876         // set to NULL in case pedantic implementations check for it
877         phKey = NULL;
878         break;
879     default:
880         // empty
881         break;
882     }
883 
884     rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, ckpMechanism, ckBaseKeyHandle,
885                  ckpAttributes, ckAttributesLength, phKey);
886 
887     jKeyHandle = ckLongToJLong(ckKeyHandle);
888 
889     switch (ckpMechanism->mechanism) {
890     case CKM_SSL3_MASTER_KEY_DERIVE:
891     case CKM_TLS_MASTER_KEY_DERIVE:
892         /* we must copy back the client version */
893         ssl3CopyBackClientVersion(env, ckpMechanism, jMechanism);
894         break;
895     case CKM_TLS12_MASTER_KEY_DERIVE:
896         tls12CopyBackClientVersion(env, ckpMechanism, jMechanism);
897         break;
898     case CKM_SSL3_KEY_AND_MAC_DERIVE:
899     case CKM_TLS_KEY_AND_MAC_DERIVE:
900         /* we must copy back the unwrapped key info to the jMechanism object */
901         ssl3CopyBackKeyMatParams(env, ckpMechanism, jMechanism);
902         break;
903     case CKM_TLS12_KEY_AND_MAC_DERIVE:
904         /* we must copy back the unwrapped key info to the jMechanism object */
905         tls12CopyBackKeyMatParams(env, ckpMechanism, jMechanism);
906         break;
907     case CKM_TLS_PRF:
908         copyBackTLSPrfParams(env, ckpMechanism, jMechanism);
909         break;
910     default:
911         // empty
912         break;
913     }
914     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
915         jKeyHandle =0L;
916     }
917 
918 cleanup:
919     freeCKMechanismPtr(ckpMechanism);
920     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
921 
922     return jKeyHandle ;
923 }
924 
copyBackClientVersion(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism,CK_VERSION * ckVersion,const char * class_master_key_derive_params)925 static void copyBackClientVersion(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism, jobject jMechanism,
926         CK_VERSION *ckVersion, const char *class_master_key_derive_params)
927 {
928     jclass jMasterKeyDeriveParamsClass, jMechanismClass, jVersionClass;
929     jobject jMasterKeyDeriveParams;
930     jfieldID fieldID;
931     CK_MECHANISM_TYPE ckMechanismType;
932     jlong jMechanismType;
933     jobject jVersion;
934 
935     /* get mechanism */
936     jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
937     if (jMechanismClass == NULL) { return; }
938     fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
939     if (fieldID == NULL) { return; }
940     jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
941     ckMechanismType = jLongToCKULong(jMechanismType);
942     if (ckMechanismType != ckpMechanism->mechanism) {
943         /* we do not have maching types, this should not occur */
944         return;
945     }
946 
947     if (ckVersion != NULL_PTR) {
948       /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
949       fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
950       if (fieldID == NULL) { return; }
951 
952       jMasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
953 
954       /* get the Java CK_VERSION */
955       jMasterKeyDeriveParamsClass = (*env)->FindClass(env, class_master_key_derive_params);
956       if (jMasterKeyDeriveParamsClass == NULL) { return; }
957       fieldID = (*env)->GetFieldID(env, jMasterKeyDeriveParamsClass,
958               "pVersion", "L"CLASS_VERSION";");
959       if (fieldID == NULL) { return; }
960       jVersion = (*env)->GetObjectField(env, jMasterKeyDeriveParams, fieldID);
961 
962       /* now copy back the version from the native structure to the Java structure */
963 
964       /* copy back the major version */
965       jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
966       if (jVersionClass == NULL) { return; }
967       fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
968       if (fieldID == NULL) { return; }
969       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
970 
971       /* copy back the minor version */
972       fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
973       if (fieldID == NULL) { return; }
974       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
975     }
976 }
977 
978 /*
979  * Copy back the client version information from the native
980  * structure to the Java object. This is only used for
981  * CKM_SSL3_MASTER_KEY_DERIVE and CKM_TLS_MASTER_KEY_DERIVE
982  * mechanisms when used for deriving a key.
983  *
984  */
ssl3CopyBackClientVersion(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism)985 void ssl3CopyBackClientVersion(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism,
986         jobject jMechanism)
987 {
988     CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
989     ckSSL3MasterKeyDeriveParams =
990             (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)ckpMechanism->pParameter;
991     if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
992         copyBackClientVersion(env, ckpMechanism, jMechanism,
993                 ckSSL3MasterKeyDeriveParams->pVersion,
994                 CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
995     }
996 }
997 
998 /*
999  * Copy back the client version information from the native
1000  * structure to the Java object. This is only used for
1001  * CKM_TLS12_MASTER_KEY_DERIVE mechanism when used for deriving a key.
1002  *
1003  */
tls12CopyBackClientVersion(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism)1004 void tls12CopyBackClientVersion(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism,
1005         jobject jMechanism)
1006 {
1007     CK_TLS12_MASTER_KEY_DERIVE_PARAMS *ckTLS12MasterKeyDeriveParams;
1008     ckTLS12MasterKeyDeriveParams =
1009             (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)ckpMechanism->pParameter;
1010     if (ckTLS12MasterKeyDeriveParams != NULL_PTR) {
1011         copyBackClientVersion(env, ckpMechanism, jMechanism,
1012                 ckTLS12MasterKeyDeriveParams->pVersion,
1013                 CLASS_TLS12_MASTER_KEY_DERIVE_PARAMS);
1014     }
1015 }
1016 
copyBackKeyMatParams(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism,CK_SSL3_RANDOM_DATA * RandomInfo,CK_SSL3_KEY_MAT_OUT_PTR ckSSL3KeyMatOut,const char * class_key_mat_params)1017 static void copyBackKeyMatParams(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism,
1018         jobject jMechanism, CK_SSL3_RANDOM_DATA *RandomInfo,
1019         CK_SSL3_KEY_MAT_OUT_PTR ckSSL3KeyMatOut, const char *class_key_mat_params)
1020 {
1021     jclass jMechanismClass, jKeyMatParamsClass, jSSL3KeyMatOutClass;
1022     jfieldID fieldID;
1023     CK_MECHANISM_TYPE ckMechanismType;
1024     jlong jMechanismType;
1025     CK_BYTE_PTR iv;
1026     jobject jKeyMatParam;
1027     jobject jSSL3KeyMatOut;
1028     jobject jIV;
1029     jint jLength;
1030     jbyte* jBytes;
1031     int i;
1032 
1033     /* get mechanism */
1034     jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
1035     if (jMechanismClass == NULL) { return; }
1036     fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
1037     if (fieldID == NULL) { return; }
1038     jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
1039     ckMechanismType = jLongToCKULong(jMechanismType);
1040     if (ckMechanismType != ckpMechanism->mechanism) {
1041         /* we do not have maching types, this should not occur */
1042         return;
1043     }
1044 
1045     if (ckSSL3KeyMatOut != NULL_PTR) {
1046       /* get the Java params object (pParameter) */
1047       fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter",
1048               "Ljava/lang/Object;");
1049       if (fieldID == NULL) { return; }
1050       jKeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
1051 
1052       /* get the Java CK_SSL3_KEY_MAT_OUT */
1053       jKeyMatParamsClass = (*env)->FindClass(env, class_key_mat_params);
1054       if (jKeyMatParamsClass == NULL) { return; }
1055       fieldID = (*env)->GetFieldID(env, jKeyMatParamsClass,
1056               "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
1057       if (fieldID == NULL) { return; }
1058       jSSL3KeyMatOut = (*env)->GetObjectField(env, jKeyMatParam, fieldID);
1059 
1060       /* now copy back all the key handles and the initialization vectors */
1061       /* copy back client MAC secret handle */
1062       jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
1063       if (jSSL3KeyMatOutClass == NULL) { return; }
1064       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass,
1065               "hClientMacSecret", "J");
1066       if (fieldID == NULL) { return; }
1067       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID,
1068               ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
1069 
1070       /* copy back server MAC secret handle */
1071       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass,
1072               "hServerMacSecret", "J");
1073       if (fieldID == NULL) { return; }
1074       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID,
1075               ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
1076 
1077       /* copy back client secret key handle */
1078       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
1079       if (fieldID == NULL) { return; }
1080       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID,
1081               ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
1082 
1083       /* copy back server secret key handle */
1084       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
1085       if (fieldID == NULL) { return; }
1086       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID,
1087               ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
1088 
1089       /* copy back the client IV */
1090       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
1091       if (fieldID == NULL) { return; }
1092       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
1093       iv = ckSSL3KeyMatOut->pIVClient;
1094 
1095       if (jIV != NULL) {
1096         jLength = (*env)->GetArrayLength(env, jIV);
1097         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
1098         if (jBytes == NULL) { return; }
1099         /* copy the bytes to the Java buffer */
1100         for (i=0; i < jLength; i++) {
1101           jBytes[i] = ckByteToJByte(iv[i]);
1102         }
1103         /* copy back the Java buffer to the object */
1104         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
1105       }
1106 
1107       /* copy back the server IV */
1108       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
1109       if (fieldID == NULL) { return; }
1110       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
1111       iv = ckSSL3KeyMatOut->pIVServer;
1112 
1113       if (jIV != NULL) {
1114         jLength = (*env)->GetArrayLength(env, jIV);
1115         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
1116         if (jBytes == NULL) { return; }
1117         /* copy the bytes to the Java buffer */
1118         for (i=0; i < jLength; i++) {
1119           jBytes[i] = ckByteToJByte(iv[i]);
1120         }
1121         /* copy back the Java buffer to the object */
1122         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
1123       }
1124     }
1125 }
1126 
1127 /*
1128  * Copy back the derived keys and initialization vectors from the native
1129  * structure to the Java object. This is only used for
1130  * CKM_SSL3_KEY_AND_MAC_DERIVE and CKM_TLS_KEY_AND_MAC_DERIVE mechanisms
1131  * when used for deriving a key.
1132  *
1133  */
ssl3CopyBackKeyMatParams(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism)1134 void ssl3CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism,
1135         jobject jMechanism)
1136 {
1137     CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
1138     ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *)ckpMechanism->pParameter;
1139     if (ckSSL3KeyMatParam != NULL_PTR) {
1140         copyBackKeyMatParams(env, ckpMechanism, jMechanism,
1141                 &(ckSSL3KeyMatParam->RandomInfo),
1142                 ckSSL3KeyMatParam->pReturnedKeyMaterial,
1143                 CLASS_SSL3_KEY_MAT_PARAMS);
1144     }
1145 }
1146 
1147 /*
1148  * Copy back the derived keys and initialization vectors from the native
1149  * structure to the Java object. This is only used for
1150  * CKM_TLS12_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
1151  *
1152  */
tls12CopyBackKeyMatParams(JNIEnv * env,CK_MECHANISM_PTR ckpMechanism,jobject jMechanism)1153 void tls12CopyBackKeyMatParams(JNIEnv *env, CK_MECHANISM_PTR ckpMechanism,
1154         jobject jMechanism)
1155 {
1156     CK_TLS12_KEY_MAT_PARAMS *ckTLS12KeyMatParam;
1157     ckTLS12KeyMatParam = (CK_TLS12_KEY_MAT_PARAMS *)ckpMechanism->pParameter;
1158     if (ckTLS12KeyMatParam != NULL_PTR) {
1159         copyBackKeyMatParams(env, ckpMechanism, jMechanism,
1160                 &(ckTLS12KeyMatParam->RandomInfo),
1161                 ckTLS12KeyMatParam->pReturnedKeyMaterial,
1162                 CLASS_TLS12_KEY_MAT_PARAMS);
1163     }
1164 }
1165 
1166 #endif
1167