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  */
  68 JNIEXPORT 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  */
 108 JNIEXPORT 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  */
 147 JNIEXPORT 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  */
 175 JNIEXPORT 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  */
 210 JNIEXPORT 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  */
 301 JNIEXPORT 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  */
 336 JNIEXPORT 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  */
 376 JNIEXPORT 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  */
 416 JNIEXPORT 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