/* * Class: org_opensc_pkcs11_wrap_PKCS11Session * Method: verifyUpdateNative * Signature: (JJJ[BII)V */ JNIEXPORT void JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_wrap_PKCS11Session_verifyUpdateNative) (JNIEnv *env, jclass cls, jlong mh, jlong shandle, jlong hsession, jbyteArray data, jint off, jint len) { int rv; CK_BYTE_PTR pPart; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return; if (len < 0) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid data length %d.",(int)len); return; } if (data == NULL) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "NULL input data."); return; } if (off < 0 || off > len) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid input offset %d.",(int)off); return; } allocaCArrayFromJByteArrayOffLen(pPart,env,data,off,len); rv = mod->method->C_VerifyUpdate(hsession,pPart,len); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_VerifyUpdate failed for slot %d.", (int)slot->id); return; } }
pkcs11_slot_t *pkcs11_slot_from_jhandle(JNIEnv *env, jlong handle) { pkcs11_slot_t *slot = (pkcs11_slot_t *)(size_t)handle; if (!slot || slot->_magic != PKCS11_SLOT_MAGIC) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid PKCS11 slot handle %p.",(void*)slot); return 0; } return slot; }
/* * Class: org_opensc_pkcs11_wrap_PKCS11Session * Method: verifyFinalNative * Signature: (JJJ[B)Z */ JNIEXPORT jboolean JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_wrap_PKCS11Session_verifyFinalNative) (JNIEnv *env, jclass cls, jlong mh, jlong shandle, jlong hsession, jbyteArray data) { int rv; CK_BYTE_PTR pSignature; CK_ULONG ulSignatureLen; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return JNI_FALSE; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return JNI_FALSE; if (data == NULL) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "NULL input data."); return JNI_FALSE; } allocaCArrayFromJByteArray(pSignature,ulSignatureLen,env,data); rv = mod->method->C_VerifyFinal(hsession,pSignature,ulSignatureLen); switch (rv) { case CKR_SIGNATURE_INVALID: return JNI_FALSE; case CKR_OK: return JNI_TRUE; default: jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_VerifyFinal failed for slot %d.", (int)slot->id); return JNI_FALSE; } }
/* * Class: org_opensc_pkcs11_wrap_PKCS11Slot * Method: getTokenMaxPinLenNative * Signature: (JJ)I */ jint JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_wrap_PKCS11Slot_getTokenMaxPinLenNative) (JNIEnv *env, jobject jslot, jlong mh, jlong handle) { pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return JNI_FALSE; slot = pkcs11_slot_from_jhandle(env,handle); if (!slot) return JNI_FALSE; if ((slot->ck_slot_info.flags & CKF_TOKEN_PRESENT) == 0) jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",CKR_TOKEN_NOT_PRESENT, "No token present in slot %d.", (int)slot->id); if (slot->ck_token_info.ulMaxPinLen > 0x7fffffff || slot->ck_token_info.ulMinPinLen > slot->ck_token_info.ulMaxPinLen ) jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid value %u for ulMaxPinLen of token in slot %d.", (unsigned)slot->ck_token_info.ulMaxPinLen,(int)slot->id); return slot->ck_token_info.ulMaxPinLen; }
pkcs11_slot_t *new_pkcs11_slot(JNIEnv *env, pkcs11_module_t *mod, CK_SLOT_ID id) { int rv; pkcs11_slot_t *slot = (pkcs11_slot_t *) malloc(sizeof(pkcs11_slot_t)); if (!slot) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Out of memory allocating PKCS11 slot."); return 0; } memset(slot, 0, sizeof(pkcs11_slot_t)); slot->_magic = PKCS11_SLOT_MAGIC; slot->id = id; rv = mod->method->C_GetSlotInfo(id,&slot->ck_slot_info); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_GetSlotInfo for PKCS11 slot %d failed.",(int)id); goto failed; } #ifdef DEBUG_PKCS11_SLOT fprintf(stderr,"Loaded slot: %d.\n",(int)id); fprintf(stderr,"handle= %p.\n",slot); fprintf(stderr,"description= %.64s.\n",slot->ck_slot_info.slotDescription); fprintf(stderr,"manufacturer= %.32s.\n",slot->ck_slot_info.manufacturerID); fprintf(stderr,"flags= %x.\n",(unsigned)slot->ck_slot_info.flags); fprintf(stderr,"hardwareVersion= %d.%d.\n", (int)slot->ck_slot_info.hardwareVersion.major, (int)slot->ck_slot_info.hardwareVersion.minor ); fprintf(stderr,"firmwareVersion= %d.%d.\n", (int)slot->ck_slot_info.firmwareVersion.major, (int)slot->ck_slot_info.firmwareVersion.minor ); #endif if (slot->ck_slot_info.flags & CKF_TOKEN_PRESENT) { rv = mod->method->C_GetTokenInfo(id,&slot->ck_token_info); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_GetTokenInfo for PKCS11 slot %d failed.",(int)id); goto failed; } #ifdef DEBUG_PKCS11_SLOT fprintf(stderr,"token.label= %.32s.\n",slot->ck_token_info.label); fprintf(stderr,"token.manufacturer= %.32s.\n",slot->ck_token_info.manufacturerID); fprintf(stderr,"token.model= %.16s.\n",slot->ck_token_info.model); fprintf(stderr,"token.serialNumber= %.16s.\n",slot->ck_token_info.serialNumber); fprintf(stderr,"token.flags= %x.\n",(unsigned)slot->ck_token_info.flags); fprintf(stderr,"token.ulMaxSessionCount= %u.\n", (unsigned)slot->ck_token_info.ulMaxSessionCount); fprintf(stderr,"token.ulMaxPinLen= %u.\n", (unsigned)slot->ck_token_info.ulMaxPinLen); fprintf(stderr,"token.ulMinPinLen= %u.\n", (unsigned)slot->ck_token_info.ulMinPinLen); #endif } return slot; failed: free(slot); return 0; }
/* * Class: org_opensc_pkcs11_wrap_PKCS11Object * Method: enumObjectsNative * Signature: (JJJ[Lorg/opensc/pkcs11/wrap/PKCS11Attribute;)[J */ JNIEXPORT jlongArray JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_wrap_PKCS11Object_enumObjectsNative) (JNIEnv *env, jclass jp11obj, jlong mh, jlong shandle, jlong hsession, jobjectArray attrs) { jclass clazz; jmethodID getKindID,getDataID; CK_ULONG ulAttributeCount; CK_ATTRIBUTE_PTR pAttributes; CK_ULONG i,count; int nobjs,rv; CK_ULONG obj_ids[ENUM_HANDLES_BLOCK_SZ]; size_t ret_obj_ids_sz; jlong *ret_obj_ids; jlongArray ret; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return 0; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return 0; clazz = (*env)->FindClass(env,"org/opensc/pkcs11/wrap/PKCS11Attribute"); if (!clazz) return 0; getKindID = (*env)->GetMethodID(env,clazz,"getKind","()I"); if (!getKindID) return 0; getDataID = (*env)->GetMethodID(env,clazz,"getData","()[B"); if (!getDataID) return 0; ulAttributeCount = (*env)->GetArrayLength(env,attrs); pAttributes = alloca(ulAttributeCount * sizeof(CK_ATTRIBUTE)); for (i=0;i<ulAttributeCount;++i) { jbyteArray data; jobject jattr = (*env)->GetObjectArrayElement(env,attrs,i); if (!jattr) return 0; pAttributes[i].type = (*env)->CallIntMethod(env,jattr,getKindID); data = (jbyteArray)(*env)->CallObjectMethod(env,jattr,getDataID); allocaCArrayFromJByteArray(pAttributes[i].pValue,pAttributes[i].ulValueLen,env,data); } ret_obj_ids_sz = ENUM_HANDLES_BLOCK_SZ; nobjs = 0; ret_obj_ids=(jlong*)malloc(ret_obj_ids_sz * sizeof(jlong)); if (!ret_obj_ids) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Out of memory during object enumeration for slot number %d.", (int)slot->id); goto failed; } rv = mod->method->C_FindObjectsInit(hsession,pAttributes,ulAttributeCount); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_FindObjectsInit failed for slot number %d.", (int)slot->id); goto failed; } count = 0; rv = mod->method->C_FindObjects(hsession,obj_ids, ENUM_HANDLES_BLOCK_SZ, &count); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_FindObjects failed for slot number %d.", (int)slot->id); goto failed; } for (i=0; i<count ;++i) { jlong id = (jlong)obj_ids[i]; ret_obj_ids[nobjs] = id; ++nobjs; } while (count == ENUM_HANDLES_BLOCK_SZ) { jlong *new_obj_ids; ret_obj_ids_sz += ENUM_HANDLES_BLOCK_SZ; new_obj_ids=(jlong*)realloc(ret_obj_ids,ret_obj_ids_sz * sizeof(jlong)); if (!new_obj_ids) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Out of memory during object enumeration for slot number %d.", (int)slot->id); goto failed; } ret_obj_ids=new_obj_ids; rv = mod->method->C_FindObjects(hsession,obj_ids,ENUM_HANDLES_BLOCK_SZ, &count); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_FindObjects failed for slot number %d.", (int)slot->id); goto failed; } for (i=0; i<count ;++i) { jlong id = (jlong)obj_ids[i]; ret_obj_ids[nobjs] = id; ++nobjs; } } rv = mod->method->C_FindObjectsFinal(hsession); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_FindObjectsFinal failed for slot number %d.", (int)slot->id); goto failed; } /* OK, akc it into JAVA's realm. */ ret = (*env)->NewLongArray(env,nobjs); (*env)->SetLongArrayRegion(env,ret,0,nobjs,ret_obj_ids); free(ret_obj_ids); return ret; failed: free(ret_obj_ids); return 0; }
/* * Class: org_opensc_pkcs11_spi_PKCS11CipherSpi * Method: updateDecryptNative * Signature: (JJJJ[BII)[B */ JNIEXPORT jbyteArray JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_spi_PKCS11CipherSpi_updateDecryptNative) (JNIEnv *env, jobject jciph, jlong mh, jlong shandle, jlong hsession, jlong hkey, jbyteArray input, jint off, jint len) { int rv; CK_BYTE_PTR pInputPart; CK_BYTE_PTR pOutputPart = 0; CK_ULONG ulOutputLen = 0; jbyteArray ret; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return 0; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return 0; if (len < 0) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid data length %d.",(int)len); return 0; } if (input == NULL) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "NULL input data."); return 0; } if (off < 0 || off > len) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid input offset %d.",(int)off); return 0; } allocaCArrayFromJByteArrayOffLen(pInputPart,env,input,off,len); rv = mod->method->C_DecryptUpdate(hsession,pInputPart,len,pOutputPart,&ulOutputLen); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_DecryptUpdate failed for slot %d.", (int)slot->id); return 0; } pOutputPart=alloca(ulOutputLen); rv = mod->method->C_DecryptUpdate(hsession,pInputPart,len,pOutputPart,&ulOutputLen); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_DecryptUpdate failed for slot %d.", (int)slot->id); return 0; } ret = (*env)->NewByteArray(env,ulOutputLen); if (ret) (*env)->SetByteArrayRegion(env,ret,0,ulOutputLen,(jbyte*)pOutputPart); return ret; }
/* * Class: org_opensc_pkcs11_spi_PKCS11CipherSpi * Method: doFinalEncryptNativeOff * Signature: (JJJJ[BII[BI)I */ JNIEXPORT jint JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_spi_PKCS11CipherSpi_doFinalEncryptNativeOff) (JNIEnv *env, jobject jciph, jlong mh, jlong shandle, jlong hsession, jlong hkey, jbyteArray input, jint off, jint len, jbyteArray output, jint output_off) { int rv; CK_BYTE_PTR pOutputPart; CK_ULONG ulOutputLen,ulOutputLen0,ulOutputLen1; CK_BYTE_PTR pInputPart; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return 0; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return 0; if (len < 0) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid data length %d.",(int)len); return 0; } if (input == NULL) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "NULL input data."); return 0; } if (off < 0 || off > len) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid input offset %d.",(int)off); return 0; } ulOutputLen = (*env)->GetArrayLength(env,output); if (output_off < 0 || output_off > ulOutputLen) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid output offset %d.",(int)output_off); return 0; } ulOutputLen -= output_off; pOutputPart = alloca(ulOutputLen); ulOutputLen0 = ulOutputLen; allocaCArrayFromJByteArrayOffLen(pInputPart,env,input,off,len); rv = mod->method->C_EncryptUpdate(hsession,pInputPart,len,pOutputPart,&ulOutputLen0); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_EncryptUpdate failed for slot %d.", (int)slot->id); return 0; } ulOutputLen1 = ulOutputLen - ulOutputLen0; rv = mod->method->C_EncryptFinal(hsession,pOutputPart+ulOutputLen0,&ulOutputLen1); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_EncryptFinal failed for slot %d.", (int)slot->id); return 0; } ulOutputLen = ulOutputLen0+ulOutputLen1; (*env)->SetByteArrayRegion(env,output,output_off,ulOutputLen,(jbyte*)pOutputPart); return ulOutputLen; }
/* * Class: org_opensc_pkcs11_wrap_PKCS11Session * Method: signNative * Signature: (JJJ[BII)[B */ JNIEXPORT jbyteArray JNICALL JNIX_FUNC_NAME(Java_org_opensc_pkcs11_wrap_PKCS11Session_signNative) (JNIEnv *env, jclass cls, jlong mh, jlong shandle, jlong hsession, jbyteArray ba, jint off, jint len) { int rv; CK_BYTE_PTR pMessage = NULL; CK_BYTE_PTR pSignature = NULL; CK_ULONG ulSignatureLen = 0; jbyteArray ret; pkcs11_slot_t *slot; pkcs11_module_t *mod = pkcs11_module_from_jhandle(env,mh); if (!mod) return 0; slot = pkcs11_slot_from_jhandle(env,shandle); if (!slot) return 0; if (len < 0) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid data length %d.",(int)len); return NULL; } if (ba == NULL) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "NULL input data."); return NULL; } if (off < 0) { jnixThrowException(env,"org/opensc/pkcs11/wrap/PKCS11Exception", "Invalid input offset %d.",(int)off); return NULL; } allocaCArrayFromJByteArrayOffLen(pMessage,env,ba,off,len); rv = mod->method->C_Sign(hsession,pMessage,len,pSignature,&ulSignatureLen); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_Sign failed for slot %d.", (int)slot->id); return NULL; } pSignature = (CK_BYTE_PTR)alloca(ulSignatureLen); rv = mod->method->C_Sign(hsession,pMessage,len,pSignature,&ulSignatureLen); if (rv != CKR_OK) { jnixThrowExceptionI(env,"org/opensc/pkcs11/wrap/PKCS11Exception",rv, "C_SignFinal failed for slot %d.", (int)slot->id); return NULL; } ret = (*env)->NewByteArray(env,ulSignatureLen); if (ret) (*env)->SetByteArrayRegion(env,ret,0,ulSignatureLen,(jbyte*)pSignature); return ret; }