crypt32: Implement CryptMsgGetAndVerifySigner.
This commit is contained in:
parent
d677f6084d
commit
fc8545b43a
|
@ -2446,12 +2446,118 @@ BOOL WINAPI CryptMsgControl(HCRYPTMSG hCryptMsg, DWORD dwFlags,
|
|||
return msg->control(hCryptMsg, dwFlags, dwCtrlType, pvCtrlPara);
|
||||
}
|
||||
|
||||
static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg,
|
||||
DWORD dwSignerIndex)
|
||||
{
|
||||
CERT_INFO *certInfo = NULL;
|
||||
DWORD size;
|
||||
|
||||
if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL,
|
||||
&size))
|
||||
{
|
||||
certInfo = CryptMemAlloc(size);
|
||||
if (certInfo)
|
||||
{
|
||||
if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM,
|
||||
dwSignerIndex, certInfo, &size))
|
||||
{
|
||||
CryptMemFree(certInfo);
|
||||
certInfo = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return certInfo;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, DWORD cSignerStore,
|
||||
HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT *ppSigner,
|
||||
DWORD *pdwSignerIndex)
|
||||
{
|
||||
FIXME("(%p, %d, %p, %08x, %p, %p): stub\n", hCryptMsg, cSignerStore,
|
||||
HCERTSTORE store;
|
||||
DWORD i, signerIndex;
|
||||
PCCERT_CONTEXT signerCert = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p, %d, %p, %08x, %p, %p)\n", hCryptMsg, cSignerStore,
|
||||
rghSignerStore, dwFlags, ppSigner, pdwSignerIndex);
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
|
||||
/* Clear output parameters */
|
||||
if (ppSigner)
|
||||
*ppSigner = NULL;
|
||||
if (pdwSignerIndex && !(dwFlags & CMSG_USE_SIGNER_INDEX_FLAG))
|
||||
*pdwSignerIndex = 0;
|
||||
|
||||
/* Create store to search for signer certificates */
|
||||
store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
|
||||
CERT_STORE_CREATE_NEW_FLAG, NULL);
|
||||
if (!(dwFlags & CMSG_TRUSTED_SIGNER_FLAG))
|
||||
{
|
||||
HCERTSTORE msgStore = CertOpenStore(CERT_STORE_PROV_MSG, 0, 0, 0,
|
||||
hCryptMsg);
|
||||
|
||||
CertAddStoreToCollection(store, msgStore, 0, 0);
|
||||
CertCloseStore(msgStore, 0);
|
||||
}
|
||||
for (i = 0; i < cSignerStore; i++)
|
||||
CertAddStoreToCollection(store, rghSignerStore[i], 0, 0);
|
||||
|
||||
/* Find signer cert */
|
||||
if (dwFlags & CMSG_USE_SIGNER_INDEX_FLAG)
|
||||
{
|
||||
CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
|
||||
*pdwSignerIndex);
|
||||
|
||||
if (signer)
|
||||
{
|
||||
signerIndex = *pdwSignerIndex;
|
||||
signerCert = CertFindCertificateInStore(store, X509_ASN_ENCODING,
|
||||
0, CERT_FIND_SUBJECT_CERT, signer, NULL);
|
||||
CryptMemFree(signer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD count, size = sizeof(count);
|
||||
|
||||
if (CryptMsgGetParam(hCryptMsg, CMSG_SIGNER_COUNT_PARAM, 0, &count,
|
||||
&size))
|
||||
{
|
||||
for (i = 0; !signerCert && i < count; i++)
|
||||
{
|
||||
CERT_INFO *signer = CRYPT_GetSignerCertInfoFromMsg(hCryptMsg,
|
||||
i);
|
||||
|
||||
if (signer)
|
||||
{
|
||||
signerCert = CertFindCertificateInStore(store,
|
||||
X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, signer,
|
||||
NULL);
|
||||
if (signerCert)
|
||||
signerIndex = i;
|
||||
CryptMemFree(signer);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!signerCert)
|
||||
SetLastError(CRYPT_E_NO_TRUSTED_SIGNER);
|
||||
}
|
||||
if (signerCert)
|
||||
{
|
||||
if (!(dwFlags & CMSG_SIGNER_ONLY_FLAG))
|
||||
ret = CryptMsgControl(hCryptMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE,
|
||||
signerCert->pCertInfo);
|
||||
else
|
||||
ret = TRUE;
|
||||
if (ret)
|
||||
{
|
||||
if (ppSigner)
|
||||
*ppSigner = CertDuplicateCertificateContext(signerCert);
|
||||
if (pdwSignerIndex)
|
||||
*pdwSignerIndex = signerIndex;
|
||||
}
|
||||
CertFreeCertificateContext(signerCert);
|
||||
}
|
||||
|
||||
CertCloseStore(store, 0);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2580,26 +2580,21 @@ static void test_msg_get_and_verify_signer(void)
|
|||
/* An empty message has no signer */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
/* The signer is cleared on error */
|
||||
signer = (PCCERT_CONTEXT)0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
todo_wine
|
||||
ok(!signer, "expected signer to be NULL\n");
|
||||
/* The signer index is also cleared on error */
|
||||
signerIndex = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
todo_wine
|
||||
ok(!signerIndex, "expected 0, got %d\n", signerIndex);
|
||||
/* An unsigned message (msgData isn't a signed message at all)
|
||||
* likewise has no signer.
|
||||
|
@ -2607,7 +2602,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
CryptMsgUpdate(msg, msgData, sizeof(msgData), TRUE);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
CryptMsgClose(msg);
|
||||
|
@ -2617,7 +2611,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
CryptMsgUpdate(msg, signedEmptyContent, sizeof(signedEmptyContent), TRUE);
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
CryptMsgClose(msg);
|
||||
|
@ -2627,21 +2620,16 @@ static void test_msg_get_and_verify_signer(void)
|
|||
CryptMsgUpdate(msg, signedWithCertWithValidPubKeyContent,
|
||||
sizeof(signedWithCertWithValidPubKeyContent), TRUE);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, NULL);
|
||||
todo_wine
|
||||
ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
|
||||
/* the signer index can be retrieved, .. */
|
||||
signerIndex = 0xdeadbeef;
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, NULL, &signerIndex);
|
||||
todo_wine
|
||||
ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
|
||||
todo_wine
|
||||
ok(signerIndex == 0, "expected 0, got %d\n", signerIndex);
|
||||
/* as can the signer cert. */
|
||||
signer = (PCCERT_CONTEXT)0xdeadbeef;
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, 0, &signer, NULL);
|
||||
todo_wine
|
||||
ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
|
||||
todo_wine
|
||||
ok(signer != NULL && signer != (PCCERT_CONTEXT)0xdeadbeef,
|
||||
"expected a valid signer\n");
|
||||
if (signer && signer != (PCCERT_CONTEXT)0xdeadbeef)
|
||||
|
@ -2652,7 +2640,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_USE_SIGNER_INDEX_FLAG,
|
||||
NULL, &signerIndex);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_INVALID_INDEX,
|
||||
"expected CRYPT_E_INVALID_INDEX, got 0x%08x\n", GetLastError());
|
||||
/* Specifying CMSG_TRUSTED_SIGNER_FLAG and no cert stores causes the
|
||||
|
@ -2661,7 +2648,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 0, NULL, CMSG_TRUSTED_SIGNER_FLAG,
|
||||
NULL, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
/* Specifying CMSG_TRUSTED_SIGNER_FLAG and an empty cert store also causes
|
||||
|
@ -2672,7 +2658,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
|
||||
NULL, NULL);
|
||||
todo_wine
|
||||
ok(!ret && GetLastError() == CRYPT_E_NO_TRUSTED_SIGNER,
|
||||
"expected CRYPT_E_NO_TRUSTED_SIGNER, got 0x%08x\n", GetLastError());
|
||||
ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING,
|
||||
|
@ -2686,7 +2671,6 @@ static void test_msg_get_and_verify_signer(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = CryptMsgGetAndVerifySigner(msg, 1, &store, CMSG_TRUSTED_SIGNER_FLAG,
|
||||
NULL, NULL);
|
||||
todo_wine
|
||||
ok(ret, "CryptMsgGetAndVerifySigner failed: 0x%08x\n", GetLastError());
|
||||
CertCloseStore(store, 0);
|
||||
CryptMsgClose(msg);
|
||||
|
|
Loading…
Reference in New Issue