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 | #include "jlong.h" |
55 | |
56 | #include "sun_security_pkcs11_wrapper_PKCS11.h" |
57 | |
58 | #ifdef P11_ENABLE_C_DIGESTINIT |
59 | /* |
60 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
61 | * Method: C_DigestInit |
62 | * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;)V |
63 | * Parametermapping: *PKCS11* |
64 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
65 | * @param jobject jMechanism CK_MECHANISM_PTR pMechanism |
66 | */ |
67 | JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestInit |
68 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism) |
69 | { |
70 | CK_SESSION_HANDLE ckSessionHandle; |
71 | CK_MECHANISM_PTR ckpMechanism = NULL; |
72 | CK_RV rv; |
73 | |
74 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
75 | if (ckpFunctions == NULL) { return; } |
76 | |
77 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
78 | ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism); |
79 | if ((*env)->ExceptionCheck(env)) { return; } |
80 | |
81 | rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, ckpMechanism); |
82 | |
83 | freeCKMechanismPtr(ckpMechanism); |
84 | |
85 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } |
86 | } |
87 | #endif |
88 | |
89 | #ifdef P11_ENABLE_C_DIGEST |
90 | /* |
91 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
92 | * Method: C_Digest |
93 | * Signature: (J[BII[BII)I |
94 | * Parametermapping: *PKCS11* |
95 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
96 | * @param jbyteArray jData CK_BYTE_PTR pData |
97 | * CK_ULONG ulDataLen |
98 | * @return jbyteArray jDigest CK_BYTE_PTR pDigest |
99 | * CK_ULONG_PTR pulDigestLen |
100 | */ |
101 | JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle |
102 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, |
103 | jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jDigest, |
104 | jint jDigestOfs, jint jDigestLen) |
105 | { |
106 | CK_SESSION_HANDLE ckSessionHandle; |
107 | CK_RV rv; |
108 | CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; |
109 | CK_BYTE_PTR bufP = BUF; |
110 | CK_BYTE DIGESTBUF[MAX_DIGEST_LEN]; |
111 | CK_ULONG ckDigestLength = 0; |
112 | CK_MECHANISM_PTR ckpMechanism = NULL; |
113 | |
114 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
115 | if (ckpFunctions == NULL) { return 0; } |
116 | |
117 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
118 | ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism); |
119 | if ((*env)->ExceptionCheck(env)) { return 0; } |
120 | |
121 | rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, ckpMechanism); |
122 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { goto cleanup; } |
123 | |
124 | if (jInLen > MAX_STACK_BUFFER_LEN) { |
125 | /* always use single part op, even for large data */ |
126 | bufP = (CK_BYTE_PTR) malloc((size_t)jInLen); |
127 | if (bufP == NULL) { |
128 | throwOutOfMemoryError(env, 0); |
129 | goto cleanup; |
130 | } |
131 | } |
132 | |
133 | (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)bufP); |
134 | if ((*env)->ExceptionCheck(env)) { |
135 | goto cleanup; |
136 | } |
137 | |
138 | ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen); |
139 | |
140 | rv = (*ckpFunctions->C_Digest)(ckSessionHandle, bufP, jInLen, DIGESTBUF, &ckDigestLength); |
141 | if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { |
142 | (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)DIGESTBUF); |
143 | } |
144 | cleanup: |
145 | freeCKMechanismPtr(ckpMechanism); |
146 | if (bufP != BUF) { free(bufP); } |
147 | |
148 | return ckDigestLength; |
149 | } |
150 | #endif |
151 | |
152 | #ifdef P11_ENABLE_C_DIGESTUPDATE |
153 | /* |
154 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
155 | * Method: C_DigestUpdate |
156 | * Signature: (J[B)V |
157 | * Parametermapping: *PKCS11* |
158 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
159 | * @param jbyteArray jData CK_BYTE_PTR pData |
160 | * CK_ULONG ulDataLen |
161 | */ |
162 | JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestUpdate |
163 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, |
164 | jint jInOfs, jint jInLen) |
165 | { |
166 | CK_SESSION_HANDLE ckSessionHandle; |
167 | CK_RV rv; |
168 | CK_BYTE_PTR bufP; |
169 | CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; |
170 | jsize bufLen; |
171 | |
172 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
173 | if (ckpFunctions == NULL) { return; } |
174 | |
175 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
176 | |
177 | if (directIn != 0) { |
178 | rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen); |
179 | ckAssertReturnValueOK(env, rv); |
180 | return; |
181 | } |
182 | |
183 | if (jInLen <= MAX_STACK_BUFFER_LEN) { |
184 | bufLen = MAX_STACK_BUFFER_LEN; |
185 | bufP = BUF; |
186 | } else { |
187 | bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); |
188 | bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); |
189 | if (bufP == NULL) { |
190 | throwOutOfMemoryError(env, 0); |
191 | return; |
192 | } |
193 | } |
194 | |
195 | while (jInLen > 0) { |
196 | jsize chunkLen = min(bufLen, jInLen); |
197 | (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP); |
198 | if ((*env)->ExceptionCheck(env)) { |
199 | if (bufP != BUF) { free(bufP); } |
200 | return; |
201 | } |
202 | rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, bufP, chunkLen); |
203 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { |
204 | if (bufP != BUF) { free(bufP); } |
205 | return; |
206 | } |
207 | jInOfs += chunkLen; |
208 | jInLen -= chunkLen; |
209 | } |
210 | |
211 | if (bufP != BUF) { |
212 | free(bufP); |
213 | } |
214 | } |
215 | #endif |
216 | |
217 | #ifdef P11_ENABLE_C_DIGESTKEY |
218 | /* |
219 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
220 | * Method: C_DigestKey |
221 | * Signature: (JJ)V |
222 | * Parametermapping: *PKCS11* |
223 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
224 | * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey |
225 | */ |
226 | JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestKey |
227 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle) |
228 | { |
229 | CK_SESSION_HANDLE ckSessionHandle; |
230 | CK_ULONG ckKeyHandle; |
231 | CK_RV rv; |
232 | |
233 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
234 | if (ckpFunctions == NULL) { return; } |
235 | |
236 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
237 | ckKeyHandle = jLongToCKULong(jKeyHandle); |
238 | |
239 | rv = (*ckpFunctions->C_DigestKey)(ckSessionHandle, ckKeyHandle); |
240 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } |
241 | } |
242 | #endif |
243 | |
244 | #ifdef P11_ENABLE_C_DIGESTFINAL |
245 | /* |
246 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
247 | * Method: C_DigestFinal |
248 | * Signature: (J[BII)I |
249 | * Parametermapping: *PKCS11* |
250 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
251 | * @return jbyteArray jDigest CK_BYTE_PTR pDigest |
252 | * CK_ULONG_PTR pulDigestLen |
253 | */ |
254 | JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestFinal |
255 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jDigest, |
256 | jint jDigestOfs, jint jDigestLen) |
257 | { |
258 | CK_SESSION_HANDLE ckSessionHandle; |
259 | CK_RV rv; |
260 | CK_BYTE BUF[MAX_DIGEST_LEN]; |
261 | CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen); |
262 | |
263 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
264 | if (ckpFunctions == NULL) { return 0; } |
265 | |
266 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
267 | |
268 | rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, BUF, &ckDigestLength); |
269 | if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { |
270 | (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)BUF); |
271 | } |
272 | return ckDigestLength; |
273 | } |
274 | #endif |
275 | |
276 | #ifdef P11_ENABLE_C_SEEDRANDOM |
277 | /* |
278 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
279 | * Method: C_SeedRandom |
280 | * Signature: (J[B)V |
281 | * Parametermapping: *PKCS11* |
282 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
283 | * @param jbyteArray jSeed CK_BYTE_PTR pSeed |
284 | * CK_ULONG ulSeedLen |
285 | */ |
286 | JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SeedRandom |
287 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed) |
288 | { |
289 | CK_SESSION_HANDLE ckSessionHandle; |
290 | CK_BYTE_PTR ckpSeed = NULL_PTR; |
291 | CK_ULONG ckSeedLength; |
292 | CK_RV rv; |
293 | |
294 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
295 | if (ckpFunctions == NULL) { return; } |
296 | |
297 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
298 | jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength); |
299 | if ((*env)->ExceptionCheck(env)) { return; } |
300 | |
301 | rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength); |
302 | |
303 | free(ckpSeed); |
304 | |
305 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } |
306 | } |
307 | #endif |
308 | |
309 | #ifdef P11_ENABLE_C_GENERATERANDOM |
310 | /* |
311 | * Class: sun_security_pkcs11_wrapper_PKCS11 |
312 | * Method: C_GenerateRandom |
313 | * Signature: (J[B)V |
314 | * Parametermapping: *PKCS11* |
315 | * @param jlong jSessionHandle CK_SESSION_HANDLE hSession |
316 | * @param jbyteArray jRandomData CK_BYTE_PTR pRandomData |
317 | * CK_ULONG ulRandomDataLen |
318 | */ |
319 | JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateRandom |
320 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jRandomData) |
321 | { |
322 | CK_SESSION_HANDLE ckSessionHandle; |
323 | jbyte *jRandomBuffer; |
324 | jlong jRandomBufferLength; |
325 | CK_RV rv; |
326 | |
327 | CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); |
328 | if (ckpFunctions == NULL) { return; } |
329 | |
330 | ckSessionHandle = jLongToCKULong(jSessionHandle); |
331 | |
332 | jRandomBufferLength = (*env)->GetArrayLength(env, jRandomData); |
333 | jRandomBuffer = (*env)->GetByteArrayElements(env, jRandomData, NULL); |
334 | if (jRandomBuffer == NULL) { return; } |
335 | |
336 | rv = (*ckpFunctions->C_GenerateRandom)(ckSessionHandle, |
337 | (CK_BYTE_PTR) jRandomBuffer, |
338 | jLongToCKULong(jRandomBufferLength)); |
339 | |
340 | /* copy back generated bytes */ |
341 | (*env)->ReleaseByteArrayElements(env, jRandomData, jRandomBuffer, 0); |
342 | |
343 | if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } |
344 | } |
345 | #endif |
346 | |