SecureProgramming.com
Login
Username: 
Password: 
Forgot your password?
Create a new account





Win32: Obtaining CRLs with CryptoAPICategory: Public Key Infrastructure
Language: C, C++, and Objective-C
Posted by Matt Messier on Tue, Dec 02, 2003 (03:37 AM) GMT [Submitted by Sascha Kiefer]

Secure Programming Cookbook for C and C++ This recipe is a supplement to Recipe 10.11, which can be found beginning on page 556 in Secure Programming Cookbook for C and C++ by John Viega and Matt Messier.

Problem
Recipe 10.11 in the book "Secure Programming Cookbook for C and C++" showed an example of how to retrieve CRLs from a CA specified as a URL in the extension properties of an X.509 Certificate. The code presented in book used its own "search" function to find a cRLDistributionPoints extension in the certificate, and the Win32 WinInet functions to download the CRL from an HTTP or HTTPS location. Other types of URLs are possible as well, including LDAP and FTP; however, the code presented in the book does not support anything other than HTTP and HTTPS.

Solution
Newer versions of CryptoAPI provides two functions that help to get the CRL information, and can be used in place of the GetDistrubtionPoint() and SpcRetrieveCRL() functions presented in Recipe 10.11. The two functions are:
  • CryptGetObjectUrl()
  • CryptRetrieveObjectByUrl()

Both are declared in wincrypt.h and require the Cryptnet.lib import library. Note that these functions are only available on Windows 2000, XP, and newer.

Discussion
PCRYPT_URL_ARRAY SpcGetDistributionPointList(PCCERT_CONTEXT pCertContext)
{
DWORD dwFlags, cbUrlArray;
PCRYPT_URL_ARRAY pUrlArray;

dwFlags = CRYPT_GET_URL_FROM_PROPERTY | CRYPT_GET_URL_FROM_EXTENSION;
if (!CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, pCertContext,
dwFlags, NULL, &cbUrlArray, NULL, NULL, NULL))
{
return NULL;
}

if (!(pUrlArray = (PCRYPT_URL_ARRAY)LocalAlloc(LMEM_FIXED, cbUrlArray)))
return NULL;

if (!CryptGetObjectUrl(URL_OID_CERTIFICATE_CRL_DIST_POINT, pCertContext,
dwFlags, pUrlArray, &cbUrlArray, NULL, NULL, NULL))
{
LocalFree(pUrlArray);
return NULL;
}

return pUrlArray;
}

PCCRL_CONTEXT *SpcRetrieveRemoteCRLs(PCCERT_CONTEXT pCertContext)
{
DWORD dwFlags, dwIndex, i;
LPCSTR pszURL;
PCCRL_CONTEXT pCrlContext, *pCrlContexts;
PCRYPT_URL_ARRAY pUrlArray;

if (!(pUrlArray = GetDistributionPointBetter(pCertContext))) return NULL;
dwFlags = CRYPT_WIRE_ONLY_RETRIEVAL;

pCrlContexts = (PCCRL_CONTEXT *)LocalAlloc(LMEM_FIXED,
sizeof(PCCRL_CONTEXT) * (pUrlArray->cUrl + 1));
if (!pCrlContexts) {
LocalFree(pUrlArray);
return NULL;
}

for (dwIndex = i = 0; i < pUrlArray->cUrl; i++) {
if (!(lpszURL = make_thin(pUrlArray->rgwszUrl[i]))) continue;
if (!CryptRetrieveObjectByUrl(lpszURL, CONTEXT_OID_CRL, dwFlags, 5000,
(LPVOID *)&pCrlContext, 0, 0, 0, 0))
{
LocalFree(lpszUrl);
continue;
}

pCrlContexts[dwIndex++] = pCrlContext;
LocalFree(lpszUrl);
}

pCrlContexts[dwIndex] = NULL;
LocalFree(pUrlArray);
return pCrlContexts;
}


[Python Powered]