HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiVerify::VerifyInternal___BOOLEAN__SZARRAY_U1__I4__I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack ) { TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis = stack.This(); CLR_RT_HeapBlock_Array* pData = stack.Arg1().DereferenceArray(); CLR_INT32 offset = stack.Arg2().NumericByRef().s4; CLR_INT32 len = stack.Arg3().NumericByRef().s4; CLR_RT_HeapBlock_Array* pSig = stack.Arg4().DereferenceArray(); CLR_INT32 sigOff = stack.Arg5().NumericByRef().s4; CLR_INT32 sigLen = stack.Arg6().NumericByRef().s4; CLR_RT_HeapBlock* pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session].Dereference(); CK_SESSION_HANDLE hSession; bool retVal = false; CK_RV result; FAULT_ON_NULL_ARG(pData); FAULT_ON_NULL_ARG(pSig); if((offset + len ) > (CLR_INT32)pData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); if((sigOff + sigLen) > (CLR_INT32)pSig->m_numOfElements ) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); hSession = (CK_SESSION_HANDLE)pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().s4; if(hSession == CK_SESSION_HANDLE_INVALID) TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); result = C_Verify(hSession, pData->GetElement(offset), len, pSig->GetElement(sigOff), sigLen); retVal = CKR_OK == result; stack.SetResult_Boolean(retVal); TINYCLR_NOCLEANUP(); }
void CPKCSDemoDlg::OnBtnVerify() { StartOP(); CK_RV rv; rv = C_VerifyInit(m_hSession, &ckMechanism, m_hPubKey); if(CKR_OK != rv) { ShowErr(NEWLINE"Failed to call VerifyInit!Error code 0x%08X."NEWLINE, rv); return; } rv = C_Verify(m_hSession, pbMsg, ulMsgLen, m_pSignature, m_ulSignatureLen); if(CKR_OK != rv) ShowErr(NEWLINE"Failed to call verify!Error code 0x%08X."NEWLINE, rv); else ShowMsg(NEWLINE"Verify Successfully!"NEWLINE); }
/* * Utility routine for verifying generic data using * the cryptographic framework (PKCS#11). * There are situations where we want to force this * operation to happen in a specific keystore. * For example: * libelfsign.so.1 verifies signatures on crypto libraries. * We must use pkcs11 functions to verify the pkcs11 * plugins in order to keep the validation within the * Cryptographic Framework's FIPS-140 boundary. To avoid * a circular dependency, pksc11_softtoken.so.1 is * interposed by libkcfd.so.1 via kcfd, which prevents * libpkcs11.so.1's interfaces from being used when libkmf.so.1 * is called from kcfd. * * This also saves code and time because verify operations * only use public keys and do not need acccess to any * keystore specific functions. */ KMF_RETURN PKCS_VerifyData(KMF_HANDLE_T handle, KMF_ALGORITHM_INDEX AlgorithmId, KMF_X509_SPKI *keyp, KMF_DATA *data, KMF_DATA *signature) { KMF_RETURN rv = KMF_OK; CK_RV ckRv; KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; CK_MECHANISM ckMechanism; CK_MECHANISM_TYPE mechtype, hashmech; CK_OBJECT_HANDLE ckKeyHandle = 0; CK_KEY_TYPE pk11keytype; CK_SESSION_HANDLE ckSession = 0; CK_ATTRIBUTE subprime = { CKA_SUBPRIME, NULL, 0 }; CK_BYTE *dataptr; CK_ULONG datalen; KMF_DATA hashData = { 0, NULL }; uchar_t digest[1024]; if (AlgorithmId == KMF_ALGID_NONE) return (KMF_ERR_BAD_ALGORITHM); if (get_pk11_data(AlgorithmId, &pk11keytype, &mechtype, &hashmech, 1)) return (KMF_ERR_BAD_ALGORITHM); /* * Verify in metaslot/softtoken since only the public key is needed * and not all hardware tokens support the combined [hash]-RSA/DSA/EC * mechanisms. */ rv = kmf_create_pk11_session(&ckSession, mechtype, 0); if (rv != KMF_OK) return (rv); /* Fetch the verifying key */ rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp, pk11keytype, &ckKeyHandle); if (rv != KMF_OK) { (void) C_CloseSession(ckSession); return (rv); } dataptr = data->Data; datalen = data->Length; /* * For some mechanisms, we must compute the hash separately * and then do the verify. */ if (hashmech != 0 && (mechtype == CKM_ECDSA || mechtype == CKM_DSA || mechtype == CKM_RSA_PKCS)) { hashData.Data = digest; hashData.Length = sizeof (digest); rv = PKCS_DigestData(handle, ckSession, hashmech, data, &hashData, (mechtype == CKM_RSA_PKCS)); if (rv) goto cleanup; dataptr = hashData.Data; datalen = hashData.Length; } if (mechtype == CKM_DSA && hashmech == CKM_SHA256) { /* * FIPS 186-3 says that when using DSA * the hash must be truncated to the size of the * subprime. */ ckRv = C_GetAttributeValue(ckSession, ckKeyHandle, &subprime, 1); if (ckRv != CKR_OK) { kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; kmfh->lasterr.errcode = ckRv; rv = KMF_ERR_INTERNAL; goto cleanup; } datalen = subprime.ulValueLen; } ckMechanism.mechanism = mechtype; ckMechanism.pParameter = NULL; ckMechanism.ulParameterLen = 0; ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle); if (ckRv != CKR_OK) { kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; kmfh->lasterr.errcode = ckRv; rv = KMF_ERR_INTERNAL; goto cleanup; } ckRv = C_Verify(ckSession, dataptr, datalen, (CK_BYTE *)signature->Data, (CK_ULONG)signature->Length); if (ckRv != CKR_OK) { kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; kmfh->lasterr.errcode = ckRv; rv = KMF_ERR_INTERNAL; } cleanup: if (ckKeyHandle != 0) (void) C_DestroyObject(ckSession, ckKeyHandle); (void) C_CloseSession(ckSession); return (rv); }