1 /*
   2  * Copyright (c) 2003, 2016, 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 /* declare file private functions */
  58 
  59 void prefetchFields(JNIEnv *env, jclass thisClass);
  60 jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
  61 jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
  62 jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
  63 jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
  64 
  65 /* define variables */
  66 
  67 jfieldID pNativeDataID;
  68 jfieldID mech_mechanismID;
  69 jfieldID mech_pParameterID;
  70 
  71 jclass jByteArrayClass;
  72 jclass jLongClass;
  73 
  74 JavaVM* jvm = NULL;
  75 
  76 jboolean debug = 0;
  77 
  78 JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
  79     jvm = vm;
  80     return JNI_VERSION_1_4;
  81 }
  82 
  83 /* ************************************************************************** */
  84 /* The native implementation of the methods of the PKCS11Implementation class */
  85 /* ************************************************************************** */
  86 
  87 /*
  88  * This method is used to do static initialization. This method is static and
  89  * synchronized. Summary: use this method like a static initialization block.
  90  *
  91  * Class:     sun_security_pkcs11_wrapper_PKCS11
  92  * Method:    initializeLibrary
  93  * Signature: ()V
  94  */
  95 JNIEXPORT void JNICALL
  96 Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
  97 (JNIEnv *env, jclass thisClass, jboolean enableDebug)
  98 {
  99 #ifndef NO_CALLBACKS
 100     if (notifyListLock == NULL) {
 101         notifyListLock = createLockObject(env);
 102     }
 103 #endif
 104 
 105     prefetchFields(env, thisClass);
 106     debug = enableDebug;
 107 }
 108 
 109 jclass fetchClass(JNIEnv *env, const char *name) {
 110     jclass tmpClass = (*env)->FindClass(env, name);
 111     if (tmpClass == NULL) { return NULL; }
 112     return (*env)->NewGlobalRef(env, tmpClass);
 113 }
 114 
 115 void prefetchFields(JNIEnv *env, jclass thisClass) {
 116     jclass tmpClass;
 117 
 118     /* PKCS11 */
 119     pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
 120     if (pNativeDataID == NULL) { return; }
 121 
 122     /* CK_MECHANISM */
 123     tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
 124     if (tmpClass == NULL) { return; }
 125     mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
 126     if (mech_mechanismID == NULL) { return; }
 127     mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
 128                                            "Ljava/lang/Object;");
 129     if (mech_pParameterID == NULL) { return; }
 130     jByteArrayClass = fetchClass(env, "[B");
 131     if (jByteArrayClass == NULL) { return; }
 132     jLongClass = fetchClass(env, "java/lang/Long");
 133 }
 134 
 135 /* This method is designed to do a clean-up. It releases all global resources
 136  * of this library. By now, this function is not called. Calling from
 137  * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
 138  *
 139  * Class:     sun_security_pkcs11_wrapper_PKCS11
 140  * Method:    finalizeLibrary
 141  * Signature: ()V
 142  */
 143 JNIEXPORT void JNICALL
 144 Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
 145 (JNIEnv *env, jclass thisClass)
 146 {
 147 /* XXX
 148     * remove all left lists and release the resources and the lock
 149      * objects that synchroniz access to these lists.
 150      *
 151     removeAllModuleEntries(env);
 152     if (moduleListHead == NULL) { * check, if we removed the last active module *
 153         * remove also the moduleListLock, it is no longer used *
 154         if (moduleListLock != NULL) {
 155             destroyLockObject(env, moduleListLock);
 156             moduleListLock = NULL;
 157         }
 158 #ifndef NO_CALLBACKS
 159         * remove all left notify callback entries *
 160         while (removeFirstNotifyEntry(env));
 161         * remove also the notifyListLock, it is no longer used *
 162         if (notifyListLock != NULL) {
 163             destroyLockObject(env, notifyListLock);
 164             notifyListLock = NULL;
 165         }
 166         if (jInitArgsObject != NULL) {
 167             (*env)->DeleteGlobalRef(env, jInitArgsObject);
 168         }
 169         if (ckpGlobalInitArgs != NULL_PTR) {
 170             free(ckpGlobalInitArgs);
 171         }
 172 #endif * NO_CALLBACKS *
 173     }
 174 */
 175 }
 176 
 177 #ifdef P11_ENABLE_C_INITIALIZE
 178 /*
 179  * Class:     sun_security_pkcs11_wrapper_PKCS11
 180  * Method:    C_Initialize
 181  * Signature: (Ljava/lang/Object;)V
 182  * Parametermapping:                    *PKCS11*
 183  * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
 184  */
 185 JNIEXPORT void JNICALL
 186 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
 187 (JNIEnv *env, jobject obj, jobject jInitArgs)
 188 {
 189     /*
 190      * Initalize Cryptoki
 191      */
 192     CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
 193     CK_RV rv;
 194     CK_FUNCTION_LIST_PTR ckpFunctions;
 195 
 196     TRACE0("DEBUG: initializing module... ");
 197 
 198     ckpFunctions = getFunctionList(env, obj);
 199     if (ckpFunctions == NULL) {
 200         TRACE0("failed getting module entry");
 201         return;
 202     }
 203 
 204     ckpInitArgs = (jInitArgs != NULL)
 205                 ? makeCKInitArgsAdapter(env, jInitArgs)
 206                 : NULL_PTR;
 207 
 208     rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
 209 
 210     free(ckpInitArgs);
 211 
 212     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 213 
 214     TRACE0("FINISHED\n");
 215 }
 216 #endif
 217 
 218 #ifdef P11_ENABLE_C_FINALIZE
 219 /*
 220  * Class:     sun_security_pkcs11_wrapper_PKCS11
 221  * Method:    C_Finalize
 222  * Signature: (Ljava/lang/Object;)V
 223  * Parametermapping:                    *PKCS11*
 224  * @param   jobject jReserved           CK_VOID_PTR pReserved
 225  */
 226 JNIEXPORT void JNICALL
 227 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
 228 (JNIEnv *env, jobject obj, jobject jReserved)
 229 {
 230     /*
 231      * Finalize Cryptoki
 232      */
 233     CK_VOID_PTR ckpReserved;
 234     CK_RV rv;
 235 
 236     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 237     if (ckpFunctions == NULL) { return; }
 238 
 239     ckpReserved = jObjectToCKVoidPtr(jReserved);
 240 
 241     rv = (*ckpFunctions->C_Finalize)(ckpReserved);
 242     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 243 }
 244 #endif
 245 
 246 #ifdef P11_ENABLE_C_GETINFO
 247 /*
 248  * Class:     sun_security_pkcs11_wrapper_PKCS11
 249  * Method:    C_GetInfo
 250  * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
 251  * Parametermapping:                    *PKCS11*
 252  * @return  jobject jInfoObject         CK_INFO_PTR pInfo
 253  */
 254 JNIEXPORT jobject JNICALL
 255 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
 256 (JNIEnv *env, jobject obj)
 257 {
 258     CK_INFO ckLibInfo;
 259     jobject jInfoObject=NULL;
 260     CK_RV rv;
 261     CK_FUNCTION_LIST_PTR ckpFunctions;
 262     memset(&ckLibInfo, 0, sizeof(CK_INFO));
 263 
 264     ckpFunctions = getFunctionList(env, obj);
 265     if (ckpFunctions == NULL) { return NULL; }
 266 
 267     rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
 268     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 269         jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
 270     }
 271     return jInfoObject ;
 272 }
 273 
 274 /*
 275  * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
 276  *
 277  * @param env - used to call JNI funktions to create the new Java object
 278  * @param ckpInfo - the pointer to the CK_INFO structure
 279  * @return - the new Java CK_INFO object
 280  */
 281 jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
 282 {
 283     jclass jInfoClass;
 284     jmethodID jCtrId;
 285     jobject jInfoObject;
 286     jobject jCryptokiVer;
 287     jcharArray jVendor;
 288     jlong jFlags;
 289     jcharArray jLibraryDesc;
 290     jobject jLibraryVer;
 291 
 292     /* load CK_INFO class */
 293     jInfoClass = (*env)->FindClass(env, CLASS_INFO);
 294     if (jInfoClass == NULL) { return NULL; };
 295 
 296     /* load CK_INFO constructor */
 297     jCtrId = (*env)->GetMethodID
 298       (env, jInfoClass, "<init>",
 299        "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
 300     if (jCtrId == NULL) { return NULL; }
 301 
 302     /* prep all fields */
 303     jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
 304     if (jCryptokiVer == NULL) { return NULL; }
 305     jVendor =
 306       ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
 307     if (jVendor == NULL) { return NULL; }
 308     jFlags = ckULongToJLong(ckpInfo->flags);
 309     jLibraryDesc =
 310       ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
 311     if (jLibraryDesc == NULL) { return NULL; }
 312     jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
 313     if (jLibraryVer == NULL) { return NULL; }
 314 
 315     /* create new CK_INFO object */
 316     jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
 317                                     jVendor, jFlags, jLibraryDesc, jLibraryVer);
 318     if (jInfoObject == NULL) { return NULL; }
 319 
 320     /* free local references */
 321     (*env)->DeleteLocalRef(env, jInfoClass);
 322     (*env)->DeleteLocalRef(env, jCryptokiVer);
 323     (*env)->DeleteLocalRef(env, jVendor);
 324     (*env)->DeleteLocalRef(env, jLibraryDesc);
 325     (*env)->DeleteLocalRef(env, jLibraryVer);
 326 
 327     return jInfoObject ;
 328 }
 329 #endif
 330 
 331 #ifdef P11_ENABLE_C_GETSLOTLIST
 332 /*
 333  * Class:     sun_security_pkcs11_wrapper_PKCS11
 334  * Method:    C_GetSlotList
 335  * Signature: (Z)[J
 336  * Parametermapping:                    *PKCS11*
 337  * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
 338  * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
 339  *                                      CK_ULONG_PTR pulCount
 340  */
 341 JNIEXPORT jlongArray JNICALL
 342 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
 343 (JNIEnv *env, jobject obj, jboolean jTokenPresent)
 344 {
 345     CK_ULONG ckTokenNumber;
 346     CK_SLOT_ID_PTR ckpSlotList;
 347     CK_BBOOL ckTokenPresent;
 348     jlongArray jSlotList = NULL;
 349     CK_RV rv;
 350 
 351     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 352     if (ckpFunctions == NULL) { return NULL; }
 353 
 354     ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
 355 
 356     rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
 357                                         &ckTokenNumber);
 358     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
 359 
 360     ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
 361     if (ckpSlotList == NULL) {
 362         throwOutOfMemoryError(env, 0);
 363         return NULL;
 364     }
 365 
 366     rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
 367                                         &ckTokenNumber);
 368     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 369         jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
 370     }
 371     free(ckpSlotList);
 372 
 373     return jSlotList ;
 374 }
 375 #endif
 376 
 377 #ifdef P11_ENABLE_C_GETSLOTINFO
 378 /*
 379  * Class:     sun_security_pkcs11_wrapper_PKCS11
 380  * Method:    C_GetSlotInfo
 381  * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
 382  * Parametermapping:                    *PKCS11*
 383  * @param   jlong jSlotID               CK_SLOT_ID slotID
 384  * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
 385  */
 386 JNIEXPORT jobject JNICALL
 387 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
 388 (JNIEnv *env, jobject obj, jlong jSlotID)
 389 {
 390     CK_SLOT_ID ckSlotID;
 391     CK_SLOT_INFO ckSlotInfo;
 392     jobject jSlotInfoObject=NULL;
 393     CK_RV rv;
 394 
 395     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 396     if (ckpFunctions == NULL) { return NULL; }
 397 
 398     ckSlotID = jLongToCKULong(jSlotID);
 399 
 400     rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
 401     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 402         jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
 403     }
 404     return jSlotInfoObject;
 405 }
 406 
 407 /*
 408  * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
 409  * Object.
 410  *
 411  * @param env - used to call JNI funktions to create the new Java object
 412  * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
 413  * @return - the new Java CK_SLOT_INFO object
 414  */
 415 jobject
 416 ckSlotInfoPtrToJSlotInfo
 417 (JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
 418 {
 419     jclass jSlotInfoClass;
 420     jmethodID jCtrId;
 421     jobject jSlotInfoObject;
 422     jcharArray jSlotDesc;
 423     jcharArray jVendor;
 424     jlong jFlags;
 425     jobject jHardwareVer;
 426     jobject jFirmwareVer;
 427 
 428     /* load CK_SLOT_INFO class */
 429     jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
 430     if (jSlotInfoClass == NULL) { return NULL; };
 431 
 432     /* load CK_SLOT_INFO constructor */
 433     jCtrId = (*env)->GetMethodID
 434       (env, jSlotInfoClass, "<init>",
 435        "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
 436     if (jCtrId == NULL) { return NULL; }
 437 
 438     /* prep all fields */
 439     jSlotDesc =
 440       ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
 441     if (jSlotDesc == NULL) { return NULL; }
 442     jVendor =
 443       ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
 444     if (jVendor == NULL) { return NULL; }
 445     jFlags = ckULongToJLong(ckpSlotInfo->flags);
 446     jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
 447     if (jHardwareVer == NULL) { return NULL; }
 448     jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
 449     if (jFirmwareVer == NULL) { return NULL; }
 450 
 451     /* create new CK_SLOT_INFO object */
 452     jSlotInfoObject = (*env)->NewObject
 453       (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
 454        jHardwareVer, jFirmwareVer);
 455     if (jSlotInfoObject == NULL) { return NULL; }
 456 
 457     /* free local references */
 458     (*env)->DeleteLocalRef(env, jSlotInfoClass);
 459     (*env)->DeleteLocalRef(env, jSlotDesc);
 460     (*env)->DeleteLocalRef(env, jVendor);
 461     (*env)->DeleteLocalRef(env, jHardwareVer);
 462     (*env)->DeleteLocalRef(env, jFirmwareVer);
 463 
 464     return jSlotInfoObject ;
 465 }
 466 
 467 #endif
 468 
 469 #ifdef P11_ENABLE_C_GETTOKENINFO
 470 /*
 471  * Class:     sun_security_pkcs11_wrapper_PKCS11
 472  * Method:    C_GetTokenInfo
 473  * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
 474  * Parametermapping:                    *PKCS11*
 475  * @param   jlong jSlotID               CK_SLOT_ID slotID
 476  * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
 477  */
 478 JNIEXPORT jobject JNICALL
 479 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
 480 (JNIEnv *env, jobject obj, jlong jSlotID)
 481 {
 482     CK_SLOT_ID ckSlotID;
 483     CK_TOKEN_INFO ckTokenInfo;
 484     jobject jInfoTokenObject = NULL;
 485     CK_RV rv;
 486 
 487     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 488     if (ckpFunctions == NULL) { return NULL; }
 489 
 490     ckSlotID = jLongToCKULong(jSlotID);
 491 
 492     rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
 493     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 494         jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
 495     }
 496     return jInfoTokenObject ;
 497 }
 498 
 499 /*
 500  * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
 501  * Object.
 502  *
 503  * @param env - used to call JNI funktions to create the new Java object
 504  * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
 505  * @return - the new Java CK_TOKEN_INFO object
 506  */
 507 jobject
 508 ckTokenInfoPtrToJTokenInfo
 509 (JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
 510 {
 511     jclass jTokenInfoClass;
 512     jmethodID jCtrId;
 513     jobject jTokenInfoObject;
 514     jcharArray jLabel;
 515     jcharArray jVendor;
 516     jcharArray jModel;
 517     jcharArray jSerialNo;
 518     jlong jFlags;
 519     jlong jMaxSnCnt;
 520     jlong jSnCnt;
 521     jlong jMaxRwSnCnt;
 522     jlong jRwSnCnt;
 523     jlong jMaxPinLen;
 524     jlong jMinPinLen;
 525     jlong jTotalPubMem;
 526     jlong jFreePubMem;
 527     jlong jTotalPrivMem;
 528     jlong jFreePrivMem;
 529     jobject jHardwareVer;
 530     jobject jFirmwareVer;
 531     jcharArray jUtcTime;
 532 
 533     /* load CK_TOKEN_INFO class */
 534     jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
 535     if (jTokenInfoClass == NULL)  { return NULL; };
 536 
 537     /* load CK_TOKEN_INFO constructor */
 538     jCtrId = (*env)->GetMethodID
 539       (env, jTokenInfoClass, "<init>",
 540        "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
 541     if (jCtrId == NULL)  { return NULL; };
 542 
 543     /* prep all fields */
 544     jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
 545     if (jLabel == NULL)  { return NULL; };
 546     jVendor =
 547       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
 548     if (jVendor == NULL)  { return NULL; };
 549     jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
 550     if (jModel == NULL)  { return NULL; };
 551     jSerialNo =
 552       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
 553     if (jSerialNo == NULL)  { return NULL; };
 554     jFlags = ckULongToJLong(ckpTokenInfo->flags);
 555     jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
 556     jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
 557     jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
 558     jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
 559     jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
 560     jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
 561     jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
 562     jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
 563     jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
 564     jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
 565     jHardwareVer =
 566       ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
 567     if (jHardwareVer == NULL) { return NULL; }
 568     jFirmwareVer =
 569       ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
 570     if (jFirmwareVer == NULL) { return NULL; }
 571     jUtcTime =
 572       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
 573     if (jUtcTime == NULL) { return NULL; }
 574 
 575     /* create new CK_TOKEN_INFO object */
 576     jTokenInfoObject =
 577       (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
 578                         jSerialNo, jFlags,
 579                         jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
 580                         jMaxPinLen, jMinPinLen,
 581                         jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
 582                         jHardwareVer, jFirmwareVer, jUtcTime);
 583     if (jTokenInfoObject == NULL) { return NULL; }
 584 
 585     /* free local references */
 586     (*env)->DeleteLocalRef(env, jTokenInfoClass);
 587     (*env)->DeleteLocalRef(env, jLabel);
 588     (*env)->DeleteLocalRef(env, jVendor);
 589     (*env)->DeleteLocalRef(env, jModel);
 590     (*env)->DeleteLocalRef(env, jSerialNo);
 591     (*env)->DeleteLocalRef(env, jHardwareVer);
 592     (*env)->DeleteLocalRef(env, jFirmwareVer);
 593 
 594     return jTokenInfoObject ;
 595 }
 596 #endif
 597 
 598 #ifdef P11_ENABLE_C_WAITFORSLOTEVENT
 599 /*
 600  * Class:     sun_security_pkcs11_wrapper_PKCS11
 601  * Method:    C_WaitForSlotEvent
 602  * Signature: (JLjava/lang/Object;)J
 603  * Parametermapping:                    *PKCS11*
 604  * @param   jlong jFlags                CK_FLAGS flags
 605  * @param   jobject jReserved           CK_VOID_PTR pReserved
 606  * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
 607  */
 608 JNIEXPORT jlong JNICALL
 609 Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
 610 (JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
 611 {
 612     CK_FLAGS ckFlags;
 613     CK_SLOT_ID ckSlotID;
 614     jlong jSlotID = 0L;
 615     CK_RV rv;
 616 
 617     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 618     if (ckpFunctions == NULL) { return 0L; }
 619 
 620     ckFlags = jLongToCKULong(jFlags);
 621 
 622     rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
 623     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 624         jSlotID = ckULongToJLong(ckSlotID);
 625     }
 626 
 627     return jSlotID ;
 628 }
 629 #endif
 630 
 631 #ifdef P11_ENABLE_C_GETMECHANISMLIST
 632 /*
 633  * Class:     sun_security_pkcs11_wrapper_PKCS11
 634  * Method:    C_GetMechanismList
 635  * Signature: (J)[J
 636  * Parametermapping:                    *PKCS11*
 637  * @param   jlong jSlotID               CK_SLOT_ID slotID
 638  * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
 639  *                                      CK_ULONG_PTR pulCount
 640  */
 641 JNIEXPORT jlongArray JNICALL
 642 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
 643 (JNIEnv *env, jobject obj, jlong jSlotID)
 644 {
 645     CK_SLOT_ID ckSlotID;
 646     CK_ULONG ckMechanismNumber;
 647     CK_MECHANISM_TYPE_PTR ckpMechanismList;
 648     jlongArray jMechanismList = NULL;
 649     CK_RV rv;
 650 
 651     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 652     if (ckpFunctions == NULL) { return NULL; }
 653 
 654     ckSlotID = jLongToCKULong(jSlotID);
 655 
 656     rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
 657                                              &ckMechanismNumber);
 658     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
 659 
 660     ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
 661       malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
 662     if (ckpMechanismList == NULL) {
 663         throwOutOfMemoryError(env, 0);
 664         return NULL;
 665     }
 666 
 667     rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
 668                                              &ckMechanismNumber);
 669     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 670         jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
 671                                                   ckMechanismNumber);
 672     }
 673     free(ckpMechanismList);
 674 
 675     return jMechanismList ;
 676 }
 677 #endif
 678 
 679 #ifdef P11_ENABLE_C_GETMECHANISMINFO
 680 /*
 681  * Class:     sun_security_pkcs11_wrapper_PKCS11
 682  * Method:    C_GetMechanismInfo
 683  * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
 684  * Parametermapping:                    *PKCS11*
 685  * @param   jlong jSlotID               CK_SLOT_ID slotID
 686  * @param   jlong jType                 CK_MECHANISM_TYPE type
 687  * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
 688  */
 689 JNIEXPORT jobject JNICALL
 690 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
 691 (JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
 692 {
 693     CK_SLOT_ID ckSlotID;
 694     CK_MECHANISM_TYPE ckMechanismType;
 695     CK_MECHANISM_INFO ckMechanismInfo;
 696     jobject jMechanismInfo = NULL;
 697     CK_RV rv;
 698 
 699     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 700     if (ckpFunctions == NULL) { return NULL; }
 701 
 702     ckSlotID = jLongToCKULong(jSlotID);
 703     ckMechanismType = jLongToCKULong(jType);
 704 
 705     rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
 706                                              &ckMechanismInfo);
 707     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 708         jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
 709     }
 710     return jMechanismInfo ;
 711 }
 712 
 713 /*
 714  * converts a pointer to a CK_MECHANISM_INFO structure into a Java
 715  * CK_MECHANISM_INFO Object.
 716  *
 717  * @param env - used to call JNI funktions to create the new Java object
 718  * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
 719  * @return - the new Java CK_MECHANISM_INFO object
 720  */
 721 jobject
 722 ckMechanismInfoPtrToJMechanismInfo
 723 (JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
 724 {
 725 
 726     jclass jMechanismInfoClass;
 727     jmethodID jCtrId;
 728     jobject jMechanismInfoObject;
 729     jlong jMinKeySize;
 730     jlong jMaxKeySize;
 731     jlong jFlags;
 732 
 733     /* load CK_MECHANISM_INFO class */
 734     jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
 735     if (jMechanismInfoClass == NULL) { return NULL; };
 736 
 737     /* load CK_MECHANISM_INFO constructor */
 738     jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
 739     if (jCtrId == NULL) { return NULL; };
 740 
 741     /* prep all fields */
 742     jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
 743     jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
 744     jFlags = ckULongToJLong(ckpMechanismInfo->flags);
 745 
 746     /* create new CK_MECHANISM_INFO object */
 747     jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
 748                                              jMinKeySize, jMaxKeySize, jFlags);
 749     if (jMechanismInfoObject == NULL) { return NULL; };
 750 
 751     /* free local references */
 752     (*env)->DeleteLocalRef(env, jMechanismInfoClass);
 753 
 754     return jMechanismInfoObject ;
 755 }
 756 #endif
 757 
 758 #ifdef P11_ENABLE_C_INITTOKEN
 759 /*
 760  * Class:     sun_security_pkcs11_wrapper_PKCS11
 761  * Method:    C_InitToken
 762  * Signature: (J[C[C)V
 763  * Parametermapping:                    *PKCS11*
 764  * @param   jlong jSlotID               CK_SLOT_ID slotID
 765  * @param   jcharArray jPin             CK_CHAR_PTR pPin
 766  *                                      CK_ULONG ulPinLen
 767  * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
 768  */
 769 JNIEXPORT void JNICALL
 770 Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
 771 (JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
 772 {
 773     CK_SLOT_ID ckSlotID;
 774     CK_CHAR_PTR ckpPin = NULL_PTR;
 775     CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
 776     CK_ULONG ckPinLength;
 777     CK_ULONG ckLabelLength;
 778     CK_RV rv;
 779 
 780     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 781     if (ckpFunctions == NULL) { return; }
 782 
 783     ckSlotID = jLongToCKULong(jSlotID);
 784     jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
 785     if ((*env)->ExceptionCheck(env)) { return; }
 786     /* ckLabelLength <= 32 !!! */
 787     jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
 788     if ((*env)->ExceptionCheck(env)) {
 789         free(ckpPin);
 790         return;
 791     }
 792 
 793     rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
 794     TRACE1("InitToken return code: %d", rv);
 795 
 796     free(ckpPin);
 797     free(ckpLabel);
 798 
 799     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 800 }
 801 #endif
 802 
 803 #ifdef P11_ENABLE_C_INITPIN
 804 /*
 805  * Class:     sun_security_pkcs11_wrapper_PKCS11
 806  * Method:    C_InitPIN
 807  * Signature: (J[C)V
 808  * Parametermapping:                    *PKCS11*
 809  * @param   jlong jSessionHandle        CK_SESSION_HANDLE
 810  * @param   jcharArray jPin             CK_CHAR_PTR pPin
 811  *                                      CK_ULONG ulPinLen
 812  */
 813 JNIEXPORT void JNICALL
 814 Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
 815 (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
 816 {
 817     CK_SESSION_HANDLE ckSessionHandle;
 818     CK_CHAR_PTR ckpPin = NULL_PTR;
 819     CK_ULONG ckPinLength;
 820     CK_RV rv;
 821 
 822     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 823     if (ckpFunctions == NULL) { return; }
 824 
 825     ckSessionHandle = jLongToCKULong(jSessionHandle);
 826     jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
 827     if ((*env)->ExceptionCheck(env)) { return; }
 828 
 829     rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
 830 
 831     free(ckpPin);
 832 
 833     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 834 }
 835 #endif
 836 
 837 #ifdef P11_ENABLE_C_SETPIN
 838 /*
 839  * Class:     sun_security_pkcs11_wrapper_PKCS11
 840  * Method:    C_SetPIN
 841  * Signature: (J[C[C)V
 842  * Parametermapping:                    *PKCS11*
 843  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 844  * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
 845  *                                      CK_ULONG ulOldLen
 846  * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
 847  *                                      CK_ULONG ulNewLen
 848  */
 849 JNIEXPORT void JNICALL
 850 Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
 851 (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
 852 jcharArray jNewPin)
 853 {
 854     CK_SESSION_HANDLE ckSessionHandle;
 855     CK_CHAR_PTR ckpOldPin = NULL_PTR;
 856     CK_CHAR_PTR ckpNewPin = NULL_PTR;
 857     CK_ULONG ckOldPinLength;
 858     CK_ULONG ckNewPinLength;
 859     CK_RV rv;
 860 
 861     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 862     if (ckpFunctions == NULL) { return; }
 863 
 864     ckSessionHandle = jLongToCKULong(jSessionHandle);
 865     jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
 866     if ((*env)->ExceptionCheck(env)) { return; }
 867     jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
 868     if ((*env)->ExceptionCheck(env)) {
 869         free(ckpOldPin);
 870         return;
 871     }
 872 
 873     rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
 874                                    ckpNewPin, ckNewPinLength);
 875 
 876     free(ckpOldPin);
 877     free(ckpNewPin);
 878 
 879     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 880 }
 881 #endif