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