|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: urlprov.cpp
//
// Contents: CryptGetObjectUrl provider implementation
//
// History: 16-Sep-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Function: CertificateIssuerGetObjectUrl
//
// Synopsis: get certificate issuer URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CertificateIssuerGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN OPTIONAL LPVOID pvReserved ) { return( ObjectContextUrlFromInfoAccess( CONTEXT_OID_CERTIFICATE, pvPara, (DWORD) -1L, szOID_AUTHORITY_INFO_ACCESS, dwFlags, szOID_PKIX_CA_ISSUERS, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CertificateCrlDistPointGetObjectUrl
//
// Synopsis: get certificate CRL URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CertificateCrlDistPointGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { return( ObjectContextUrlFromCrlDistPoint( CONTEXT_OID_CERTIFICATE, pvPara, (DWORD) -1L, dwFlags, szOID_CRL_DIST_POINTS, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CertificateFreshestCrlGetObjectUrl
//
// Synopsis: get certificate freshest CRL URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CertificateFreshestCrlGetObjectUrl( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN OPTIONAL LPVOID pvReserved ) {
return( ObjectContextUrlFromCrlDistPoint( CONTEXT_OID_CERTIFICATE, pvPara, (DWORD) -1L, dwFlags, szOID_FRESHEST_CRL, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CrlFreshestCrlGetObjectUrl
//
// Synopsis: get freshest CRL URL from the certificate's base CRL
//
//----------------------------------------------------------------------------
BOOL WINAPI CrlFreshestCrlGetObjectUrl( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN OPTIONAL LPVOID pvReserved ) { PCCERT_CRL_CONTEXT_PAIR pCertCrlPair = (PCCERT_CRL_CONTEXT_PAIR) pvPara;
return( ObjectContextUrlFromCrlDistPoint( CONTEXT_OID_CRL, (LPVOID) pCertCrlPair->pCrlContext, (DWORD) -1L, dwFlags, szOID_FRESHEST_CRL, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CtlIssuerGetObjectUrl
//
// Synopsis: get CTL issuer URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CtlIssuerGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { PURL_OID_CTL_ISSUER_PARAM pParam = (PURL_OID_CTL_ISSUER_PARAM)pvPara;
return( ObjectContextUrlFromInfoAccess( CONTEXT_OID_CTL, (LPVOID)pParam->pCtlContext, pParam->SignerIndex, szOID_AUTHORITY_INFO_ACCESS, CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE | CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE, szOID_PKIX_CA_ISSUERS, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CtlNextUpdateGetObjectUrl
//
// Synopsis: get CTL renewal URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CtlNextUpdateGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { LPVOID* apv = (LPVOID *)pvPara;
return( ObjectContextUrlFromNextUpdateLocation( CONTEXT_OID_CTL, apv[0], (DWORD)(DWORD_PTR)apv[1], dwFlags, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: CrlIssuerGetObjectUrl
//
// Synopsis: get CRL issuer URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CrlIssuerGetObjectUrl ( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { return( ObjectContextUrlFromInfoAccess( CONTEXT_OID_CRL, pvPara, (DWORD) -1L, szOID_AUTHORITY_INFO_ACCESS, dwFlags, szOID_PKIX_CA_ISSUERS, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo, pvReserved ) ); }
//+---------------------------------------------------------------------------
//
// Function: ObjectContextUrlFromInfoAccess
//
// Synopsis: get the URLs specified by the access method OID from the given
// context and format it as a CRYPT_URL_ARRAY
//
//----------------------------------------------------------------------------
BOOL WINAPI ObjectContextUrlFromInfoAccess ( IN LPCSTR pszContextOid, IN LPVOID pvContext, IN DWORD Index, IN LPCSTR pszInfoAccessOid, IN DWORD dwFlags, IN LPCSTR pszAccessMethodOid, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { BOOL fResult = FALSE; CRYPT_RAW_URL_DATA RawData[MAX_RAW_URL_DATA]; ULONG cRawData = MAX_RAW_URL_DATA;
fResult = ObjectContextGetRawUrlData( pszContextOid, pvContext, Index, dwFlags, pszInfoAccessOid, RawData, &cRawData );
if ( fResult == TRUE ) { fResult = GetUrlArrayAndInfoFromInfoAccess( cRawData, RawData, pszAccessMethodOid, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo );
ObjectContextFreeRawUrlData( cRawData, RawData ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: ObjectContextUrlFromCrlDistPoint
//
// Synopsis: get the URLs from the CRL distribution point on the object and
// format as a CRYPT_URL_ARRAY
//
//----------------------------------------------------------------------------
BOOL WINAPI ObjectContextUrlFromCrlDistPoint ( IN LPCSTR pszContextOid, IN LPVOID pvContext, IN DWORD Index, IN DWORD dwFlags, IN LPCSTR pszSourceOid, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { BOOL fResult = FALSE; CRYPT_RAW_URL_DATA RawData[MAX_RAW_URL_DATA]; ULONG cRawData = MAX_RAW_URL_DATA;
fResult = ObjectContextGetRawUrlData( pszContextOid, pvContext, Index, dwFlags, pszSourceOid, RawData, &cRawData );
if ( fResult == TRUE ) { fResult = GetUrlArrayAndInfoFromCrlDistPoint( cRawData, RawData, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo );
ObjectContextFreeRawUrlData( cRawData, RawData ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: ObjectContextUrlFromNextUpdateLocation
//
// Synopsis: get the URLs from the next update location
//
//----------------------------------------------------------------------------
BOOL WINAPI ObjectContextUrlFromNextUpdateLocation ( IN LPCSTR pszContextOid, IN LPVOID pvContext, IN DWORD Index, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { BOOL fResult = FALSE; CRYPT_RAW_URL_DATA RawData[MAX_RAW_URL_DATA]; ULONG cRawData = MAX_RAW_URL_DATA;
fResult = ObjectContextGetRawUrlData( pszContextOid, pvContext, Index, dwFlags, szOID_NEXT_UPDATE_LOCATION, RawData, &cRawData );
if ( fResult == TRUE ) { fResult = GetUrlArrayAndInfoFromNextUpdateLocation( cRawData, RawData, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo );
ObjectContextFreeRawUrlData( cRawData, RawData ); }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: InitializeDefaultUrlInfo
//
// Synopsis: initialize default URL info
//
//----------------------------------------------------------------------------
VOID WINAPI InitializeDefaultUrlInfo ( OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT DWORD* pcbUrlInfo ) {
if ( pUrlInfo == NULL ) { *pcbUrlInfo = sizeof( CRYPT_URL_INFO ); return; }
if (*pcbUrlInfo >= sizeof( CRYPT_URL_INFO )) { *pcbUrlInfo = sizeof( CRYPT_URL_INFO ); memset( pUrlInfo, 0, sizeof( CRYPT_URL_INFO ) ); pUrlInfo->cbSize = sizeof( CRYPT_URL_INFO ); } else if (*pcbUrlInfo >= sizeof( DWORD )) { *pcbUrlInfo = sizeof( DWORD ); pUrlInfo->cbSize = sizeof( DWORD ); } }
//+---------------------------------------------------------------------------
//
// Function: ObjectContextGetRawUrlData
//
// Synopsis: Raw URL data is a decoded extension, property or attribute
// specified by a source OID that contains locator information.
// This API retrieves and decodes such data
//
//----------------------------------------------------------------------------
BOOL WINAPI ObjectContextGetRawUrlData ( IN LPCSTR pszContextOid, IN LPVOID pvContext, IN DWORD Index, IN DWORD dwFlags, IN LPCSTR pszSourceOid, OUT PCRYPT_RAW_URL_DATA aRawUrlData, IN OUT DWORD* pcRawUrlData ) { BOOL fResult = TRUE; DWORD cCount; DWORD cError = 0; DWORD cRawData = 0; CRYPT_RAW_URL_DATA RawData[MAX_RAW_URL_DATA]; CRYPT_DATA_BLOB DataBlob = {0, NULL}; BOOL fFreeDataBlob = FALSE; DWORD cbDecoded; LPBYTE pbDecoded = NULL; PCRYPT_ATTRIBUTE pAttr = NULL; DWORD cbAttr;
if ( dwFlags & CRYPT_GET_URL_FROM_PROPERTY ) { RawData[cRawData].dwFlags = CRYPT_GET_URL_FROM_PROPERTY; RawData[cRawData].pvData = NULL; cRawData += 1; }
if ( dwFlags & CRYPT_GET_URL_FROM_EXTENSION ) { RawData[cRawData].dwFlags = CRYPT_GET_URL_FROM_EXTENSION; RawData[cRawData].pvData = NULL; cRawData += 1; }
if ( dwFlags & CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE ) { RawData[cRawData].dwFlags = CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE; RawData[cRawData].pvData = NULL; cRawData += 1; }
if ( dwFlags & CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE ) { RawData[cRawData].dwFlags = CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE; RawData[cRawData].pvData = NULL; cRawData += 1; }
if ( *pcRawUrlData < cRawData ) { SetLastError( (DWORD) E_INVALIDARG ); return( FALSE ); }
for ( cCount = 0; cCount < cRawData; cCount++ ) { switch ( RawData[cCount].dwFlags ) { case CRYPT_GET_URL_FROM_PROPERTY: { DWORD PropId;
fResult = MapOidToPropertyId( pszSourceOid, &PropId ); if ( fResult == TRUE ) { fResult = ObjectContextGetProperty( pszContextOid, pvContext, PropId, NULL, &DataBlob.cbData ); }
if ( fResult == TRUE ) { DataBlob.pbData = new BYTE [ DataBlob.cbData ]; if ( DataBlob.pbData != NULL ) { fFreeDataBlob = TRUE;
fResult = ObjectContextGetProperty( pszContextOid, pvContext, PropId, DataBlob.pbData, &DataBlob.cbData ); } else { fResult = FALSE; SetLastError( (DWORD) E_OUTOFMEMORY ); } } } break; case CRYPT_GET_URL_FROM_EXTENSION: { PCERT_EXTENSION pExt;
pExt = ObjectContextFindExtension( pszContextOid, pvContext, pszSourceOid );
if ( pExt != NULL ) { DataBlob.cbData = pExt->Value.cbData; DataBlob.pbData = pExt->Value.pbData; fResult = TRUE; } else { fResult = FALSE; } } break; case CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE: case CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE: { fResult = ObjectContextGetAttribute( pszContextOid, pvContext, Index, RawData[cCount].dwFlags, pszSourceOid, NULL, &cbAttr );
if ( fResult == TRUE ) { pAttr = (PCRYPT_ATTRIBUTE)new BYTE [cbAttr]; if ( pAttr != NULL ) { fResult = ObjectContextGetAttribute( pszContextOid, pvContext, Index, RawData[cCount].dwFlags, pszSourceOid, pAttr, &cbAttr ); } else { fResult = FALSE; SetLastError( (DWORD) E_OUTOFMEMORY ); } }
if ( fResult == TRUE ) { // We only deal with single valued attributes
DataBlob.cbData = pAttr->rgValue[0].cbData; DataBlob.pbData = pAttr->rgValue[0].pbData; } } break; }
if ( fResult == TRUE ) { fResult = CryptDecodeObject( X509_ASN_ENCODING, pszSourceOid, DataBlob.pbData, DataBlob.cbData, 0, NULL, &cbDecoded );
if ( fResult == TRUE ) { pbDecoded = new BYTE [ cbDecoded ]; if ( pbDecoded != NULL ) { fResult = CryptDecodeObject( X509_ASN_ENCODING, pszSourceOid, DataBlob.pbData, DataBlob.cbData, 0, pbDecoded, &cbDecoded ); } else { fResult = FALSE; } } }
if ( fResult == TRUE ) { RawData[cCount].pvData = (LPVOID)pbDecoded; } else { if ( pbDecoded != NULL ) { delete [] pbDecoded; } cError += 1; } pbDecoded = NULL;
if ( fFreeDataBlob == TRUE ) { delete [] DataBlob.pbData; fFreeDataBlob = FALSE; }
if ( pAttr != NULL ) { delete [] (BYTE *)pAttr; pAttr = NULL; } }
if ( cError != cRawData ) { memcpy( aRawUrlData, RawData, cRawData * sizeof( CRYPT_RAW_URL_DATA ) ); *pcRawUrlData = cRawData; fResult = TRUE; } else { SetLastError( (DWORD) CRYPT_E_NOT_FOUND ); fResult = FALSE; }
return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: ObjectContextFreeRawUrlData
//
// Synopsis: free the raw URL data
//
//----------------------------------------------------------------------------
VOID WINAPI ObjectContextFreeRawUrlData ( IN DWORD cRawUrlData, IN PCRYPT_RAW_URL_DATA aRawUrlData ) { DWORD cCount;
for ( cCount = 0; cCount < cRawUrlData; cCount++ ) { delete [] (BYTE *) aRawUrlData[cCount].pvData; } }
//+---------------------------------------------------------------------------
//
// Function: GetUrlArrayAndInfoFromAuthInfoAccess
//
// Synopsis: get URL data using decoded info access data
//
//----------------------------------------------------------------------------
BOOL WINAPI GetUrlArrayAndInfoFromInfoAccess ( IN DWORD cRawUrlData, IN PCRYPT_RAW_URL_DATA aRawUrlData, IN LPCSTR pszAccessMethodOid, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo ) { BOOL fResult = FALSE; PCERT_AUTHORITY_INFO_ACCESS pAuthInfoAccess = NULL; PCERT_ACCESS_DESCRIPTION rgAccDescr = NULL; DWORD cRaw; DWORD cCount; BOOL fAnyFound = FALSE; CCryptUrlArray cua( 1, 5, fResult );
for ( cRaw = 0; ( fResult == TRUE ) && ( cRaw < cRawUrlData ); cRaw++ ) { pAuthInfoAccess = (PCERT_AUTHORITY_INFO_ACCESS)aRawUrlData[cRaw].pvData; if ( pAuthInfoAccess != NULL ) { rgAccDescr = pAuthInfoAccess->rgAccDescr;
for ( cCount = 0; ( cCount < pAuthInfoAccess->cAccDescr ) && ( fResult == TRUE ); cCount++ ) { if ( !strcmp( pszAccessMethodOid, rgAccDescr[cCount].pszAccessMethod ) ) { if ( rgAccDescr[cCount].AccessLocation.dwAltNameChoice == CERT_ALT_NAME_URL ) { fResult = cua.AddUrl( rgAccDescr[cCount].AccessLocation.pwszURL, TRUE );
fAnyFound = TRUE; } } } } }
if ( ( fAnyFound == FALSE ) && ( fResult == TRUE ) ) { SetLastError( (DWORD) CRYPT_E_NOT_FOUND ); fResult = FALSE; }
if ( fResult == TRUE ) { PCRYPT_URL_ARRAY* ppUrlArray = NULL;
if ( pUrlArray != NULL ) { ppUrlArray = &pUrlArray; }
fResult = cua.GetArrayInSingleBufferEncodedForm( ppUrlArray, pcbUrlArray ); }
if ( ( fResult == TRUE ) && ( pcbUrlInfo != NULL ) ) { InitializeDefaultUrlInfo( pUrlInfo, pcbUrlInfo ); }
cua.FreeArray( TRUE ); return( fResult ); }
#define DIR_NAME_LDAP_URL_PREFIX L"ldap://"
#define URL_OID_CDP_DIR_NAME_LDAP_HOST_PORTS_VALUE_NAME \
L"DirectoryNameLdapHostPorts" #define URL_OID_CDP_DIR_NAME_LDAP_SUFFIX_VALUE_NAME \
L"DirectoryNameLdapSuffix"
LPCWSTR pwszDefaultCDPDirNameLdapUrlHostPorts = L"\0\0";
LPCWSTR pwszDefaultCDPDirNameLdapUrlSuffix= L"?certificateRevocationList;binary,authorityRevocationList;binary,deltaRevocationList;binary";
LPWSTR WINAPI GetCDPOIDFunctionValue( IN LPCWSTR pwszValueName ) { BOOL fResult; DWORD dwType; DWORD cchValue; DWORD cbValue = 0; LPWSTR pwszValue = NULL;
fResult = CryptGetOIDFunctionValue( X509_ASN_ENCODING, URL_OID_GET_OBJECT_URL_FUNC, URL_OID_CERTIFICATE_CRL_DIST_POINT, pwszValueName, &dwType, NULL, &cbValue ); cchValue = cbValue / sizeof(WCHAR); if (!fResult || 0 == cchValue || !(REG_MULTI_SZ == dwType || REG_SZ == dwType || REG_EXPAND_SZ == dwType)) goto ErrorReturn;
pwszValue = new WCHAR [cchValue + 2]; if (NULL == pwszValue) goto OutOfMemory;
fResult = CryptGetOIDFunctionValue( X509_ASN_ENCODING, URL_OID_GET_OBJECT_URL_FUNC, URL_OID_CERTIFICATE_CRL_DIST_POINT, pwszValueName, &dwType, (BYTE *) pwszValue, &cbValue ); if (!fResult) goto ErrorReturn;
// Ensure the value has two null terminators
pwszValue[cchValue] = L'\0'; pwszValue[cchValue + 1] = L'\0';
CommonReturn: return pwszValue; ErrorReturn: if (pwszValue) { delete [] pwszValue; pwszValue = NULL; } goto CommonReturn; OutOfMemory: SetLastError( (DWORD) E_OUTOFMEMORY ); goto ErrorReturn; }
// For an error or no found registry value,
// returns pwszDefaultCDPDirNameLdapUrlHostPorts
LPWSTR WINAPI GetCDPDirNameLdapUrlHostPorts() { LPWSTR pwszHostPorts;
pwszHostPorts = GetCDPOIDFunctionValue( URL_OID_CDP_DIR_NAME_LDAP_HOST_PORTS_VALUE_NAME); if (NULL == pwszHostPorts) pwszHostPorts = (LPWSTR) pwszDefaultCDPDirNameLdapUrlHostPorts;
return pwszHostPorts; }
// For an error or no found registry value,
// returns pwszDefaultCDPDirNameLdapUrlSuffix
LPWSTR WINAPI GetCDPDirNameLdapUrlSuffix() { LPWSTR pwszSuffix = NULL;
pwszSuffix = GetCDPOIDFunctionValue( URL_OID_CDP_DIR_NAME_LDAP_SUFFIX_VALUE_NAME); if (NULL == pwszSuffix) pwszSuffix = (LPWSTR) pwszDefaultCDPDirNameLdapUrlSuffix;
return pwszSuffix; }
BOOL WINAPI AddUrlsFromCDPDirectoryName ( IN PCERT_NAME_BLOB pDirNameBlob, IN OUT CCryptUrlArray *pcua ) { BOOL fResult; LPWSTR pwszHP; LPWSTR pwszHostPorts; LPWSTR pwszSuffix; LPWSTR pwszDirName = NULL; DWORD cchDirName;
pwszHostPorts = GetCDPDirNameLdapUrlHostPorts(); pwszSuffix = GetCDPDirNameLdapUrlSuffix(); assert(NULL != pwszHostPorts && NULL != pwszSuffix);
cchDirName = CertNameToStrW( X509_ASN_ENCODING, pDirNameBlob, CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, NULL, // pwsz
0 // cch
); if (1 >= cchDirName) goto ErrorReturn; pwszDirName = new WCHAR [cchDirName]; if (NULL == pwszDirName) goto OutOfMemory; cchDirName = CertNameToStrW( X509_ASN_ENCODING, pDirNameBlob, CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, pwszDirName, cchDirName ); if (1 >= cchDirName) goto ErrorReturn; cchDirName--; // exclude trailing L'\0'
pwszHP = pwszHostPorts; while (TRUE) { DWORD cchHP; LPWSTR pwszUrl; DWORD cchUrl;
// Skip past any spaces in the HostPort
while (L' ' == *pwszHP) pwszHP++; cchHP = wcslen(pwszHP);
cchUrl = wcslen(DIR_NAME_LDAP_URL_PREFIX); cchUrl += cchHP; cchUrl += 1; // L'/'
cchUrl += cchDirName; cchUrl += wcslen(pwszSuffix); cchUrl += 1; // L'\0'
pwszUrl = new WCHAR [cchUrl]; if (NULL == pwszUrl) goto OutOfMemory;
wcscpy(pwszUrl, DIR_NAME_LDAP_URL_PREFIX); wcscat(pwszUrl, pwszHP); wcscat(pwszUrl, L"/"); wcscat(pwszUrl, pwszDirName); wcscat(pwszUrl, pwszSuffix);
fResult = pcua->AddUrl(pwszUrl, TRUE);
delete [] pwszUrl; if (!fResult) goto ErrorReturn;
pwszHP += cchHP + 1; if (L'\0' == *pwszHP) break; }
fResult = TRUE; CommonReturn: if (pwszDirName) delete [] pwszDirName; if (pwszHostPorts != pwszDefaultCDPDirNameLdapUrlHostPorts) delete [] pwszHostPorts; if (pwszSuffix != pwszDefaultCDPDirNameLdapUrlSuffix) delete [] pwszSuffix;
return fResult; ErrorReturn: fResult = FALSE; goto CommonReturn;
OutOfMemory: SetLastError( (DWORD) E_OUTOFMEMORY ); goto ErrorReturn; }
//+---------------------------------------------------------------------------
//
// Function: GetUrlArrayAndInfoFromCrlDistPoint
//
// Synopsis: get URL data using decoded CRL distribution point info
//
//----------------------------------------------------------------------------
BOOL WINAPI GetUrlArrayAndInfoFromCrlDistPoint ( IN DWORD cRawUrlData, IN PCRYPT_RAW_URL_DATA aRawUrlData, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo ) { BOOL fResult = FALSE; PCRL_DIST_POINTS_INFO pDistPointsInfo; PCRL_DIST_POINT rgDistPoint; PCRL_DIST_POINT_NAME pDistPointName; PCERT_ALT_NAME_ENTRY rgAltEntry; DWORD cRaw; DWORD cCount; DWORD cEntry; BOOL fAnyFound = FALSE; CCryptUrlArray cua( 1, 5, fResult );
for ( cRaw = 0; ( fResult == TRUE ) && ( cRaw < cRawUrlData ); cRaw++ ) { pDistPointsInfo = (PCRL_DIST_POINTS_INFO)aRawUrlData[cRaw].pvData; if ( pDistPointsInfo != NULL ) { rgDistPoint = pDistPointsInfo->rgDistPoint;
for ( cCount = 0; ( cCount < pDistPointsInfo->cDistPoint ) && ( fResult == TRUE ); cCount++ ) { // Assumption:: don't support partial reasons
// For now, will ignore CRL issuers, they might
// be the same as the cert's issuer. That was the case
// with a Netscape CDP
if (rgDistPoint[cCount].ReasonFlags.cbData) continue;
pDistPointName = &rgDistPoint[cCount].DistPointName;
if ( pDistPointName->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME ) { rgAltEntry = pDistPointName->FullName.rgAltEntry;
for ( cEntry = 0; ( fResult == TRUE ) && ( cEntry < pDistPointName->FullName.cAltEntry ); cEntry++ ) { switch (rgAltEntry[cEntry].dwAltNameChoice) { case CERT_ALT_NAME_URL: fResult = cua.AddUrl( rgAltEntry[cEntry].pwszURL, TRUE ); fAnyFound = TRUE; break; case CERT_ALT_NAME_DIRECTORY_NAME: fResult = AddUrlsFromCDPDirectoryName( &rgAltEntry[cEntry].DirectoryName, &cua ); fAnyFound = TRUE; break; default: break; } } } } } }
if ( ( fAnyFound == FALSE ) && ( fResult == TRUE ) ) { SetLastError( (DWORD) CRYPT_E_NOT_FOUND ); fResult = FALSE; }
if ( fResult == TRUE ) { PCRYPT_URL_ARRAY* ppUrlArray = NULL;
if ( pUrlArray != NULL ) { ppUrlArray = &pUrlArray; }
fResult = cua.GetArrayInSingleBufferEncodedForm( ppUrlArray, pcbUrlArray ); }
if ( ( fResult == TRUE ) && ( pcbUrlInfo != NULL ) ) { InitializeDefaultUrlInfo( pUrlInfo, pcbUrlInfo ); }
cua.FreeArray( TRUE ); return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: GetUrlArrayAndInfoFromNextUpdateLocation
//
// Synopsis: get URL data using decoded next update location data
//
//----------------------------------------------------------------------------
BOOL WINAPI GetUrlArrayAndInfoFromNextUpdateLocation ( IN DWORD cRawUrlData, IN PCRYPT_RAW_URL_DATA aRawUrlData, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo ) { BOOL fResult = FALSE; PCERT_ALT_NAME_INFO pAltNameInfo; PCERT_ALT_NAME_ENTRY rgAltEntry; DWORD cRaw; DWORD cEntry; BOOL fAnyFound = FALSE; CCryptUrlArray cua( 1, 5, fResult );
for ( cRaw = 0; ( fResult == TRUE ) && ( cRaw < cRawUrlData ); cRaw++ ) { pAltNameInfo = (PCERT_ALT_NAME_INFO)aRawUrlData[cRaw].pvData; if ( pAltNameInfo != NULL ) { rgAltEntry = pAltNameInfo->rgAltEntry;
for ( cEntry = 0; ( cEntry < pAltNameInfo->cAltEntry ) && ( fResult == TRUE ); cEntry++ ) { if ( rgAltEntry[cEntry].dwAltNameChoice == CERT_ALT_NAME_URL ) { fResult = cua.AddUrl( rgAltEntry[cEntry].pwszURL, TRUE ); fAnyFound = TRUE; } } } }
if ( ( fAnyFound == FALSE ) && ( fResult == TRUE ) ) { SetLastError( (DWORD) CRYPT_E_NOT_FOUND ); fResult = FALSE; }
if ( fResult == TRUE ) { PCRYPT_URL_ARRAY* ppUrlArray = NULL;
if ( pUrlArray != NULL ) { ppUrlArray = &pUrlArray; }
fResult = cua.GetArrayInSingleBufferEncodedForm( ppUrlArray, pcbUrlArray ); }
if ( ( fResult == TRUE ) && ( pcbUrlInfo != NULL ) ) { InitializeDefaultUrlInfo( pUrlInfo, pcbUrlInfo ); }
cua.FreeArray( TRUE ); return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: CopyUrlArray
//
// Synopsis: copy URL array
//
//----------------------------------------------------------------------------
BOOL WINAPI CopyUrlArray ( IN PCRYPT_URL_ARRAY pDest, IN PCRYPT_URL_ARRAY pSource, IN DWORD cbDest ) { DWORD cCount; DWORD cb; DWORD cbStruct; DWORD cbPointers; DWORD cbUrl;
cbStruct = sizeof( CRYPT_URL_ARRAY ); cbPointers = pSource->cUrl * sizeof( LPWSTR );
if (cbDest < (cbStruct + cbPointers)) { SetLastError( (DWORD) E_INVALIDARG ); return FALSE; }
pDest->cUrl = pSource->cUrl; pDest->rgwszUrl = (LPWSTR *)( (LPBYTE)pDest + cbStruct );
for ( cCount = 0, cb = 0; cCount < pSource->cUrl; cCount++ ) { pDest->rgwszUrl[cCount] = (LPWSTR)((LPBYTE)pDest+cbStruct+cbPointers+cb);
cbUrl = ( wcslen( pSource->rgwszUrl[cCount] ) + 1 ) * sizeof( WCHAR );
if (cbDest < (cbStruct + cbPointers + cb + cbUrl)) { SetLastError( (DWORD) E_INVALIDARG ); return FALSE; }
memcpy( pDest->rgwszUrl[cCount], pSource->rgwszUrl[cCount], cbUrl );
cb += cbUrl; }
return TRUE; }
//+---------------------------------------------------------------------------
//
// Function: GetUrlArrayIndex
//
// Synopsis: get index of an URL in the URL array
//
//----------------------------------------------------------------------------
VOID WINAPI GetUrlArrayIndex ( IN PCRYPT_URL_ARRAY pUrlArray, IN LPWSTR pwszUrl, IN DWORD DefaultIndex, OUT DWORD* pUrlIndex, OUT BOOL* pfHintInArray ) { DWORD cCount;
if ( pUrlIndex != NULL ) { *pUrlIndex = DefaultIndex; }
if ( pfHintInArray != NULL ) { *pfHintInArray = FALSE; }
if ( pwszUrl == NULL ) { return; }
for ( cCount = 0; cCount < pUrlArray->cUrl; cCount++ ) { if ( wcscmp( pUrlArray->rgwszUrl[cCount], pwszUrl ) == 0 ) { if ( pUrlIndex != NULL ) { *pUrlIndex = cCount; }
if ( pfHintInArray != NULL ) { *pfHintInArray = TRUE; }
break; } } }
//+---------------------------------------------------------------------------
//
// Function: GetUrlArrayAndInfoFromCrossCertDistPoint
//
// Synopsis: get URL data using decoded Cross Cert distribution point info
//
//----------------------------------------------------------------------------
BOOL WINAPI GetUrlArrayAndInfoFromCrossCertDistPoint ( IN DWORD cRawUrlData, IN PCRYPT_RAW_URL_DATA aRawUrlData, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo ) { BOOL fResult = FALSE; PCROSS_CERT_DIST_POINTS_INFO pDistPointsInfo; PCERT_ALT_NAME_INFO rgDistPoint; PCERT_ALT_NAME_ENTRY rgAltEntry; DWORD cRaw; DWORD cCount; DWORD cEntry; BOOL fAnyFound = FALSE; CCryptUrlArray cua( 1, 5, fResult );
DWORD dwSyncDeltaTime = 0; DWORD cMaxGroup = 0; DWORD cGroup = 0; DWORD *pcGroupEntry = NULL; DWORD cGroupEntry; DWORD cbUrlInfo;
// Get maximum number of groups
for ( cRaw = 0; cRaw < cRawUrlData; cRaw++ ) { pDistPointsInfo = (PCROSS_CERT_DIST_POINTS_INFO)aRawUrlData[cRaw].pvData; if ( pDistPointsInfo != NULL ) { cMaxGroup += pDistPointsInfo->cDistPoint; } }
if (cMaxGroup > 0) { pcGroupEntry = new DWORD [cMaxGroup]; if ( pcGroupEntry == NULL) { fResult = FALSE; SetLastError( (DWORD) E_OUTOFMEMORY ); } }
for ( cRaw = 0; ( fResult == TRUE ) && ( cRaw < cRawUrlData ); cRaw++ ) { pDistPointsInfo = (PCROSS_CERT_DIST_POINTS_INFO)aRawUrlData[cRaw].pvData; if ( pDistPointsInfo != NULL ) { if ( dwSyncDeltaTime == 0 ) { dwSyncDeltaTime = pDistPointsInfo->dwSyncDeltaTime; }
rgDistPoint = pDistPointsInfo->rgDistPoint;
for ( cCount = 0; ( cCount < pDistPointsInfo->cDistPoint ) && ( fResult == TRUE ); cCount++ ) { rgAltEntry = rgDistPoint[cCount].rgAltEntry; cGroupEntry = 0;
for ( cEntry = 0; ( fResult == TRUE ) && ( cEntry < rgDistPoint[cCount].cAltEntry ); cEntry++ ) { switch (rgAltEntry[cEntry].dwAltNameChoice) { case CERT_ALT_NAME_URL: fResult = cua.AddUrl( rgAltEntry[cEntry].pwszURL, TRUE ); fAnyFound = TRUE; cGroupEntry++; break; default: break; } }
if ( cGroupEntry > 0 ) { if (cGroup < cMaxGroup) { pcGroupEntry[cGroup] = cGroupEntry; cGroup++; } else { fResult = FALSE; SetLastError( (DWORD) E_UNEXPECTED ); } } } } }
if ( ( fAnyFound == FALSE ) && ( fResult == TRUE ) ) { SetLastError( (DWORD) CRYPT_E_NOT_FOUND ); fResult = FALSE; }
if ( fResult == TRUE ) { PCRYPT_URL_ARRAY* ppUrlArray = NULL;
if ( pUrlArray != NULL ) { ppUrlArray = &pUrlArray; }
fResult = cua.GetArrayInSingleBufferEncodedForm( ppUrlArray, pcbUrlArray ); }
if ( ( fResult == TRUE ) && ( pcbUrlInfo != NULL ) ) { cbUrlInfo = sizeof( CRYPT_URL_INFO ) + cGroup * sizeof(DWORD); if ( pUrlInfo != NULL ) { if (*pcbUrlInfo < cbUrlInfo) { fResult = FALSE; SetLastError( (DWORD) E_INVALIDARG ); } else { pUrlInfo->cbSize = sizeof( CRYPT_URL_INFO ); pUrlInfo->dwSyncDeltaTime = dwSyncDeltaTime; pUrlInfo->cGroup = cGroup;
if ( cGroup > 0 ) { pUrlInfo->rgcGroupEntry = (DWORD *) &pUrlInfo[ 1 ]; memcpy(pUrlInfo->rgcGroupEntry, pcGroupEntry, cGroup * sizeof(DWORD)); } else { pUrlInfo->rgcGroupEntry = NULL; } } } *pcbUrlInfo = cbUrlInfo; }
cua.FreeArray( TRUE ); if (pcGroupEntry) { delete [] pcGroupEntry; } return( fResult ); }
//+---------------------------------------------------------------------------
//
// Function: CertificateCrossCertDistPointGetObjectUrl
//
// Synopsis: get certificate cross certificate URL
//
//----------------------------------------------------------------------------
BOOL WINAPI CertificateCrossCertDistPointGetObjectUrl( IN LPCSTR pszUrlOid, IN LPVOID pvPara, IN DWORD dwFlags, OUT OPTIONAL PCRYPT_URL_ARRAY pUrlArray, IN OUT DWORD* pcbUrlArray, OUT OPTIONAL PCRYPT_URL_INFO pUrlInfo, IN OUT OPTIONAL DWORD* pcbUrlInfo, IN LPVOID pvReserved ) { BOOL fResult = FALSE; CRYPT_RAW_URL_DATA RawData[MAX_RAW_URL_DATA]; ULONG cRawData = MAX_RAW_URL_DATA;
fResult = ObjectContextGetRawUrlData( CONTEXT_OID_CERTIFICATE, pvPara, (DWORD) -1L, // Index
dwFlags, szOID_CROSS_CERT_DIST_POINTS, RawData, &cRawData );
if ( fResult == TRUE ) { fResult = GetUrlArrayAndInfoFromCrossCertDistPoint( cRawData, RawData, pUrlArray, pcbUrlArray, pUrlInfo, pcbUrlInfo );
ObjectContextFreeRawUrlData( cRawData, RawData ); }
return( fResult ); }
|