1/*
2 * Copyright (c) 2003, 2011, 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_CREATEOBJECT
58/*
59 * Class: sun_security_pkcs11_wrapper_PKCS11
60 * Method: C_CreateObject
61 * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
62 * Parametermapping: *PKCS11*
63 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
64 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
65 * CK_ULONG ulCount
66 * @return jlong jObjectHandle CK_OBJECT_HANDLE_PTR phObject
67 */
68JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject
69 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
70{
71 CK_SESSION_HANDLE ckSessionHandle;
72 CK_OBJECT_HANDLE ckObjectHandle;
73 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
74 CK_ULONG ckAttributesLength;
75 jlong jObjectHandle = 0L;
76 CK_RV rv;
77
78 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
79 if (ckpFunctions == NULL) { return 0L; }
80
81 ckSessionHandle = jLongToCKULong(jSessionHandle);
82 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
83 if ((*env)->ExceptionCheck(env)) { return 0L; }
84
85 rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);
86
87 jObjectHandle = ckULongToJLong(ckObjectHandle);
88 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
89
90 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
91
92 return jObjectHandle ;
93}
94#endif
95
96#ifdef P11_ENABLE_C_COPYOBJECT
97/*
98 * Class: sun_security_pkcs11_wrapper_PKCS11
99 * Method: C_CopyObject
100 * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
101 * Parametermapping: *PKCS11*
102 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
103 * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
104 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
105 * CK_ULONG ulCount
106 * @return jlong jNewObjectHandle CK_OBJECT_HANDLE_PTR phNewObject
107 */
108JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CopyObject
109 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
110{
111 CK_SESSION_HANDLE ckSessionHandle;
112 CK_OBJECT_HANDLE ckObjectHandle;
113 CK_OBJECT_HANDLE ckNewObjectHandle;
114 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
115 CK_ULONG ckAttributesLength;
116 jlong jNewObjectHandle = 0L;
117 CK_RV rv;
118
119 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
120 if (ckpFunctions == NULL) { return 0L; }
121
122 ckSessionHandle = jLongToCKULong(jSessionHandle);
123 ckObjectHandle = jLongToCKULong(jObjectHandle);
124 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
125 if ((*env)->ExceptionCheck(env)) { return 0L; }
126
127 rv = (*ckpFunctions->C_CopyObject)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength, &ckNewObjectHandle);
128
129 jNewObjectHandle = ckULongToJLong(ckNewObjectHandle);
130 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
131
132 if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
133
134 return jNewObjectHandle ;
135}
136#endif
137
138#ifdef P11_ENABLE_C_DESTROYOBJECT
139/*
140 * Class: sun_security_pkcs11_wrapper_PKCS11
141 * Method: C_DestroyObject
142 * Signature: (JJ)V
143 * Parametermapping: *PKCS11*
144 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
145 * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
146 */
147JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DestroyObject
148 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
149{
150 CK_SESSION_HANDLE ckSessionHandle;
151 CK_OBJECT_HANDLE ckObjectHandle;
152 CK_RV rv;
153
154 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
155 if (ckpFunctions == NULL) { return; }
156
157 ckSessionHandle = jLongToCKULong(jSessionHandle);
158 ckObjectHandle = jLongToCKULong(jObjectHandle);
159
160 rv = (*ckpFunctions->C_DestroyObject)(ckSessionHandle, ckObjectHandle);
161 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
162}
163#endif
164
165#ifdef P11_ENABLE_C_GETOBJECTSIZE
166/*
167 * Class: sun_security_pkcs11_wrapper_PKCS11
168 * Method: C_GetObjectSize
169 * Signature: (JJ)J
170 * Parametermapping: *PKCS11*
171 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
172 * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
173 * @return jlong jObjectSize CK_ULONG_PTR pulSize
174 */
175JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize
176 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
177{
178 CK_SESSION_HANDLE ckSessionHandle;
179 CK_OBJECT_HANDLE ckObjectHandle;
180 CK_ULONG ckObjectSize;
181 jlong jObjectSize = 0L;
182 CK_RV rv;
183
184 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
185 if (ckpFunctions == NULL) { return 0L; }
186
187 ckSessionHandle = jLongToCKULong(jSessionHandle);
188 ckObjectHandle = jLongToCKULong(jObjectHandle);
189
190 rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
191 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
192
193 jObjectSize = ckULongToJLong(ckObjectSize);
194
195 return jObjectSize ;
196}
197#endif
198
199#ifdef P11_ENABLE_C_GETATTRIBUTEVALUE
200/*
201 * Class: sun_security_pkcs11_wrapper_PKCS11
202 * Method: C_GetAttributeValue
203 * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;
204 * Parametermapping: *PKCS11*
205 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
206 * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
207 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
208 * CK_ULONG ulCount
209 */
210JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeValue
211 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
212{
213 CK_SESSION_HANDLE ckSessionHandle;
214 CK_OBJECT_HANDLE ckObjectHandle;
215 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
216 CK_ULONG ckAttributesLength;
217 CK_ULONG ckBufferLength;
218 CK_ULONG i;
219 jobject jAttribute;
220 CK_RV rv;
221
222 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
223 if (ckpFunctions == NULL) { return; }
224
225 TRACE0("DEBUG: C_GetAttributeValue");
226 TRACE1(", hSession=%u", jSessionHandle);
227 TRACE1(", hObject=%u", jObjectHandle);
228 TRACE1(", pTemplate=%p", jTemplate);
229 TRACE0(" ... ");
230
231 ckSessionHandle = jLongToCKULong(jSessionHandle);
232 ckObjectHandle = jLongToCKULong(jObjectHandle);
233 TRACE1("jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate);
234 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
235 if ((*env)->ExceptionCheck(env)) { return; }
236
237 TRACE2("DEBUG: jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength);
238
239 /* first set all pValue to NULL, to get the needed buffer length */
240 for(i = 0; i < ckAttributesLength; i++) {
241 if (ckpAttributes[i].pValue != NULL_PTR) {
242 free(ckpAttributes[i].pValue);
243 ckpAttributes[i].pValue = NULL_PTR;
244 }
245 }
246
247 rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
248 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
249 free(ckpAttributes);
250 return ;
251 }
252
253 /* now, the ulValueLength field of each attribute should hold the exact buffer length needed
254 * allocate the needed buffers accordingly
255 */
256 for (i = 0; i < ckAttributesLength; i++) {
257 ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
258 ckpAttributes[i].pValue = (void *) malloc(ckBufferLength);
259 if (ckpAttributes[i].pValue == NULL) {
260 freeCKAttributeArray(ckpAttributes, i);
261 throwOutOfMemoryError(env, 0);
262 return;
263 }
264 ckpAttributes[i].ulValueLen = ckBufferLength;
265 }
266
267 /* now get the attributes with all values */
268 rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
269
270 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
271 /* copy back the values to the Java attributes */
272 for (i = 0; i < ckAttributesLength; i++) {
273 jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i]));
274 if (jAttribute == NULL) {
275 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
276 return;
277 }
278 (*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute);
279 if ((*env)->ExceptionCheck(env)) {
280 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
281 return;
282 }
283 }
284 }
285 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
286 TRACE0("FINISHED\n");
287}
288#endif
289
290#ifdef P11_ENABLE_C_SETATTRIBUTEVALUE
291/*
292 * Class: sun_security_pkcs11_wrapper_PKCS11
293 * Method: C_SetAttributeValue
294 * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
295 * Parametermapping: *PKCS11*
296 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
297 * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
298 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
299 * CK_ULONG ulCount
300 */
301JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetAttributeValue
302 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
303{
304 CK_SESSION_HANDLE ckSessionHandle;
305 CK_OBJECT_HANDLE ckObjectHandle;
306 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
307 CK_ULONG ckAttributesLength;
308 CK_RV rv;
309
310 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
311 if (ckpFunctions == NULL) { return; }
312
313 ckSessionHandle = jLongToCKULong(jSessionHandle);
314 ckObjectHandle = jLongToCKULong(jObjectHandle);
315 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
316 if ((*env)->ExceptionCheck(env)) { return; }
317
318 rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
319
320 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
321
322 if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
323}
324#endif
325
326#ifdef P11_ENABLE_C_FINDOBJECTSINIT
327/*
328 * Class: sun_security_pkcs11_wrapper_PKCS11
329 * Method: C_FindObjectsInit
330 * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
331 * Parametermapping: *PKCS11*
332 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
333 * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
334 * CK_ULONG ulCount
335 */
336JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsInit
337 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
338{
339 CK_SESSION_HANDLE ckSessionHandle;
340 CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
341 CK_ULONG ckAttributesLength;
342 CK_RV rv;
343
344 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
345 if (ckpFunctions == NULL) { return; }
346
347 TRACE0("DEBUG: C_FindObjectsInit");
348 TRACE1(", hSession=%u", jSessionHandle);
349 TRACE1(", pTemplate=%p", jTemplate);
350 TRACE0(" ... ");
351
352 ckSessionHandle = jLongToCKULong(jSessionHandle);
353 jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
354 if ((*env)->ExceptionCheck(env)) { return; }
355
356 rv = (*ckpFunctions->C_FindObjectsInit)(ckSessionHandle, ckpAttributes, ckAttributesLength);
357
358 freeCKAttributeArray(ckpAttributes, ckAttributesLength);
359 TRACE0("FINISHED\n");
360
361 if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
362}
363#endif
364
365#ifdef P11_ENABLE_C_FINDOBJECTS
366/*
367 * Class: sun_security_pkcs11_wrapper_PKCS11
368 * Method: C_FindObjects
369 * Signature: (JJ)[J
370 * Parametermapping: *PKCS11*
371 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
372 * @param jlong jMaxObjectCount CK_ULONG ulMaxObjectCount
373 * @return jlongArray jObjectHandleArray CK_OBJECT_HANDLE_PTR phObject
374 * CK_ULONG_PTR pulObjectCount
375 */
376JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjects
377 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jMaxObjectCount)
378{
379 CK_RV rv;
380 CK_SESSION_HANDLE ckSessionHandle;
381 CK_ULONG ckMaxObjectLength;
382 CK_OBJECT_HANDLE_PTR ckpObjectHandleArray;
383 CK_ULONG ckActualObjectCount;
384 jlongArray jObjectHandleArray = NULL;
385
386 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
387 if (ckpFunctions == NULL) { return NULL; }
388
389 ckSessionHandle = jLongToCKULong(jSessionHandle);
390 ckMaxObjectLength = jLongToCKULong(jMaxObjectCount);
391 ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength);
392 if (ckpObjectHandleArray == NULL) {
393 throwOutOfMemoryError(env, 0);
394 return NULL;
395 }
396
397 rv = (*ckpFunctions->C_FindObjects)(ckSessionHandle, ckpObjectHandleArray, ckMaxObjectLength, &ckActualObjectCount);
398 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
399 jObjectHandleArray = ckULongArrayToJLongArray(env, ckpObjectHandleArray, ckActualObjectCount);
400 }
401
402 free(ckpObjectHandleArray);
403
404 return jObjectHandleArray ;
405}
406#endif
407
408#ifdef P11_ENABLE_C_FINDOBJECTSFINAL
409/*
410 * Class: sun_security_pkcs11_wrapper_PKCS11
411 * Method: C_FindObjectsFinal
412 * Signature: (J)V
413 * Parametermapping: *PKCS11*
414 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
415 */
416JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsFinal
417 (JNIEnv *env, jobject obj, jlong jSessionHandle)
418{
419 CK_SESSION_HANDLE ckSessionHandle;
420 CK_RV rv;
421
422 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
423 if (ckpFunctions == NULL) { return; }
424
425 ckSessionHandle = jLongToCKULong(jSessionHandle);
426 rv = (*ckpFunctions->C_FindObjectsFinal)(ckSessionHandle);
427 if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
428}
429#endif
430