Example #1
0
/*
 * Class:     sun_security_pkcs11_wrapper_PKCS11
 * Method:    C_CreateObject
 * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
 * Parametermapping:                    *PKCS11*
 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
 *                                      CK_ULONG ulCount
 * @return  jlong jObjectHandle         CK_OBJECT_HANDLE_PTR phObject
 */
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject
    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
{
    CK_SESSION_HANDLE ckSessionHandle;
    CK_OBJECT_HANDLE ckObjectHandle;
    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
    CK_ULONG ckAttributesLength;
    jlong jObjectHandle = 0L;
    CK_RV rv;

    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
    if (ckpFunctions == NULL) { return 0L; }

    ckSessionHandle = jLongToCKULong(jSessionHandle);
    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
    if ((*env)->ExceptionCheck(env)) { return 0L; }

    rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);

    jObjectHandle = ckULongToJLong(ckObjectHandle);
    freeCKAttributeArray(ckpAttributes, ckAttributesLength);

    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }

    return jObjectHandle ;
}
Example #2
0
/*
 * Class:     sun_security_pkcs11_wrapper_PKCS11
 * Method:    C_GenerateKey
 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
 * Parametermapping:                    *PKCS11*
 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
 * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
 *                                      CK_ULONG ulCount
 * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
 */
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
{
    CK_SESSION_HANDLE ckSessionHandle;
    CK_MECHANISM ckMechanism;
    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
    CK_ULONG ckAttributesLength;
    CK_OBJECT_HANDLE ckKeyHandle = 0;
    jlong jKeyHandle = 0L;
    CK_RV rv;

    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
    if (ckpFunctions == NULL) { return 0L; }

    ckSessionHandle = jLongToCKULong(jSessionHandle);
    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
    if ((*env)->ExceptionCheck(env)) { return 0L ; }

    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
    if ((*env)->ExceptionCheck(env)) {
        if (ckMechanism.pParameter != NULL_PTR) {
            free(ckMechanism.pParameter);
        }
        return 0L;
    }

    rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);

    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
        jKeyHandle = ckULongToJLong(ckKeyHandle);

        /* cheack, if we must give a initialization vector back to Java */
        switch (ckMechanism.mechanism) {
        case CKM_PBE_MD2_DES_CBC:
        case CKM_PBE_MD5_DES_CBC:
        case CKM_PBE_MD5_CAST_CBC:
        case CKM_PBE_MD5_CAST3_CBC:
        case CKM_PBE_MD5_CAST128_CBC:
        /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
        case CKM_PBE_SHA1_CAST128_CBC:
        /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
            /* we must copy back the initialization vector to the jMechanism object */
            copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
            break;
        }
    }

    if (ckMechanism.pParameter != NULL_PTR) {
        free(ckMechanism.pParameter);
    }
    freeCKAttributeArray(ckpAttributes, ckAttributesLength);

    return jKeyHandle ;
}
Example #3
0
/*
 * converts a CK_ULONG pointer to a Java long Object.
 *
 * @param env - used to call JNI funktions to create the new Java object
 * @param ckpValue - the pointer to the CK_ULONG value
 * @return - the new Java long object with the long value
 */
jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
{
    jclass jValueObjectClass;
    jmethodID jConstructor;
    jobject jValueObject;
    jlong jValue;

    jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
    if (jValueObjectClass == NULL) { return NULL; }
    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
    if (jConstructor == NULL) { return NULL; }
    jValue = ckULongToJLong(*ckpValue);
    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);

    return jValueObject ;
}
Example #4
0
/*
 * Class:     sun_security_pkcs11_wrapper_PKCS11
 * Method:    C_GetObjectSize
 * Signature: (JJ)J
 * Parametermapping:                    *PKCS11*
 * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
 * @return  jlong jObjectSize           CK_ULONG_PTR pulSize
 */
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize
    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
{
    CK_SESSION_HANDLE ckSessionHandle;
    CK_OBJECT_HANDLE ckObjectHandle;
    CK_ULONG ckObjectSize;
    jlong jObjectSize = 0L;
    CK_RV rv;

    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
    if (ckpFunctions == NULL) { return 0L; }

    ckSessionHandle = jLongToCKULong(jSessionHandle);
    ckObjectHandle = jLongToCKULong(jObjectHandle);

    rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }

    jObjectSize = ckULongToJLong(ckObjectSize);

    return jObjectSize ;
}
Example #5
0
/*
 * function to convert a PKCS#11 return value into a PKCS#11Exception
 *
 * This function generates a PKCS#11Exception with the returnValue as the errorcode
 * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is
 * CKR_OK. Otherwise, it returns the returnValue as a jLong.
 *
 * @param env - used to call JNI funktions and to get the Exception class
 * @param returnValue - of the PKCS#11 function
 */
jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue)
{
    jclass jPKCS11ExceptionClass;
    jmethodID jConstructor;
    jthrowable jPKCS11Exception;
    jlong jErrorCode = 0L;

    if (returnValue != CKR_OK) {
        jErrorCode = ckULongToJLong(returnValue);
        jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
        if (jPKCS11ExceptionClass != NULL) {
            jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V");
            if (jConstructor != NULL) {
                jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode);
                if (jPKCS11Exception != NULL) {
                    (*env)->Throw(env, jPKCS11Exception);
                }
            }
        }
        (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
    }
    return jErrorCode ;
}
/*
 * Class:     sun_security_pkcs11_wrapper_PKCS11
 * Method:    C_OpenSession
 * Signature: (JJLjava/lang/Object;Lsun/security/pkcs11/wrapper/CK_NOTIFY;)J
 * Parametermapping:                    *PKCS11*
 * @param   jlong jSlotID               CK_SLOT_ID slotID
 * @param   jlong jFlags                CK_FLAGS flags
 * @param   jobject jApplication        CK_VOID_PTR pApplication
 * @param   jobject jNotify             CK_NOTIFY Notify
 * @return  jlong jSessionHandle        CK_SESSION_HANDLE_PTR phSession
 */
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession
    (JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify)
{
    CK_SESSION_HANDLE ckSessionHandle;
    CK_SLOT_ID ckSlotID;
    CK_FLAGS ckFlags;
    CK_VOID_PTR ckpApplication;
    CK_NOTIFY ckNotify;
    jlong jSessionHandle;
    CK_RV rv;
#ifndef NO_CALLBACKS
    NotifyEncapsulation *notifyEncapsulation = NULL;
#endif /* NO_CALLBACKS */

    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
    if (ckpFunctions == NULL) { return 0L; }

    ckSlotID = jLongToCKULong(jSlotID);
    ckFlags = jLongToCKULong(jFlags);

#ifndef NO_CALLBACKS
    if (jNotify != NULL) {
        notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation));
        if (notifyEncapsulation == NULL) {
            JNU_ThrowOutOfMemoryError(env, 0);
            return 0L;
        }
        notifyEncapsulation->jApplicationData = (jApplication != NULL)
                ? (*env)->NewGlobalRef(env, jApplication)
                : NULL;
        notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify);
        ckpApplication = notifyEncapsulation;
        ckNotify = (CK_NOTIFY) &notifyCallback;
    } else {
        ckpApplication = NULL_PTR;
        ckNotify = NULL_PTR;
    }
#else
        ckpApplication = NULL_PTR;
        ckNotify = NULL_PTR;
#endif /* NO_CALLBACKS */

    TRACE0("DEBUG: C_OpenSession");
    TRACE1(", slotID=%u", ckSlotID);
    TRACE1(", flags=%x", ckFlags);
    TRACE0(" ... ");

    rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle);
    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
#ifndef NO_CALLBACKS
        if (notifyEncapsulation != NULL) {
            if (notifyEncapsulation->jApplicationData != NULL) {
                (*env)->DeleteGlobalRef(env, jApplication);
            }
            (*env)->DeleteGlobalRef(env, jNotify);
            free(notifyEncapsulation);
        }
#endif /* NO_CALLBACKS */
        return 0L;
    }

    TRACE0("got session");
    TRACE1(", SessionHandle=%u", ckSessionHandle);
    TRACE0(" ... ");

    jSessionHandle = ckULongToJLong(ckSessionHandle);

#ifndef NO_CALLBACKS
    if (notifyEncapsulation != NULL) {
        /* store the notifyEncapsulation to enable later cleanup */
        putNotifyEntry(env, ckSessionHandle, notifyEncapsulation);
    }
#endif /* NO_CALLBACKS */

    TRACE0("FINISHED\n");

    return jSessionHandle ;
}
/*
 * The function handling notify callbacks. It casts the pApplication paramter
 * back to a NotifyEncapsulation structure and retrieves the Notify object and
 * the application data from it.
 *
 * @param hSession The session, this callback is comming from.
 * @param event The type of event that occurred.
 * @param pApplication The application data as passed in upon OpenSession. In
                       this wrapper we always pass in a NotifyEncapsulation
                       object, which holds necessary information for delegating
                       the callback to the Java VM.
 * @return
 */
