static BOOL WINTRUST_VerifySigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx) { BOOL ret; CERT_INFO *certInfo = WINTRUST_GetSignerCertInfo(data, signerIdx); if (certInfo) { PCCERT_CONTEXT subject = CertGetSubjectCertificateFromStore( data->pahStores[0], data->dwEncoding, certInfo); if (subject) { CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA para = { sizeof(para), 0, signerIdx, CMSG_VERIFY_SIGNER_CERT, (LPVOID)subject }; ret = CryptMsgControl(data->hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE_EX, ¶); if (!ret) SetLastError(TRUST_E_CERT_SIGNATURE); else data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0, subject); CertFreeCertificateContext(subject); } else { SetLastError(TRUST_E_NO_SIGNER_CERT); ret = FALSE; } data->psPfns->pfnFree(certInfo); } else ret = FALSE; return ret; }
static DWORD WINTRUST_VerifySigner(CRYPT_PROVIDER_DATA *data, DWORD signerIdx) { DWORD err; CERT_INFO *certInfo = WINTRUST_GetSignerCertInfo(data, signerIdx); if (certInfo) { PCCERT_CONTEXT subject = CertGetSubjectCertificateFromStore( data->pahStores[0], data->dwEncoding, certInfo); if (subject) { CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA para = { sizeof(para), 0, signerIdx, CMSG_VERIFY_SIGNER_CERT, (LPVOID)subject }; if (!CryptMsgControl(data->hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE_EX, ¶)) err = TRUST_E_CERT_SIGNATURE; else { data->psPfns->pfnAddCert2Chain(data, signerIdx, FALSE, 0, subject); err = ERROR_SUCCESS; } CertFreeCertificateContext(subject); } else err = TRUST_E_NO_SIGNER_CERT; data->psPfns->pfnFree(certInfo); } else err = GetLastError(); return err; }
BOOL WINAPI CryptVerifyDetachedMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[], DWORD rgcbToBeHashed[], BYTE *pbComputedHash, DWORD *pcbComputedHash) { HCRYPTMSG msg; BOOL ret = FALSE; TRACE("(%p, %p, %d, %d, %p, %p, %p, %p)\n", pHashPara, pbDetachedHashBlob, cbDetachedHashBlob, cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbComputedHash, pcbComputedHash); if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) { SetLastError(E_INVALIDARG); return FALSE; } if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != PKCS_7_ASN_ENCODING) { SetLastError(E_INVALIDARG); return FALSE; } msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, CMSG_DETACHED_FLAG, 0, pHashPara->hCryptProv, NULL, NULL); if (msg) { DWORD i; ret = CryptMsgUpdate(msg, pbDetachedHashBlob, cbDetachedHashBlob, TRUE); if (ret) { if (cToBeHashed) { for (i = 0; ret && i < cToBeHashed; i++) { ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i], i == cToBeHashed - 1); } } else ret = CryptMsgUpdate(msg, NULL, 0, TRUE); } if (ret) { ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); if (ret && pcbComputedHash) ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, pbComputedHash, pcbComputedHash); } CryptMsgClose(msg); } return ret; }
BOOL WINAPI CryptVerifyMessageHash(PCRYPT_HASH_MESSAGE_PARA pHashPara, BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, DWORD *pcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash) { HCRYPTMSG msg; BOOL ret = FALSE; TRACE("(%p, %p, %d, %p, %p, %p, %p)\n", pHashPara, pbHashedBlob, cbHashedBlob, pbToBeHashed, pcbToBeHashed, pbComputedHash, pcbComputedHash); if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA)) { SetLastError(E_INVALIDARG); return FALSE; } if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) != PKCS_7_ASN_ENCODING) { SetLastError(E_INVALIDARG); return FALSE; } msg = CryptMsgOpenToDecode(pHashPara->dwMsgEncodingType, 0, 0, pHashPara->hCryptProv, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, pbHashedBlob, cbHashedBlob, TRUE); if (ret) { ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_HASH, NULL); if (ret && pcbToBeHashed) ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbToBeHashed, pcbToBeHashed); if (ret && pcbComputedHash) ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0, pbComputedHash, pcbComputedHash); } CryptMsgClose(msg); } return ret; }
DWORD do_low_verify (const char *infile, const char *outfile) { HCRYPTPROV hCryptProv = 0; // CSP handle PCCERT_CONTEXT pUserCert = NULL; // User certificate to be used DWORD ret = 1; FILE *tbs = NULL; BYTE *mem_tbs = NULL; DWORD mem_len = 0; FILE *signature = NULL; BYTE *mem_signature = NULL; DWORD signature_len = 0; HCRYPTMSG hMsg = 0; DWORD cbDecoded; BYTE *pbDecoded; DWORD cbSignerCertInfo; PCERT_INFO pSignerCertInfo; PCCERT_CONTEXT pSignerCertContext; PCERT_INFO pSignerCertificateInfo; HCERTSTORE hStoreHandle = NULL; if (! infile) { fprintf (stderr, "No input file was specified\n"); goto err; } tbs = fopen (infile, "rb"); if (!tbs) { fprintf (stderr, "Cannot open input file\n"); goto err; } mem_len = 0; while (!feof(tbs)) { int r = 0; BYTE tmp[1024]; r = fread (tmp, 1, 1024, tbs); mem_tbs = (BYTE *)realloc (mem_tbs, mem_len+r); memcpy (&mem_tbs[mem_len], tmp, r); mem_len += r; } fclose (tbs); tbs = NULL; if (signature) { signature_len = 0; while (!feof(signature)) { int r = 0; BYTE tmp[1024]; r = fread (tmp, 1, 1024, signature); mem_signature = (BYTE *)realloc (mem_signature , signature_len+r); memcpy (&mem_signature [signature_len], tmp, r); signature_len += r; } fclose (signature); signature = NULL; } //-------------------------------------------------------------------- // Open a message for decoding. hMsg = CryptMsgOpenToDecode( TYPE_DER, // Encoding type. 0, // Flags. 0, // Use the default message type. hCryptProv, // Cryptographic provider. NULL, // Recipient information. NULL); // Stream information. if (hMsg) printf("The message to decode is open. \n"); else{ fprintf (stderr, "OpenToDecode failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Update the message with an encoded blob. // Both pbEncodedBlob, the encoded data, // and cbEnclodeBlob, the length of the encoded data, // must be available. if (CryptMsgUpdate( hMsg, // Handle to the message mem_tbs, // Pointer to the encoded blob mem_len, // Size of the encoded blob TRUE)){ // Last call) printf("The encoded blob has been added to the message. \n"); } else { fprintf (stderr, "Decode MsgUpdate failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Get the size of the content. ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index NULL, // Address for returned info &cbDecoded); // Size of the returned info if (ret) printf("The message parameter (CMSG_CONTENT_PARAM) has been acquired. Message size: %d\n", cbDecoded); else{ fprintf (stderr, "Decode CMSG_CONTENT_PARAM failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Allocate memory. pbDecoded = (BYTE *) malloc(cbDecoded); if (!pbDecoded){ fprintf (stderr, "Decode memory allocation failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Get a pointer to the content. ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index pbDecoded, // Address for returned &cbDecoded); // Size of the returned if (ret) printf("The message param (CMSG_CONTENT_PARAM) updated. Length is %lu.\n",(unsigned long)cbDecoded); else{ fprintf (stderr, "Decode CMSG_CONTENT_PARAM #2 failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Verify the signature. // First, get the signer CERT_INFO from the message. //-------------------------------------------------------------------- // Get the size of memory required. if (! pUserCert) { ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // Parameter type 0, // Index NULL, // Address for returned &cbSignerCertInfo); // Size of the returned if (ret) printf("Try to get user cert. OK. Length %d.\n",cbSignerCertInfo); else { printf("No user certificate found in message.\n"); } } if (pUserCert) { hStoreHandle = CertOpenStore(CERT_STORE_PROV_MEMORY, TYPE_DER, 0, CERT_STORE_CREATE_NEW_FLAG,NULL); if (!hStoreHandle){ printf("Cannot create temporary store in memory."); return CSP_GetLastError(); } if (pUserCert) { ret = CertAddCertificateContextToStore(hStoreHandle, pUserCert, CERT_STORE_ADD_ALWAYS, NULL); pSignerCertInfo = pUserCert->pCertInfo; } else ret = 0; if (!ret){ printf("Cannot add user certificate to store."); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Allocate memory. if (!pUserCert) { pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo); if (!pSignerCertInfo){ printf("Verify memory allocation failed"); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Get the message certificate information (CERT_INFO // structure). if (! pUserCert) { ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // Parameter type 0, // Index pSignerCertInfo, // Address for returned &cbSignerCertInfo); // Size of the returned if (ret) printf("The signer info has been returned. \n"); else{ printf("Verify SIGNER_CERT_INFO #2 failed"); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Open a certificate store in memory using CERT_STORE_PROV_MSG, // which initializes it with the certificates from the message. if (! hStoreHandle) { hStoreHandle = CertOpenStore( CERT_STORE_PROV_MSG, // Store provider type TYPE_DER, // Encoding type hCryptProv, // Cryptographic provider 0, // Flags hMsg); // Handle to the message if (hStoreHandle) printf("The message certificate store be used for verifying\n"); } if (! hStoreHandle) { printf("Cannot open certificate store form message\n"); return CSP_GetLastError(); } //-------------------------------------------------------------------- // Find the signer's certificate in the store. if(pSignerCertContext = CertGetSubjectCertificateFromStore( hStoreHandle, // Handle to store TYPE_DER, // Encoding type pSignerCertInfo)) // Pointer to retrieved CERT_CONTEXT { DWORD errCode=0; DWORD err; printf("A signer certificate has been retrieved. \n"); err=VerifyCertificate(pSignerCertContext,&errCode); if (err) { printf("Subject cert verification failed: err=%x\n",err); return err; } if (errCode) { printf("Subject cert BAD: errCode=%x\n",errCode); return errCode; } } else { printf("Verify GetSubjectCert failed"); return CSP_GetLastError(); } //-------------------------------------------------------------------- // Use the CERT_INFO from the signer certificate to verify // the signature. pSignerCertificateInfo = pSignerCertContext->pCertInfo; if(CryptMsgControl( hMsg, // Handle to the message 0, // Flags CMSG_CTRL_VERIFY_SIGNATURE, // Control type pSignerCertificateInfo)) // Pointer to the CERT_INFO { printf("\nSignature was VERIFIED.\n"); } else { printf("\nThe signature was NOT VEIFIED.\n"); } if(hStoreHandle) CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); ret = 0; err: return ret; }
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) { BOOL ret = FALSE; HCRYPTMSG msg; TRACE("(%p, %d, %p, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob, pbDecoded, pcbDecoded, ppSignerCert); if (ppSignerCert) *ppSignerCert = NULL; if (!pVerifyPara || pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) || GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) != PKCS_7_ASN_ENCODING) { if(pcbDecoded) *pcbDecoded = 0; SetLastError(E_INVALIDARG); return FALSE; } msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, 0, 0, pVerifyPara->hCryptProv, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, pbSignedBlob, cbSignedBlob, TRUE); if (ret && pcbDecoded) ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbDecoded, pcbDecoded); if (ret) { CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, dwSignerIndex); ret = FALSE; if (certInfo) { HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG, pVerifyPara->dwMsgAndCertEncodingType, pVerifyPara->hCryptProv, 0, msg); if (store) { PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate( msg, pVerifyPara, certInfo, store); if (cert) { ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo); if (ret && ppSignerCert) *ppSignerCert = cert; else CertFreeCertificateContext(cert); } CertCloseStore(store, 0); } } CryptMemFree(certInfo); } CryptMsgClose(msg); } if(!ret && pcbDecoded) *pcbDecoded = 0; TRACE("returning %d\n", ret); return ret; }
BOOL WINAPI CryptVerifyDetachedMessageSignature( PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE *pbDetachedSignBlob, DWORD cbDetachedSignBlob, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[], DWORD rgcbToBeSigned[], PCCERT_CONTEXT *ppSignerCert) { BOOL ret = FALSE; HCRYPTMSG msg; TRACE("(%p, %d, %p, %d, %d, %p, %p, %p)\n", pVerifyPara, dwSignerIndex, pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, ppSignerCert); if (ppSignerCert) *ppSignerCert = NULL; if (!pVerifyPara || pVerifyPara->cbSize != sizeof(CRYPT_VERIFY_MESSAGE_PARA) || GET_CMSG_ENCODING_TYPE(pVerifyPara->dwMsgAndCertEncodingType) != PKCS_7_ASN_ENCODING) { SetLastError(E_INVALIDARG); return FALSE; } msg = CryptMsgOpenToDecode(pVerifyPara->dwMsgAndCertEncodingType, CMSG_DETACHED_FLAG, 0, pVerifyPara->hCryptProv, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, pbDetachedSignBlob, cbDetachedSignBlob, TRUE); if (ret) { DWORD i; for (i = 0; ret && i < cToBeSigned; i++) ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i], i == cToBeSigned - 1); } if (ret) { CERT_INFO *certInfo = CRYPT_GetSignerCertInfoFromMsg(msg, dwSignerIndex); ret = FALSE; if (certInfo) { HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MSG, pVerifyPara->dwMsgAndCertEncodingType, pVerifyPara->hCryptProv, 0, msg); if (store) { PCCERT_CONTEXT cert = CRYPT_GetSignerCertificate( msg, pVerifyPara, certInfo, store); if (cert) { ret = CryptMsgControl(msg, 0, CMSG_CTRL_VERIFY_SIGNATURE, cert->pCertInfo); if (ret && ppSignerCert) *ppSignerCert = cert; else CertFreeCertificateContext(cert); } else SetLastError(CRYPT_E_NOT_FOUND); CertCloseStore(store, 0); } CryptMemFree(certInfo); } } CryptMsgClose(msg); } TRACE("returning %d\n", ret); return ret; }
void DecodeMessage(PCRYPT_DATA_BLOB pEncodedBlob, LPWSTR pwszSignerName) { //--------------------------------------------------------------- // Buffer to hold the name of the subject of a certificate. wchar_t pszNameString[MAX_NAME]; //--------------------------------------------------------------- // The following variables are used only in the decoding phase. HCRYPTMSG hMsg; HCERTSTORE hStoreHandle; // certificate store handle DWORD cbData = sizeof(DWORD); DWORD cbDecoded; BYTE *pbDecoded; DWORD cbSignerCertInfo; PCERT_INFO pSignerCertInfo; PCCERT_CONTEXT pSignerCertContext; /*--------------------------------------------------------------- The following code decodes the message and verifies the message signature. This code would normally be in a stand-alone program that would read the signed and encoded message and its length from a file from an email message, or from some other source. ---------------------------------------------------------------*/ //--------------------------------------------------------------- // Open a message for decoding. if(hMsg = CryptMsgOpenToDecode( MY_ENCODING_TYPE, // encoding type 0, // flags 0, // use the default message type // the message type is // listed in the message header NULL, // cryptographic provider // use NULL for the default provider NULL, // recipient information NULL)) // stream information { printf("The message to decode is open. \n"); } else { MyHandleError("OpenToDecode failed"); } //--------------------------------------------------------------- // Update the message with an encoded BLOB. if(CryptMsgUpdate( hMsg, // handle to the message pEncodedBlob->pbData, // pointer to the encoded BLOB pEncodedBlob->cbData, // size of the encoded BLOB TRUE)) // last call { printf("The encoded BLOB has been added to the message. \n"); } else { MyHandleError("Decode MsgUpdate failed"); } //--------------------------------------------------------------- // Get the number of bytes needed for a buffer // to hold the decoded message. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_CONTENT_PARAM, // parameter type 0, // index NULL, &cbDecoded)) // size of the returned information { printf("The message parameter has been acquired. \n"); } else { MyHandleError("Decode CMSG_CONTENT_PARAM failed."); } //--------------------------------------------------------------- // Allocate memory. if(!(pbDecoded = (BYTE *) malloc(cbDecoded))) { MyHandleError("Decode memory allocation failed."); } //--------------------------------------------------------------- // Copy the content to the buffer. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_CONTENT_PARAM, // parameter type 0, // index pbDecoded, // address for returned information &cbDecoded)) // size of the returned information { printf("The decoded message is =>\n%s\n\n", (LPSTR)pbDecoded); } else { MyHandleError("Decode CMSG_CONTENT_PARAM #2 failed"); } //--------------------------------------------------------------- // Verify the signature. // First, get the signer CERT_INFO from the message. //--------------------------------------------------------------- // Get the size of memory required for the certificate. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // parameter type 0, // index NULL, &cbSignerCertInfo)) // size of the returned // information { printf("%d bytes needed for the buffer.\n", cbSignerCertInfo); } else { MyHandleError("Verify SIGNER_CERT_INFO #1 failed."); } //--------------------------------------------------------------- // Allocate memory. if(!(pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo))) { MyHandleError("Verify memory allocation failed."); } //--------------------------------------------------------------- // Get the message certificate information (CERT_INFO // structure). if(!(CryptMsgGetParam( hMsg, // handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // parameter type 0, // index pSignerCertInfo, // address for returned // information &cbSignerCertInfo))) // size of the returned // information { MyHandleError("Verify SIGNER_CERT_INFO #2 failed"); } //--------------------------------------------------------------- // Open a certificate store in memory using CERT_STORE_PROV_MSG, // which initializes it with the certificates from the message. if(hStoreHandle = CertOpenStore( CERT_STORE_PROV_MSG, // store provider type MY_ENCODING_TYPE, // encoding type NULL, // cryptographic provider // use NULL for the default 0, // flags hMsg)) // handle to the message { printf("The certificate store to be used for message " \ "verification has been opened.\n"); } else { MyHandleError("Verify open store failed"); } //--------------------------------------------------------------- // Find the signer's certificate in the store. if(pSignerCertContext = CertGetSubjectCertificateFromStore( hStoreHandle, // handle to the store MY_ENCODING_TYPE, // encoding type pSignerCertInfo)) // pointer to retrieved CERT_CONTEXT { if(CertGetNameString( pSignerCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { wprintf(L"The message signer is %s \n",pszNameString); } else { MyHandleError("Getting the signer's name failed.\n"); } } else { MyHandleError("Verify GetSubjectCert failed"); } //--------------------------------------------------------------- // Use the CERT_INFO from the signer certificate to verify // the signature. if(CryptMsgControl( hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo)) { printf("Verify signature succeeded. \n"); } else { printf("The signature was not verified. \n"); DWORD const errcode = GetLastError(); std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); ReportFailure(); } //--------------------------------------------------------------- // Clean up. if(pEncodedBlob->pbData) { free(pEncodedBlob->pbData); pEncodedBlob->pbData = NULL; } if(pbDecoded) { free(pbDecoded); } if(pSignerCertInfo) { free(pSignerCertInfo); } if(pSignerCertContext) { CertFreeCertificateContext(pSignerCertContext); } if(hStoreHandle) { CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); } if(hMsg) { CryptMsgClose(hMsg); } }