crypt32: Implement CryptMsgGetAndVerifySigner.

This commit is contained in:
Juan Lang 2008-08-05 11:06:17 -07:00 committed by Alexandre Julliard
parent d677f6084d
commit fc8545b43a
2 changed files with 109 additions and 19 deletions

View file

@ -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;
}

View file

@ -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);