CK_RV notifyCallback(
    CK_SESSION_HANDLE hSession,     /* the session's handle */
    CK_NOTIFICATION   event,
    CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
)
{
    NotifyEncapsulation *notifyEncapsulation;
    JavaVM *jvm;
    JNIEnv *env;
    jsize actualNumberVMs;
    jint returnValue;
    jlong jSessionHandle;
    jlong jEvent;
    jclass ckNotifyClass;
    jmethodID jmethod;
    jthrowable pkcs11Exception;
    jclass pkcs11ExceptionClass;
    jlong errorCode;
    CK_RV rv = CKR_OK;
    int wasAttached = 1;

    if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */

    notifyEncapsulation = (NotifyEncapsulation *) pApplication;

    /* Get the currently running Java VM */
    returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
    if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ; } /* there is no VM running */

    /* Determine, if current thread is already attached */
    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
    if (returnValue == JNI_EDETACHED) {
        /* thread detached, so attach it */
        wasAttached = 0;
        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
    } else if (returnValue == JNI_EVERSION) {
        /* this version of JNI is not supported, so just try to attach */
        /* we assume it was attached to ensure that this thread is not detached
         * afterwards even though it should not
         */
        wasAttached = 1;
        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
    } else {
        /* attached */
        wasAttached = 1;
    }

    jSessionHandle = ckULongToJLong(hSession);
    jEvent = ckULongToJLong(event);

    ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY);
    if (ckNotifyClass == NULL) { return rv; }
    jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V");
    if (jmethod == NULL) { return rv; }

    (*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod,
                         jSessionHandle, jEvent, notifyEncapsulation->jApplicationData);

    /* check, if callback threw an exception */
    pkcs11Exception = (*env)->ExceptionOccurred(env);

    if (pkcs11Exception != NULL) {
        /* TBD: clear the pending exception with ExceptionClear? */
        /* The was an exception thrown, now we get the error-code from it */
        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
        if (pkcs11ExceptionClass == NULL) { return rv; }

        jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
        if (jmethod == NULL) { return rv; }

        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod);
        rv = jLongToCKULong(errorCode);
    }

    /* if we attached this thread to the VM just for callback, we detach it now */
    if (wasAttached) {
        returnValue = (*jvm)->DetachCurrentThread(jvm);
    }

    return rv ;
}
Example #8
0
/*
 * Copy back the derived keys and initialization vectors from the native
 * structure to the Java object. This is only used for the
 * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
 *
 */
void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
{
  jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass;
  CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
  CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
  jfieldID fieldID;
  CK_MECHANISM_TYPE ckMechanismType;
  jlong jMechanismType;
  CK_BYTE_PTR iv;
  jobject jSSL3KeyMatParam;
  jobject jSSL3KeyMatOut;
  jobject jIV;
  jint jLength;
  jbyte* jBytes;
  int i;

  /* get mechanism */
  jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
  if (jMechanismClass == NULL) { return; }
  fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
  if (fieldID == NULL) { return; }
  jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
  ckMechanismType = jLongToCKULong(jMechanismType);
  if (ckMechanismType != ckMechanism->mechanism) {
    /* we do not have maching types, this should not occur */
    return;
  }

  /* get the native CK_SSL3_KEY_MAT_PARAMS */
  ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
  if (ckSSL3KeyMatParam != NULL_PTR) {
    // free malloc'd data
    if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) {
        free(ckSSL3KeyMatParam->RandomInfo.pClientRandom);
    }
    if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) {
        free(ckSSL3KeyMatParam->RandomInfo.pServerRandom);
    }

    /* get the native CK_SSL3_KEY_MAT_OUT */
    ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
    if (ckSSL3KeyMatOut != NULL_PTR) {
      /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
      fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
      if (fieldID == NULL) { return; }
      jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);

      /* get the Java CK_SSL3_KEY_MAT_OUT */
      jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
      if (jSSL3KeyMatParamsClass == NULL) { return; }
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
      if (fieldID == NULL) { return; }
      jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);

      /* now copy back all the key handles and the initialization vectors */
      /* copy back client MAC secret handle */
      jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
      if (jSSL3KeyMatOutClass == NULL) { return; }
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
      if (fieldID == NULL) { return; }
      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));

      /* copy back server MAC secret handle */
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
      if (fieldID == NULL) { return; }
      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));

      /* copy back client secret key handle */
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
      if (fieldID == NULL) { return; }
      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));

      /* copy back server secret key handle */
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
      if (fieldID == NULL) { return; }
      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));

      /* copy back the client IV */
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
      if (fieldID == NULL) { return; }
      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
      iv = ckSSL3KeyMatOut->pIVClient;

      if (jIV != NULL) {
        jLength = (*env)->GetArrayLength(env, jIV);
        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
        if (jBytes == NULL) { return; }
        /* copy the bytes to the Java buffer */
        for (i=0; i < jLength; i++) {
          jBytes[i] = ckByteToJByte(iv[i]);
        }
        /* copy back the Java buffer to the object */
        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
      }
      // free malloc'd data
      free(ckSSL3KeyMatOut->pIVClient);

      /* copy back the server IV */
      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
      if (fieldID == NULL) { return; }
      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
      iv = ckSSL3KeyMatOut->pIVServer;

      if (jIV != NULL) {
        jLength = (*env)->GetArrayLength(env, jIV);
        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
        if (jBytes == NULL) { return; }
        /* copy the bytes to the Java buffer */
        for (i=0; i < jLength; i++) {
          jBytes[i] = ckByteToJByte(iv[i]);
        }
        /* copy back the Java buffer to the object */
        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
      }
      // free malloc'd data
      free(ckSSL3KeyMatOut->pIVServer);
      free(ckSSL3KeyMatOut);
    }
  }
}