Commit 1ce0799d authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

wininet: Differentiate checking online and offline CRLs.

parent ec223a21
...@@ -1557,29 +1557,25 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid, ...@@ -1557,29 +1557,25 @@ BOOL WINAPI CryptRetrieveObjectByUrlW(LPCWSTR pszURL, LPCSTR pszObjectOid,
return ret; return ret;
} }
static DWORD verify_cert_revocation_with_crl(PCCERT_CONTEXT cert, static DWORD verify_cert_revocation_with_crl_online(PCCERT_CONTEXT cert,
PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime, PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime,
PCERT_REVOCATION_STATUS pRevStatus) PCERT_REVOCATION_STATUS pRevStatus)
{ {
DWORD error; DWORD error;
PCRL_ENTRY entry = NULL;
if (CertVerifyCRLTimeValidity(pTime, crl->pCrlInfo)) CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
if (entry)
{ {
/* The CRL isn't time valid */ error = CRYPT_E_REVOKED;
error = CRYPT_E_NO_REVOCATION_CHECK; pRevStatus->dwIndex = index;
} }
else else
{ {
PCRL_ENTRY entry = NULL; /* Since the CRL was retrieved for the cert being checked, then it's
* guaranteed to be fresh, and the cert is not revoked.
CertFindCertificateInCRL(cert, crl, 0, NULL, &entry); */
if (entry) error = ERROR_SUCCESS;
{
error = CRYPT_E_REVOKED;
pRevStatus->dwIndex = index;
}
else
error = ERROR_SUCCESS;
} }
return error; return error;
} }
...@@ -1625,8 +1621,8 @@ static DWORD verify_cert_revocation_from_dist_points_ext( ...@@ -1625,8 +1621,8 @@ static DWORD verify_cert_revocation_from_dist_points_ext(
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
if (ret) if (ret)
{ {
error = verify_cert_revocation_with_crl(cert, crl, index, error = verify_cert_revocation_with_crl_online(cert, crl,
pTime, pRevStatus); index, pTime, pRevStatus);
if (!error && timeout) if (!error && timeout)
{ {
DWORD time = GetTickCount(); DWORD time = GetTickCount();
...@@ -1696,6 +1692,45 @@ static DWORD verify_cert_revocation_from_aia_ext( ...@@ -1696,6 +1692,45 @@ static DWORD verify_cert_revocation_from_aia_ext(
return error; return error;
} }
static DWORD verify_cert_revocation_with_crl_offline(PCCERT_CONTEXT cert,
PCCRL_CONTEXT crl, DWORD index, FILETIME *pTime,
PCERT_REVOCATION_STATUS pRevStatus)
{
DWORD error;
LONG valid;
valid = CompareFileTime(pTime, &crl->pCrlInfo->ThisUpdate);
if (valid <= 0)
{
/* If this CRL is not older than the time being verified, there's no
* way to know whether the certificate was revoked.
*/
TRACE("CRL not old enough\n");
error = CRYPT_E_REVOCATION_OFFLINE;
}
else
{
PCRL_ENTRY entry = NULL;
CertFindCertificateInCRL(cert, crl, 0, NULL, &entry);
if (entry)
{
error = CRYPT_E_REVOKED;
pRevStatus->dwIndex = index;
}
else
{
/* Since the CRL was not retrieved for the cert being checked,
* there's no guarantee it's fresh, so the cert *might* be okay,
* but it's safer not to guess.
*/
TRACE("certificate not found\n");
error = CRYPT_E_REVOCATION_OFFLINE;
}
}
return error;
}
static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index,
FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara, FILETIME *pTime, DWORD dwFlags, PCERT_REVOCATION_PARA pRevPara,
PCERT_REVOCATION_STATUS pRevStatus) PCERT_REVOCATION_STATUS pRevStatus)
...@@ -1761,8 +1796,8 @@ static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index, ...@@ -1761,8 +1796,8 @@ static DWORD verify_cert_revocation(PCCERT_CONTEXT cert, DWORD index,
} }
if (crl) if (crl)
{ {
error = verify_cert_revocation_with_crl(cert, crl, index, error = verify_cert_revocation_with_crl_offline(cert, crl,
pTime, pRevStatus); index, pTime, pRevStatus);
CertFreeCRLContext(crl); CertFreeCRLContext(crl);
} }
else else
......
...@@ -733,7 +733,6 @@ static void test_verifyRevocation(void) ...@@ -733,7 +733,6 @@ static void test_verifyRevocation(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status); 1, (void **)&certs[1], 0, &revPara, &status);
todo_wine
ok(!ret && (GetLastError() == CRYPT_E_REVOKED || ok(!ret && (GetLastError() == CRYPT_E_REVOKED ||
broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
"expected CRYPT_E_REVOKED, got %08x\n", GetLastError()); "expected CRYPT_E_REVOKED, got %08x\n", GetLastError());
...@@ -748,7 +747,6 @@ static void test_verifyRevocation(void) ...@@ -748,7 +747,6 @@ static void test_verifyRevocation(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status); 1, (void **)&certs[1], 0, &revPara, &status);
todo_wine
ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
"expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
...@@ -764,7 +762,6 @@ static void test_verifyRevocation(void) ...@@ -764,7 +762,6 @@ static void test_verifyRevocation(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status); 1, (void **)&certs[1], 0, &revPara, &status);
todo_wine
ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
"expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
...@@ -772,7 +769,6 @@ static void test_verifyRevocation(void) ...@@ -772,7 +769,6 @@ static void test_verifyRevocation(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status); 1, (void **)&certs[1], 0, &revPara, &status);
todo_wine
ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
"expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
...@@ -780,7 +776,6 @@ static void test_verifyRevocation(void) ...@@ -780,7 +776,6 @@ static void test_verifyRevocation(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE,
1, (void **)&certs[1], 0, &revPara, &status); 1, (void **)&certs[1], 0, &revPara, &status);
todo_wine
ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE ||
broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)),
"expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment