crypt32: Implement CryptVerifyDetachedMessageSignature.
This commit is contained in:
parent
9e6b32139d
commit
cb5385e326
@ -60,39 +60,6 @@ LONG WINAPI CryptGetMessageSignerCount(DWORD dwMsgEncodingType,
|
|||||||
return count;
|
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,
|
static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
|
||||||
DWORD dwSignerIndex)
|
DWORD dwSignerIndex)
|
||||||
{
|
{
|
||||||
@ -136,6 +103,103 @@ static inline PCCERT_CONTEXT CRYPT_GetSignerCertificate(HCRYPTMSG msg,
|
|||||||
pVerifyPara->dwMsgAndCertEncodingType, certInfo, store);
|
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,
|
BOOL WINAPI CryptVerifyMessageSignature(PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
|
||||||
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
|
DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
|
||||||
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
|
BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
|
||||||
|
@ -335,34 +335,29 @@ static void test_verify_detached_message_signature(void)
|
|||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL,
|
ret = CryptVerifyDetachedMessageSignature(NULL, 0, NULL, 0, 0, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == E_INVALIDARG,
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||||
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == E_INVALIDARG,
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||||
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
||||||
para.cbSize = sizeof(para);
|
para.cbSize = sizeof(para);
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == E_INVALIDARG,
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||||
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
||||||
para.dwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
para.dwMsgAndCertEncodingType = X509_ASN_ENCODING;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == E_INVALIDARG,
|
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||||
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
"Expected E_INVALIDARG, got %08x\n", GetLastError());
|
||||||
para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
|
para.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING;
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, NULL, 0, 0, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
|
||||||
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
"Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
|
||||||
/* None of these messages contains a cert in the message itself, so the
|
/* 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);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, signedContent,
|
||||||
sizeof(signedContent), 0, NULL, NULL, NULL);
|
sizeof(signedContent), 0, NULL, NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
||||||
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
||||||
sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
||||||
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
@ -391,14 +384,12 @@ static void test_verify_detached_message_signature(void)
|
|||||||
cbContent = sizeof(msgData);
|
cbContent = sizeof(msgData);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
||||||
sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
ok(!ret && GetLastError() == CRYPT_E_NOT_FOUND,
|
||||||
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
"Expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError());
|
||||||
/* Passing the correct callback results in success */
|
/* Passing the correct callback results in success */
|
||||||
para.pfnGetSignerCertificate = msg_get_signer_callback;
|
para.pfnGetSignerCertificate = msg_get_signer_callback;
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
||||||
sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
sizeof(detachedSignedContent), 1, &pContent, &cbContent, NULL);
|
||||||
todo_wine
|
|
||||||
ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n",
|
ok(ret, "CryptVerifyDetachedMessageSignature failed: %08x\n",
|
||||||
GetLastError());
|
GetLastError());
|
||||||
/* Not passing the correct data to be signed results in the signature not
|
/* 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);
|
SetLastError(0xdeadbeef);
|
||||||
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
ret = CryptVerifyDetachedMessageSignature(¶, 0, detachedSignedContent,
|
||||||
sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
sizeof(detachedSignedContent), 0, NULL, NULL, NULL);
|
||||||
todo_wine
|
|
||||||
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
|
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
|
||||||
"expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
"expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user