diff --git a/dlls/crypt32/message.c b/dlls/crypt32/message.c index ee7c5ba5eb0..2eb210c11b5 100644 --- a/dlls/crypt32/message.c +++ b/dlls/crypt32/message.c @@ -60,39 +60,6 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType, return count; } -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) -{ - FIXME("(%p, %d, %p, %d, %d, %p, %p, %p): stub\n", pVerifyPara, dwSignerIndex, - pbDetachedSignBlob, cbDetachedSignBlob, cToBeSigned, rgpbToBeSigned, - rgcbToBeSigned, ppSignerCert); - return FALSE; -} - -static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src, - DWORD len) -{ - BOOL ret = TRUE; - - if (!pvData) - *pcbData = len; - else if (*pcbData < len) - { - *pcbData = len; - SetLastError(ERROR_MORE_DATA); - ret = FALSE; - } - else - { - *pcbData = len; - memcpy(pvData, src, len); - } - return ret; -} - static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, DWORD dwSignerIndex) { @@ -136,6 +103,103 @@ static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg, pVerifyPara->dwMsgAndCertEncodingType, certInfo, store); } +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 ? TRUE : FALSE); + } + 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; +} + +static BOOL CRYPT_CopyParam(void *pvData, DWORD *pcbData, const void *src, + DWORD len) +{ + BOOL ret = TRUE; + + if (!pvData) + *pcbData = len; + else if (*pcbData < len) + { + *pcbData = len; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + *pcbData = len; + memcpy(pvData, src, len); + } + return ret; +} + BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob, BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert) diff --git a/dlls/crypt32/tests/message.c b/dlls/crypt32/tests/message.c index a6dde761a82..28f9a4eb8ec 100644 --- a/dlls/crypt32/tests/message.c +++ b/dlls/crypt32/tests/message.c @@ -335,34 +335,29 @@ static void test_verify_detached_message_signature(void) SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); para.cbSize = sizeof(para); SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); para.dwMsgAndCertEncodingType = X509_ASN_ENCODING; SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING; SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD, "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError()); /* None of these messages contains a cert in the message itself, so the @@ -377,13 +372,11 @@ static void test_verify_detached_message_signature(void) SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent, sizeof(signedContent), 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); @@ -391,14 +384,12 @@ static void test_verify_detached_message_signature(void) cbContent = sizeof(msgData); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); - todo_wine ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND, "Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); /* Passing the correct callback results in success */ para.pfnGetSignerCertificate = msg_get_signer_callback; ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL); - todo_wine ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n", GetLastError()); /* Not passing the correct data to be signed results in the signature not @@ -407,7 +398,6 @@ static void test_verify_detached_message_signature(void) SetLastError(0xdeadbeef); ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent, sizeof(detachedSignedContent), 0, NULL, NULL, NULL); - todo_wine ok(!ret && GetLastError() == NTE_BAD_SIGNATURE, "expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError()); }