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