| 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 |  | 
|---|