Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

11913 lines
319 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: frmtfunc.cpp
//
// Contents: OID format functions
//
// Functions: CryptFrmtFuncDllMain
// CryptFormatObject
// CryptQueryObject
//
// History: 15-05-97 xiaohs created
// 27 Oct 1999 dsie add post win2k features.
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
#include "frmtfunc.h"
HMODULE hFrmtFuncInst;
static HCRYPTOIDFUNCSET hFormatFuncSet;
//function type define
typedef BOOL (WINAPI *PFN_FORMAT_FUNC)(
IN DWORD dwCertEncodingType,
IN DWORD dwFormatType,
IN DWORD dwFormatStrType,
IN void *pFormatStruct,
IN LPCSTR lpszStructType,
IN const BYTE *pbEncoded,
IN DWORD cbEncoded,
OUT void *pbFormat,
IN OUT DWORD *pcbFormat
);
static BOOL
WINAPI
FormatBytesToHex(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
CryptDllFormatAttr(
DWORD dwEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pBuffer,
DWORD *pcBuffer);
static BOOL
WINAPI
CryptDllFormatName(
DWORD dwEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbBuffer,
DWORD *pcbBuffer);
static BOOL
WINAPI
FormatBasicConstraints2(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatBasicConstraints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCRLReasonCode(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatEnhancedKeyUsage(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAltName(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAuthorityKeyID(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAuthorityKeyID2(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatNextUpdateLocation(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatSubjectKeyID(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatFinancialCriteria(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatSMIMECapabilities(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatKeyUsage(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAuthortiyInfoAccess(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatKeyAttributes(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatKeyRestriction(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCRLDistPoints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCertPolicies(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCAVersion(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAnyUnicodeStringExtension(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatAnyNameValueStringAttr(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatNetscapeCertType(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatSPAgencyInfo(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
//
// DSIE: Post Win2K.
//
static BOOL
WINAPI
FormatCrlNumber (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCrlNextPublish (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatIssuingDistPoint (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatNameConstraints (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCertSrvPreviousCertHash (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatPolicyMappings (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatPolicyConstraints (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatCertificateTemplate (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static BOOL
WINAPI
FormatXCertDistPoints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat);
static const CRYPT_OID_FUNC_ENTRY DefaultFormatTable[] = {
CRYPT_DEFAULT_OID, FormatBytesToHex};
static const CRYPT_OID_FUNC_ENTRY OIDFormatTable[] = {
szOID_COMMON_NAME, CryptDllFormatAttr,
szOID_SUR_NAME, CryptDllFormatAttr,
szOID_DEVICE_SERIAL_NUMBER, CryptDllFormatAttr,
szOID_COUNTRY_NAME, CryptDllFormatAttr,
szOID_LOCALITY_NAME, CryptDllFormatAttr,
szOID_STATE_OR_PROVINCE_NAME, CryptDllFormatAttr,
szOID_STREET_ADDRESS, CryptDllFormatAttr,
szOID_ORGANIZATION_NAME, CryptDllFormatAttr,
szOID_ORGANIZATIONAL_UNIT_NAME, CryptDllFormatAttr,
szOID_TITLE, CryptDllFormatAttr,
szOID_DESCRIPTION, CryptDllFormatAttr,
szOID_SEARCH_GUIDE, CryptDllFormatAttr,
szOID_BUSINESS_CATEGORY, CryptDllFormatAttr,
szOID_POSTAL_ADDRESS, CryptDllFormatAttr,
szOID_POSTAL_CODE, CryptDllFormatAttr,
szOID_POST_OFFICE_BOX, CryptDllFormatAttr,
szOID_PHYSICAL_DELIVERY_OFFICE_NAME, CryptDllFormatAttr,
szOID_TELEPHONE_NUMBER, CryptDllFormatAttr,
szOID_TELEX_NUMBER, CryptDllFormatAttr,
szOID_TELETEXT_TERMINAL_IDENTIFIER, CryptDllFormatAttr,
szOID_FACSIMILE_TELEPHONE_NUMBER, CryptDllFormatAttr,
szOID_X21_ADDRESS, CryptDllFormatAttr,
szOID_INTERNATIONAL_ISDN_NUMBER, CryptDllFormatAttr,
szOID_REGISTERED_ADDRESS, CryptDllFormatAttr,
szOID_DESTINATION_INDICATOR, CryptDllFormatAttr,
szOID_PREFERRED_DELIVERY_METHOD, CryptDllFormatAttr,
szOID_PRESENTATION_ADDRESS, CryptDllFormatAttr,
szOID_SUPPORTED_APPLICATION_CONTEXT, CryptDllFormatAttr,
szOID_MEMBER, CryptDllFormatAttr,
szOID_OWNER, CryptDllFormatAttr,
szOID_ROLE_OCCUPANT, CryptDllFormatAttr,
szOID_SEE_ALSO, CryptDllFormatAttr,
szOID_USER_PASSWORD, CryptDllFormatAttr,
szOID_USER_CERTIFICATE, CryptDllFormatAttr,
szOID_CA_CERTIFICATE, CryptDllFormatAttr,
szOID_AUTHORITY_REVOCATION_LIST, CryptDllFormatAttr,
szOID_CERTIFICATE_REVOCATION_LIST, CryptDllFormatAttr,
szOID_CROSS_CERTIFICATE_PAIR, CryptDllFormatAttr,
szOID_GIVEN_NAME, CryptDllFormatAttr,
szOID_INITIALS, CryptDllFormatAttr,
szOID_DOMAIN_COMPONENT, CryptDllFormatAttr,
szOID_PKCS_12_FRIENDLY_NAME_ATTR, CryptDllFormatAttr,
szOID_PKCS_12_LOCAL_KEY_ID, CryptDllFormatAttr,
X509_NAME, CryptDllFormatName,
X509_UNICODE_NAME, CryptDllFormatName,
szOID_BASIC_CONSTRAINTS2, FormatBasicConstraints2,
X509_BASIC_CONSTRAINTS2, FormatBasicConstraints2,
szOID_BASIC_CONSTRAINTS, FormatBasicConstraints,
X509_BASIC_CONSTRAINTS, FormatBasicConstraints,
szOID_CRL_REASON_CODE, FormatCRLReasonCode,
X509_CRL_REASON_CODE, FormatCRLReasonCode,
szOID_ENHANCED_KEY_USAGE, FormatEnhancedKeyUsage,
X509_ENHANCED_KEY_USAGE, FormatEnhancedKeyUsage,
szOID_SUBJECT_ALT_NAME, FormatAltName,
szOID_ISSUER_ALT_NAME, FormatAltName,
szOID_SUBJECT_ALT_NAME2, FormatAltName,
szOID_ISSUER_ALT_NAME2, FormatAltName,
X509_ALTERNATE_NAME, FormatAltName,
szOID_AUTHORITY_KEY_IDENTIFIER, FormatAuthorityKeyID,
X509_AUTHORITY_KEY_ID, FormatAuthorityKeyID,
szOID_AUTHORITY_KEY_IDENTIFIER2, FormatAuthorityKeyID2,
X509_AUTHORITY_KEY_ID2, FormatAuthorityKeyID2,
szOID_NEXT_UPDATE_LOCATION, FormatNextUpdateLocation,
szOID_SUBJECT_KEY_IDENTIFIER, FormatSubjectKeyID,
SPC_FINANCIAL_CRITERIA_OBJID, FormatFinancialCriteria,
SPC_FINANCIAL_CRITERIA_STRUCT, FormatFinancialCriteria,
szOID_RSA_SMIMECapabilities, FormatSMIMECapabilities,
PKCS_SMIME_CAPABILITIES, FormatSMIMECapabilities,
szOID_KEY_USAGE, FormatKeyUsage,
X509_KEY_USAGE, FormatKeyUsage,
szOID_AUTHORITY_INFO_ACCESS, FormatAuthortiyInfoAccess,
X509_AUTHORITY_INFO_ACCESS, FormatAuthortiyInfoAccess,
szOID_KEY_ATTRIBUTES, FormatKeyAttributes,
X509_KEY_ATTRIBUTES, FormatKeyAttributes,
szOID_KEY_USAGE_RESTRICTION, FormatKeyRestriction,
X509_KEY_USAGE_RESTRICTION, FormatKeyRestriction,
szOID_CRL_DIST_POINTS, FormatCRLDistPoints,
X509_CRL_DIST_POINTS, FormatCRLDistPoints,
szOID_FRESHEST_CRL, FormatCRLDistPoints, // Post Win2K
szOID_CERT_POLICIES, FormatCertPolicies,
X509_CERT_POLICIES, FormatCertPolicies,
szOID_ENROLL_CERTTYPE_EXTENSION, FormatAnyUnicodeStringExtension,
szOID_OS_VERSION, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_CERT_TYPE, FormatNetscapeCertType,
szOID_NETSCAPE_BASE_URL, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_REVOCATION_URL, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_CA_REVOCATION_URL, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_CERT_RENEWAL_URL, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_CA_POLICY_URL, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_SSL_SERVER_NAME, FormatAnyUnicodeStringExtension,
szOID_NETSCAPE_COMMENT, FormatAnyUnicodeStringExtension,
szOID_ENROLLMENT_NAME_VALUE_PAIR, FormatAnyNameValueStringAttr,
szOID_CERTSRV_CA_VERSION, FormatCAVersion,
SPC_SP_AGENCY_INFO_OBJID, FormatSPAgencyInfo,
SPC_SP_AGENCY_INFO_STRUCT, FormatSPAgencyInfo,
// Post Win2K
szOID_CRL_NUMBER, FormatCrlNumber,
szOID_DELTA_CRL_INDICATOR, FormatCrlNumber,
szOID_CRL_VIRTUAL_BASE, FormatCrlNumber,
szOID_CRL_NEXT_PUBLISH, FormatCrlNextPublish,
szOID_ISSUING_DIST_POINT, FormatIssuingDistPoint,
X509_ISSUING_DIST_POINT, FormatIssuingDistPoint,
szOID_NAME_CONSTRAINTS, FormatNameConstraints,
X509_NAME_CONSTRAINTS, FormatNameConstraints,
szOID_CERTSRV_PREVIOUS_CERT_HASH, FormatCertSrvPreviousCertHash,
szOID_APPLICATION_CERT_POLICIES, FormatCertPolicies,
X509_POLICY_MAPPINGS, FormatPolicyMappings,
szOID_POLICY_MAPPINGS, FormatPolicyMappings,
szOID_APPLICATION_POLICY_MAPPINGS, FormatPolicyMappings,
X509_POLICY_CONSTRAINTS, FormatPolicyConstraints,
szOID_POLICY_CONSTRAINTS, FormatPolicyConstraints,
szOID_APPLICATION_POLICY_CONSTRAINTS, FormatPolicyConstraints,
X509_CERTIFICATE_TEMPLATE, FormatCertificateTemplate,
szOID_CERTIFICATE_TEMPLATE, FormatCertificateTemplate,
szOID_CRL_SELF_CDP, FormatCRLDistPoints,
X509_CROSS_CERT_DIST_POINTS, FormatXCertDistPoints,
szOID_CROSS_CERT_DIST_POINTS, FormatXCertDistPoints,
};
DWORD dwOIDFormatCount = sizeof(OIDFormatTable) / sizeof(OIDFormatTable[0]);
//+-------------------------------------------------------------------------
// Dll initialization
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptFrmtFuncDllMain(
HMODULE hModule,
DWORD fdwReason,
LPVOID lpReserved)
{
BOOL fRet;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
hFrmtFuncInst = hModule;
if (NULL == (hFormatFuncSet = CryptInitOIDFunctionSet(
CRYPT_OID_FORMAT_OBJECT_FUNC,
0))) // dwFlags
goto CryptInitFrmtFuncError;
//install the default formatting routine
if (!CryptInstallOIDFunctionAddress(
NULL, // hModule
X509_ASN_ENCODING,
CRYPT_OID_FORMAT_OBJECT_FUNC,
1,
DefaultFormatTable,
0)) // dwFlags
goto CryptInstallFrmtFuncError;
//install the OID formatting routine
if (!CryptInstallOIDFunctionAddress(
NULL, // hModule
X509_ASN_ENCODING,
CRYPT_OID_FORMAT_OBJECT_FUNC,
dwOIDFormatCount,
OIDFormatTable,
0)) // dwFlags
goto CryptInstallFrmtFuncError;
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
default:
break;
}
fRet = TRUE;
CommonReturn:
return fRet;
ErrorReturn:
fRet = FALSE;
goto CommonReturn;
TRACE_ERROR(CryptInitFrmtFuncError)
TRACE_ERROR(CryptInstallFrmtFuncError)
}
//------------------------------------------------------------------------
// Convert the byte to its Hex presentation.
//
// Precondition: byte is less than 15
//
//------------------------------------------------------------------------
ULONG ByteToHex(BYTE byte, LPWSTR wszZero, LPWSTR wszA)
{
ULONG uValue=0;
if(((ULONG)byte)<=9)
{
uValue=((ULONG)byte)+ULONG(*wszZero);
}
else
{
uValue=(ULONG)byte-10+ULONG(*wszA);
}
return uValue;
}
//--------------------------------------------------------------------------
//
// Format the encoded bytes into a hex string in the format of
// xxxx xxxx xxxx xxxx ...
//
// DSIE 6/28/2000: change format to xx xx xx xx, per VicH's request.
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatBytesToHex(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszBuffer=NULL;
DWORD dwBufferSize=0;
DWORD dwBufferIndex=0;
DWORD dwEncodedIndex=0;
WCHAR wszSpace[CHAR_SIZE];
WCHAR wszZero[CHAR_SIZE];
WCHAR wszA[CHAR_SIZE];
WCHAR wszHex[HEX_SIZE];
//check for input parameters
if(( pbEncoded!=NULL && cbEncoded==0)
||(pbEncoded==NULL && cbEncoded!=0)
|| (pcbFormat==NULL))
{
SetLastError((DWORD) E_INVALIDARG);
return FALSE;
}
#if (0) // DSIE: Fix bug 128630.
//check for simple case. No work needed
if(pbEncoded==NULL && cbEncoded==0)
{
*pcbFormat=0;
return TRUE;
}
#endif
//calculate the memory needed, in bytes
//we need 3 wchars per byte, along with the NULL terminator
dwBufferSize=sizeof(WCHAR)*(cbEncoded*3+1);
//length only calculation
if(pcbFormat!=NULL && pbFormat==NULL)
{
*pcbFormat=dwBufferSize;
return TRUE;
}
//load the string
if(!LoadStringU(hFrmtFuncInst, IDS_FRMT_SPACE, wszSpace,
CHAR_SIZE)
||!LoadStringU(hFrmtFuncInst, IDS_FRMT_ZERO, wszZero,
CHAR_SIZE)
||!LoadStringU(hFrmtFuncInst, IDS_FRMT_A, wszA,
CHAR_SIZE)
||!LoadStringU(hFrmtFuncInst, IDS_FRMT_HEX, wszHex,
HEX_SIZE)
)
{
SetLastError((DWORD) E_UNEXPECTED);
return FALSE;
}
pwszBuffer=(LPWSTR)malloc(dwBufferSize);
if(!pwszBuffer)
{
SetLastError((DWORD) E_OUTOFMEMORY);
return FALSE;
}
dwBufferIndex=0;
//format the wchar buffer one byte at a time
for(dwEncodedIndex=0; dwEncodedIndex<cbEncoded; dwEncodedIndex++)
{
#if (0) // DSIE:
//copy the space between every two bytes. Skip for the 1st byte
if((0!=dwEncodedIndex) && (0==(dwEncodedIndex % 2)))
#else
//copy the space between every byte. Skip for the 1st byte
if(dwEncodedIndex != 0)
#endif
{
pwszBuffer[dwBufferIndex]=wszSpace[0];
dwBufferIndex++;
}
//format the higher 4 bits
pwszBuffer[dwBufferIndex]=(WCHAR)ByteToHex(
(BYTE)( (pbEncoded[dwEncodedIndex]&UPPER_BITS)>>4 ),
wszZero, wszA);
dwBufferIndex++;
//format the lower 4 bits
pwszBuffer[dwBufferIndex]=(WCHAR)ByteToHex(
(BYTE)( pbEncoded[dwEncodedIndex]&LOWER_BITS ),
wszZero, wszA);
dwBufferIndex++;
}
//add the NULL terminator to the string
pwszBuffer[dwBufferIndex]=wszSpace[1];
//calculate the real size for the buffer
dwBufferSize=sizeof(WCHAR)*(wcslen(pwszBuffer)+1);
//copy the buffer
memcpy(pbFormat, pwszBuffer,
(*pcbFormat>=dwBufferSize) ? dwBufferSize : *pcbFormat);
free(pwszBuffer);
//make sure the user has supplied enough memory
if(*pcbFormat < dwBufferSize)
{
*pcbFormat=dwBufferSize;
SetLastError((DWORD) ERROR_MORE_DATA);
return FALSE;
}
*pcbFormat=dwBufferSize;
return TRUE;
}
//+-----------------------------------------------------------------------------
//
// AllocateAnsiToUnicode
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
AllocateAnsiToUnicode(
LPCSTR pszAnsi,
LPWSTR * ppwszUnicode)
{
BOOL fResult = FALSE;
LPWSTR pwszUnicode = NULL;
DWORD dwWideSize = 0;
if (!ppwszUnicode)
{
goto InvalidArg;
}
*ppwszUnicode = NULL;
if (!pszAnsi)
{
return TRUE;
}
if (!(dwWideSize = MultiByteToWideChar(CP_ACP,
0,
pszAnsi,
strlen(pszAnsi),
NULL,
0)))
{
goto szTOwszError;
}
//
// Allocate memory, including the NULL terminator.
//
if (!(pwszUnicode = (WCHAR *) malloc(sizeof(WCHAR) * (dwWideSize + 1))))
{
goto MemoryError;
}
memset(pwszUnicode, 0, sizeof(WCHAR) * (dwWideSize + 1));
if (!MultiByteToWideChar(CP_ACP,
0,
pszAnsi,
strlen(pszAnsi),
pwszUnicode,
dwWideSize))
{
free(pwszUnicode);
goto szTOwszError;
}
*ppwszUnicode = pwszUnicode;
fResult = TRUE;
CommonReturn:
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(szTOwszError);
}
//+-----------------------------------------------------------------------------
//
// FormatObjectId
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatObjectId (
LPSTR pszObjId,
DWORD dwGroupId,
BOOL bMultiLines,
LPWSTR * ppwszFormat)
{
BOOL fResult;
PCCRYPT_OID_INFO pOIDInfo = NULL;
LPWSTR pwszObjId = NULL;
//
// Initialize.
//
*ppwszFormat = NULL;
//
// Convert OID to Unicode.
//
if (!AllocateAnsiToUnicode(pszObjId, &pwszObjId))
{
goto AnsiToUnicodeError;
}
//
// Find OID info.
//
if (pOIDInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
(void *) pszObjId,
dwGroupId))
{
//
// "%1!s!(%2!s!)%3!s!"
//
if (!FormatMessageUnicode(ppwszFormat,
IDS_GENERIC_OBJECT_ID,
pOIDInfo->pwszName,
pwszObjId,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
}
else
{
//
// "%1!s!%2!s!"
//
if (!FormatMessageUnicode(ppwszFormat,
IDS_STRING,
pwszObjId,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
}
fResult = TRUE;
CommonReturn:
if (pwszObjId)
{
free(pwszObjId);
}
return fResult;
ErrorReturn:
fResult = FALSE;
goto CommonReturn;
TRACE_ERROR(AnsiToUnicodeError);
TRACE_ERROR(FormatMessageError);
}
//+-----------------------------------------------------------------------------
//
// FormatIPAddress
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatIPAddress(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
UINT idsPrefix,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
LPWSTR pwszFormat = NULL;
WCHAR wszPrefix[PRE_FIX_SIZE] = wszEMPTY;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Check for input parameters.
//
if ((pbEncoded!=NULL && cbEncoded==0) ||
(pbEncoded==NULL && cbEncoded!=0) ||
(pcbFormat==NULL))
{
goto InvalidArg;
}
if (bMultiLines && idsPrefix)
{
if(!LoadStringU(hFrmtFuncInst,
idsPrefix,
wszPrefix,
sizeof(wszPrefix) / sizeof(wszPrefix[0])))
{
goto LoadStringError;
}
}
switch (cbEncoded)
{
case 4:
{
//
// "%1!d!.%2!d!.%3!d!.%4!d!"
//
if (!FormatMessageUnicode(&pwszFormat,
IDS_IPADDRESS_V4_4,
(DWORD) pbEncoded[0],
(DWORD) pbEncoded[1],
(DWORD) pbEncoded[2],
(DWORD) pbEncoded[3]))
{
goto FormatMessageError;
}
break;
}
case 8:
{
//
// "%1!d!.%2!d!.%3!d!.%4!d!%5!s!%6!s!Mask=%7!d!.%8!d!.%9!d!.%10!d!"
//
if (!FormatMessageUnicode(&pwszFormat,
IDS_IPADDRESS_V4_8,
(DWORD) pbEncoded[0],
(DWORD) pbEncoded[1],
(DWORD) pbEncoded[2],
(DWORD) pbEncoded[3],
bMultiLines ? wszCRLF : wszEMPTY,
bMultiLines ? wszPrefix : wszCOMMA,
(DWORD) pbEncoded[4],
(DWORD) pbEncoded[5],
(DWORD) pbEncoded[6],
(DWORD) pbEncoded[7]))
{
goto FormatMessageError;
}
break;
}
case 16:
{
//
// "%1!02x!%2!02x!:%3!02x!%4!02x!:%5!02x!%6!02x!:%7!02x!%8!02x!:%9!02x!%10!02x!:%11!02x!%12!02x!:%13!02x!%14!02x!:%15!02x!%16!02x!"
//
if (!FormatMessageUnicode(&pwszFormat,
IDS_IPADDRESS_V6_16,
(DWORD) pbEncoded[0],
(DWORD) pbEncoded[1],
(DWORD) pbEncoded[2],
(DWORD) pbEncoded[3],
(DWORD) pbEncoded[4],
(DWORD) pbEncoded[5],
(DWORD) pbEncoded[6],
(DWORD) pbEncoded[7],
(DWORD) pbEncoded[8],
(DWORD) pbEncoded[9],
(DWORD) pbEncoded[10],
(DWORD) pbEncoded[11],
(DWORD) pbEncoded[12],
(DWORD) pbEncoded[13],
(DWORD) pbEncoded[14],
(DWORD) pbEncoded[15]))
{
goto FormatMessageError;
}
break;
}
case 32:
{
//
// "%1!02x!%2!02x!:%3!02x!%4!02x!:%5!02x!%6!02x!:%7!02x!%8!02x!:%9!02x!%10!02x!:%11!02x!%12!02x!:%13!02x!%14!02x!:%15!02x!%16!02x!%17!s!%18!s!
// Mask=%19!02x!%20!02x!:%21!02x!%22!02x!:%23!02x!%24!02x!:%25!02x!%26!02x!:%27!02x!%28!02x!:%29!02x!%30!02x!:%31!02x!%32!02x!:%33!02x!%34!02x!"
//
if (!FormatMessageUnicode(&pwszFormat,
IDS_IPADDRESS_V6_32,
(DWORD) pbEncoded[0],
(DWORD) pbEncoded[1],
(DWORD) pbEncoded[2],
(DWORD) pbEncoded[3],
(DWORD) pbEncoded[4],
(DWORD) pbEncoded[5],
(DWORD) pbEncoded[6],
(DWORD) pbEncoded[7],
(DWORD) pbEncoded[8],
(DWORD) pbEncoded[9],
(DWORD) pbEncoded[10],
(DWORD) pbEncoded[11],
(DWORD) pbEncoded[12],
(DWORD) pbEncoded[13],
(DWORD) pbEncoded[14],
(DWORD) pbEncoded[15],
bMultiLines ? wszCRLF : wszEMPTY,
bMultiLines ? wszPrefix : wszCOMMA,
(DWORD) pbEncoded[16],
(DWORD) pbEncoded[17],
(DWORD) pbEncoded[18],
(DWORD) pbEncoded[19],
(DWORD) pbEncoded[20],
(DWORD) pbEncoded[21],
(DWORD) pbEncoded[22],
(DWORD) pbEncoded[23],
(DWORD) pbEncoded[24],
(DWORD) pbEncoded[25],
(DWORD) pbEncoded[26],
(DWORD) pbEncoded[27],
(DWORD) pbEncoded[28],
(DWORD) pbEncoded[29],
(DWORD) pbEncoded[30],
(DWORD) pbEncoded[31]))
{
goto FormatMessageError;
}
break;
}
default:
{
if (!(fResult = FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pbEncoded,
cbEncoded,
pbFormat,
pcbFormat)))
{
goto FormatBytesToHexError;
}
goto CommonReturn;
}
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// Length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pwszFormat)
{
LocalFree((HLOCAL) pwszFormat);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatMessageError);
TRACE_ERROR(FormatBytesToHexError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-------------------------------------------------------------------------
// format the specified data structure according to the certificate
// encoding type.
//--------------------------------------------------------------------------
BOOL
WINAPI
CryptFormatObject(
IN DWORD dwCertEncodingType,
IN DWORD dwFormatType,
IN DWORD dwFormatStrType,
IN void *pFormatStruct,
IN LPCSTR lpszStructType,
IN const BYTE *pbEncoded,
IN DWORD cbEncoded,
OUT void *pbFormat,
IN OUT DWORD *pcbFormat
)
{
BOOL fResult=FALSE;
void *pvFuncAddr;
HCRYPTOIDFUNCADDR hFuncAddr;
if (CryptGetOIDFunctionAddress(
hFormatFuncSet,
dwCertEncodingType,
lpszStructType,
0, // dwFlags
&pvFuncAddr,
&hFuncAddr))
{
fResult = ((PFN_FORMAT_FUNC) pvFuncAddr)(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pbEncoded,
cbEncoded,
pbFormat,
pcbFormat
);
CryptFreeOIDFunctionAddress(hFuncAddr, 0);
}
else
{
//do not call the default hex dump if CRYPT_FORMAT_STR_NO_HEX is set
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_NO_HEX))
{
//call the default routine automatically
if (CryptGetOIDFunctionAddress(
hFormatFuncSet,
dwCertEncodingType,
CRYPT_DEFAULT_OID,
0, // dwFlags
&pvFuncAddr,
&hFuncAddr))
{
fResult = ((PFN_FORMAT_FUNC) pvFuncAddr)(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pbEncoded,
cbEncoded,
pbFormat,
pcbFormat);
CryptFreeOIDFunctionAddress(hFuncAddr, 0);
}
else
{
*pcbFormat = 0;
fResult = FALSE;
}
}
else
{
*pcbFormat = 0;
fResult = FALSE;
}
}
return fResult;
}
//-----------------------------------------------------------
//
// This is the actual format routine for an particular RDN attribute.
//
// lpszStructType is any OID for CERT_RDN_ATTR. pbEncoded is
// an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
// *pcbBuffer return the size of memory to be allocated in bytes.
// Please notice the string is not NULL terminated.
//
// For example, to ask for an unicode string of common name,
// pass lpszStructType=szOID_COMMON_NAME,
// pass dwFormatType==CRYPT_FORMAT_SIMPL,
// pBuffer will be set the L"[email protected]".
//
//
//-------------------------------------------------------------
static BOOL WINAPI CryptDllFormatAttr(
DWORD dwEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pBuffer,
DWORD *pcbBuffer)
{
BOOL fResult=FALSE;
WCHAR *pwszSeperator=NULL;
BOOL fHeader=FALSE;
BOOL flengthOnly=FALSE;
DWORD dwBufferCount=0;
DWORD dwBufferLimit=0;
DWORD dwBufferIncrement=0;
DWORD dwSeperator=0;
DWORD dwHeader=0;
DWORD dwOIDSize=0;
WCHAR *pwszBuffer=NULL;
WCHAR *pwszHeader=NULL;
BOOL fAddSeperator=FALSE;
DWORD cbStructInfo=0;
CERT_NAME_INFO *pStructInfo=NULL;
DWORD dwRDNIndex=0;
DWORD dwAttrIndex=0;
DWORD dwAttrCount=0;
CERT_RDN_ATTR *pCertRDNAttr=NULL;
PCCRYPT_OID_INFO pOIDInfo=NULL;
LPWSTR pwszTemp;
//check input parameters
if(lpszStructType==NULL ||
(pbEncoded==NULL && cbEncoded!=0) ||
pcbBuffer==NULL
)
goto InvalidArg;
if(cbEncoded==0)
{
*pcbBuffer=0;
goto InvalidArg;
}
//get the seperator of the attributes
//wszCOMMA is the default seperator
if(dwFormatType & CRYPT_FORMAT_COMMA)
pwszSeperator=wszCOMMA;
else
{
if(dwFormatType & CRYPT_FORMAT_SEMICOLON)
pwszSeperator=wszSEMICOLON;
else
{
if(dwFormatType & CRYPT_FORMAT_CRLF)
pwszSeperator=wszCRLF;
else
{
pwszSeperator=wszPLUS;
}
}
}
//calculate the length of the seperator
dwSeperator=wcslen(pwszSeperator)*sizeof(WCHAR);
//check the requirement for the header
if(dwFormatType & CRYPT_FORMAT_X509 ||
dwFormatType & CRYPT_FORMAT_OID)
{
fHeader=TRUE;
}
if(NULL==pBuffer)
flengthOnly=TRUE;
//decode the X509_UNICODE_NAME
if(!CryptDecodeObject(dwEncodingType, X509_UNICODE_NAME,
pbEncoded, cbEncoded, CRYPT_DECODE_NOCOPY_FLAG,
NULL, &cbStructInfo))
goto DecodeError;
//allocate memory
pStructInfo=(CERT_NAME_INFO *)malloc(cbStructInfo);
if(!pStructInfo)
goto MemoryError;
//decode the struct
if(!CryptDecodeObject(dwEncodingType, X509_UNICODE_NAME,
pbEncoded, cbEncoded, CRYPT_DECODE_NOCOPY_FLAG,
pStructInfo, &cbStructInfo))
goto DecodeError;
//allocate the buffer for formatting
if(!flengthOnly)
{
pwszBuffer=(WCHAR *)malloc(g_AllocateSize);
if(!pwszBuffer)
goto MemoryError;
dwBufferLimit=g_AllocateSize;
}
//search for the OID requested. If found one, put it
//to the buffer. If no requested attribut is found,
//return.
for(dwRDNIndex=0; dwRDNIndex<pStructInfo->cRDN; dwRDNIndex++)
{
//the following line is for code optimization
dwAttrCount=(pStructInfo->rgRDN)[dwRDNIndex].cRDNAttr;
for(dwAttrIndex=0; dwAttrIndex<dwAttrCount; dwAttrIndex++)
{
//look for the specific OIDs in the function
if(_stricmp(lpszStructType,
(pStructInfo->rgRDN)[dwRDNIndex].rgRDNAttr[dwAttrIndex].pszObjId)==0)
{
pCertRDNAttr=&((pStructInfo->rgRDN)[dwRDNIndex].rgRDNAttr[dwAttrIndex]);
//init the dwBufferIncrement
dwBufferIncrement=0;
//get the header of the tag
if(fHeader)
{
if(dwFormatType & CRYPT_FORMAT_X509)
{
//get the OID's name
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
(void *)lpszStructType,
CRYPT_RDN_ATTR_OID_GROUP_ID);
if(pOIDInfo)
{
//allocate memory, including the NULL terminator
pwszHeader=(WCHAR *)malloc((wcslen(pOIDInfo->pwszName)+wcslen(wszEQUAL)+1)*
sizeof(WCHAR));
if(!pwszHeader)
goto MemoryError;
wcscpy(pwszHeader,pOIDInfo->pwszName);
}
}
//use the OID is no mapping is found or
//OID is requested in the header
if(pwszHeader==NULL)
{
//get the wide character string to the OID
if(!(dwOIDSize=MultiByteToWideChar(CP_ACP,0,
lpszStructType,strlen(lpszStructType),NULL,0)))
goto szTOwszError;
//allocate memory, including the NULL terminator
pwszHeader=(WCHAR *)malloc((dwOIDSize+wcslen(wszEQUAL)+1)*
sizeof(WCHAR));
if(!pwszHeader)
goto MemoryError;
if(!(dwHeader=MultiByteToWideChar(CP_ACP,0,
lpszStructType,strlen(lpszStructType),pwszHeader,dwOIDSize)))
goto szTOwszError;
//NULL terminate the string
*(pwszHeader+dwHeader)=L'\0';
}
//add the euqal sign
wcscat(pwszHeader, wszEQUAL);
//get the header size, in bytes, excluding the NULL terminator
dwHeader=wcslen(pwszHeader)*sizeof(WCHAR);
dwBufferIncrement+=dwHeader;
}
//allocate enough memory. Including the NULL terminator
dwBufferIncrement+=pCertRDNAttr->Value.cbData;
dwBufferIncrement+=dwSeperator;
dwBufferIncrement+=2;
if(!flengthOnly && ((dwBufferCount+dwBufferIncrement)>dwBufferLimit))
{
//reallocate the memory
#if (0) // DSIE: Bug 27436
pwszBuffer=(WCHAR *)realloc(pwszBuffer,
max(dwBufferLimit+g_AllocateSize,
dwBufferLimit+dwBufferIncrement));
if(!pwszBuffer)
goto MemoryError;
#endif
pwszTemp=(WCHAR *)realloc(pwszBuffer,
max(dwBufferLimit+g_AllocateSize,
dwBufferLimit+dwBufferIncrement));
if(!pwszTemp)
goto MemoryError;
pwszBuffer = pwszTemp;
dwBufferLimit+=max(g_AllocateSize,dwBufferIncrement);
}
//add the header if necessary
if(fHeader)
{
if(!flengthOnly)
{
memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
pwszHeader,dwHeader);
}
dwBufferCount+=dwHeader;
//do not need to do header anymore
fHeader=FALSE;
}
//add the seperator after the 1st iteration
if(fAddSeperator)
{
if(!flengthOnly)
{
memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
pwszSeperator,dwSeperator);
}
dwBufferCount+=dwSeperator;
}
else
fAddSeperator=TRUE;
//add the attr content
if(!flengthOnly)
{
memcpy((BYTE *)(pwszBuffer+dwBufferCount/sizeof(WCHAR)),
(pCertRDNAttr->Value.pbData),
pCertRDNAttr->Value.cbData);
}
//increment the buffercount
dwBufferCount+=pCertRDNAttr->Value.cbData;
}
}
}
//return the result as requested
//check if the requested OID is actually in the DN
if(0==dwBufferCount)
{
*pcbBuffer=dwBufferCount;
goto NotFoundError;
}
//we need to NULL terminate the string
if(!flengthOnly)
*(pwszBuffer+dwBufferCount/sizeof(WCHAR))=L'\0';
dwBufferCount+=2;
if(pBuffer==NULL)
{
*pcbBuffer=dwBufferCount;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbBuffer)<dwBufferCount)
{
*pcbBuffer=dwBufferCount;
goto MoreDataError;
}
*pcbBuffer=dwBufferCount;
memcpy(pBuffer, pwszBuffer,dwBufferCount);
fResult=TRUE;
CommonReturn:
if(pwszHeader)
free(pwszHeader);
if(pwszBuffer)
free(pwszBuffer);
if(pStructInfo)
free(pStructInfo);
return fResult;
ErrorReturn:
fResult = FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(DecodeError);
TRACE_ERROR(szTOwszError);
SET_ERROR(NotFoundError, E_FAIL);
SET_ERROR(MoreDataError, ERROR_MORE_DATA);
}
//-----------------------------------------------------------
//
// This is the actual format routine for an complete CERT_NAME
//
//
// lpszStructType should be X509_NAME pbEncoded is
// an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
// *pcbBuffer return the size of memory to be allocated in bytes.
// Please notice the string is NULL terminated.
//
//-------------------------------------------------------------
static BOOL WINAPI CryptDllFormatName(
DWORD dwEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbBuffer,
DWORD *pcbBuffer)
{
//makesure lpszStructType is X509_NAME or X509_UNICODE_NAME
if((X509_NAME != lpszStructType) &&
(X509_UNICODE_NAME != lpszStructType))
{
SetLastError((DWORD) E_INVALIDARG);
return FALSE;
}
//check input parameters
if((pbEncoded==NULL && cbEncoded!=0) || pcbBuffer==NULL)
{
SetLastError((DWORD) E_INVALIDARG);
return FALSE;
}
if(cbEncoded==0)
{
SetLastError((DWORD) E_INVALIDARG);
return FALSE;
}
//call CryptDllFormatNameAll with no prefix
return CryptDllFormatNameAll(dwEncodingType,
dwFormatType,
dwFormatStrType,
pStruct,
0,
FALSE,
pbEncoded,
cbEncoded,
&pbBuffer,
pcbBuffer);
}
//-----------------------------------------------------------
//
// This is the actual format routine for an complete CERT_NAME
//
//
// lpszStructType should be X509_NAME pbEncoded is
// an encoded BLOB for CERT_NAME_INFO struct. When pBuffer==NULL,
// *pcbBuffer return the size of memory to be allocated in bytes.
// Please notice the string is NULL terminated.
//
//-------------------------------------------------------------
BOOL CryptDllFormatNameAll(
DWORD dwEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pStruct,
UINT idsPreFix,
BOOL fToAllocate,
const BYTE *pbEncoded,
DWORD cbEncoded,
void **ppbBuffer,
DWORD *pcbBuffer)
{
BOOL fResult=FALSE;
DWORD dwStrType=0;
CERT_NAME_BLOB Cert_Name_Blob;
DWORD dwSize=0;
LPWSTR pwszName=NULL;
LPWSTR pwszMulti=NULL;
Cert_Name_Blob.cbData=cbEncoded;
Cert_Name_Blob.pbData=(BYTE *)pbEncoded;
//calculate the dwStryType to use for CertNameToStrW
dwStrType=FormatToStr(dwFormatType);
//overwrite dwStrType to default if we are doing MULTI line format
//since the options will be ignored
//We want to use + and , for the seperator
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
{
dwStrType &=~(CERT_NAME_STR_CRLF_FLAG);
dwStrType &=~(CERT_NAME_STR_COMMA_FLAG);
dwStrType &=~(CERT_NAME_STR_SEMICOLON_FLAG);
dwStrType &=~(CERT_NAME_STR_NO_QUOTING_FLAG);
dwStrType &=~(CERT_NAME_STR_NO_PLUS_FLAG);
}
//if this function is not called from CryptDllFormatName,
//make sure that we use the RESERSE Flag
if(TRUE == fToAllocate)
dwStrType |= CERT_NAME_STR_REVERSE_FLAG;
//call the CertNameToStrW to convert
dwSize=CertNameToStrW(dwEncodingType,
&Cert_Name_Blob,
dwStrType,
NULL,
0);
if(0==dwSize)
goto CertNameToStrError;
pwszName=(LPWSTR)malloc(sizeof(WCHAR)*(dwSize));
if(NULL==pwszName)
goto MemoryError;
dwSize=CertNameToStrW(dwEncodingType,
&Cert_Name_Blob,
dwStrType,
pwszName,
dwSize);
if(0==dwSize)
goto CertNameToStrError;
//we do not need to parse the string for single line format
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
//calculate the bytes needed
dwSize=sizeof(WCHAR)*(wcslen(pwszName)+1);
//if FALSE==fToAllocate, we do not allocate the memory on user's
//behalf; otherwize, allocate memory to eliminate the need for
//double call
if(FALSE==fToAllocate)
{
if(NULL==(*ppbBuffer))
{
*pcbBuffer=dwSize;
fResult=TRUE;
goto CommonReturn;
}
if(*pcbBuffer < dwSize)
{
*pcbBuffer=dwSize;
goto MoreDataError;
}
memcpy(*ppbBuffer, pwszName, dwSize);
*pcbBuffer=dwSize;
}
else
{
*ppbBuffer=malloc(dwSize);
if(NULL==(*ppbBuffer))
goto MemoryError;
memcpy(*ppbBuffer, pwszName, dwSize);
//pcbBuffer can be NULL in this case
}
}
else
{
//we need to parse the string to make the multiple format
if(!GetCertNameMulti(pwszName, idsPreFix, &pwszMulti))
goto GetCertNameError;
//calculate the bytes needee
dwSize=sizeof(WCHAR)*(wcslen(pwszMulti)+1);
//if FALSE==fToAllocate, we do not allocate the memory on user's
//behalf; otherwize, allocate memory to eliminate the need for
//double call
if(FALSE==fToAllocate)
{
if(NULL==(*ppbBuffer))
{
*pcbBuffer=dwSize;
fResult=TRUE;
goto CommonReturn;
}
if(*pcbBuffer < dwSize)
{
*pcbBuffer=dwSize;
goto MoreDataError;
}
memcpy(*ppbBuffer, pwszMulti, dwSize);
*pcbBuffer=dwSize;
}
else
{
*ppbBuffer=malloc(dwSize);
if(NULL==(*ppbBuffer))
goto MemoryError;
memcpy(*ppbBuffer, pwszMulti, dwSize);
//pcbBuffer can be NULL in this case
}
}
fResult=TRUE;
CommonReturn:
if(pwszName)
free(pwszName);
if(pwszMulti)
free(pwszMulti);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(CertNameToStrError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(GetCertNameError);
}
//--------------------------------------------------------------------------
//
// FormatBasicConstraints2: szOID_BASIC_CONSTRAINTS2
// X509_BASIC_CONSTRAINTS2
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatBasicConstraints2(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
WCHAR wszSubject[SUBJECT_SIZE];
WCHAR wszNone[NONE_SIZE];
PCERT_BASIC_CONSTRAINTS2_INFO pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT idsSub=0;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_BASIC_CONSTRAINTS2,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string for the subjectType
if (pInfo->fCA)
idsSub=IDS_SUB_CA;
else
idsSub=IDS_SUB_EE;
if(!LoadStringU(hFrmtFuncInst,idsSub, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
goto LoadStringError;
if (pInfo->fPathLenConstraint)
{
//decide between signle line and multi line display
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_BASIC_CONS2_PATH_MULTI;
else
idsSub=IDS_BASIC_CONS2_PATH;
if(!FormatMessageUnicode(&pwszFormat,idsSub,
wszSubject, pInfo->dwPathLenConstraint))
goto FormatMsgError;
}
else
{
if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszNone, sizeof(wszNone)/sizeof(wszNone[0])))
goto LoadStringError;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_BASIC_CONS2_NONE_MULTI;
else
idsSub=IDS_BASIC_CONS2_NONE;
if(!FormatMessageUnicode(&pwszFormat,idsSub,
wszSubject, wszNone))
goto FormatMsgError;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatSPCObject:
//
// idsPreFix is the pre fix for mulit-line display
//--------------------------------------------------------------------------
BOOL FormatSPCObject(
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
UINT idsPreFix,
PSPC_SERIALIZED_OBJECT pInfo,
LPWSTR *ppwszFormat)
{
BOOL fResult=FALSE;
LPWSTR pwszHex=NULL;
LPWSTR pwszClassId=NULL;
WCHAR wszPreFix[PRE_FIX_SIZE];
DWORD cbNeeded=0;
LPWSTR pwszClassFormat=NULL;
LPWSTR pwszDataFormat=NULL;
LPWSTR pwszTemp;
assert(pInfo);
*ppwszFormat=NULL;
//load the pre-dix
if(0!=idsPreFix)
{
if(!LoadStringU(hFrmtFuncInst, idsPreFix,
wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
goto LoadStringError;
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->ClassId,
16,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszClassId=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszClassId)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->ClassId,
16,
pwszClassId,
&cbNeeded))
goto FormatBytesToHexError;
//format
if(!FormatMessageUnicode(&pwszClassFormat, IDS_SPC_OBJECT_CLASS, pwszClassId))
goto FormatMsgError;
//strcat
*ppwszFormat=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszClassFormat)+wcslen(wszPreFix)+wcslen(wszCOMMA)+1));
if(NULL==*ppwszFormat)
goto MemoryError;
**ppwszFormat=L'\0';
if(0!=idsPreFix)
wcscat(*ppwszFormat, wszPreFix);
wcscat(*ppwszFormat, pwszClassFormat);
//format based on the availability of SerializedData
if(0!=pInfo->SerializedData.cbData)
{
//cancatenate the ", " or \n"
if(NULL != (*ppwszFormat))
{
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwszFormat, wszCRLF);
else
wcscat(*ppwszFormat, wszCOMMA);
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->SerializedData.pbData,
pInfo->SerializedData.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszHex=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszHex)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->SerializedData.pbData,
pInfo->SerializedData.cbData,
pwszHex,
&cbNeeded))
goto FormatBytesToHexError;
if(!FormatMessageUnicode(&pwszDataFormat, IDS_SPC_OBJECT_DATA,pwszHex))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
*ppwszFormat=(LPWSTR)realloc(*ppwszFormat,
sizeof(WCHAR)* (wcslen(*ppwszFormat)+wcslen(pwszDataFormat)+wcslen(wszPreFix)+1));
if(NULL==*ppwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwszFormat,
sizeof(WCHAR)* (wcslen(*ppwszFormat)+wcslen(pwszDataFormat)+wcslen(wszPreFix)+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwszFormat = pwszTemp;
if(0!=idsPreFix)
wcscat(*ppwszFormat, wszPreFix);
wcscat(*ppwszFormat, pwszDataFormat);
}
fResult=TRUE;
CommonReturn:
if(pwszHex)
free(pwszHex);
if(pwszClassId)
free(pwszClassId);
if(pwszClassFormat)
LocalFree((HLOCAL)pwszClassFormat);
if(pwszDataFormat)
LocalFree((HLOCAL)pwszDataFormat);
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
free(*ppwszFormat);
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatBytesToHexError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(LoadStringError);
}
//--------------------------------------------------------------------------
//
// FormatSPCLink:
//--------------------------------------------------------------------------
BOOL FormatSPCLink(
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
UINT idsPreFix,
PSPC_LINK pInfo,
LPWSTR *ppwsz)
{
BOOL fResult=FALSE;
LPWSTR pwszObj=NULL;
UINT ids=0;
LPWSTR pwszFormat=NULL;
assert(pInfo);
*ppwsz=NULL;
switch(pInfo->dwLinkChoice)
{
case SPC_URL_LINK_CHOICE:
if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_URL_LINK,pInfo->pwszUrl))
goto FormatMsgError;
break;
case SPC_MONIKER_LINK_CHOICE:
if(!FormatSPCObject(
dwFormatType,
dwFormatStrType,
pFormatStruct,
idsPreFix,
&(pInfo->Moniker),
&pwszObj))
goto FormatSPCObjectError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_SPC_MONIKER_LINK_MULTI;
else
ids=IDS_SPC_MONIKER_LINK;
if(!FormatMessageUnicode(&pwszFormat,ids,pwszObj))
goto FormatMsgError;
break;
case SPC_FILE_LINK_CHOICE:
if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_FILE_LINK, pInfo->pwszFile))
goto FormatMsgError;
break;
default:
if(!FormatMessageUnicode(&pwszFormat, IDS_SPC_LINK_UNKNOWN,
pInfo->dwLinkChoice))
goto FormatMsgError;
}
*ppwsz=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormat)+1));
if(NULL==(*ppwsz))
goto MemoryError;
memcpy(*ppwsz, pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat)+1));
fResult=TRUE;
CommonReturn:
if(pwszObj)
free(pwszObj);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
if(*ppwsz)
{
free(*ppwsz);
*ppwsz=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(FormatSPCObjectError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatSPCImage:
//--------------------------------------------------------------------------
BOOL FormatSPCImage(
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
UINT idsPreFix,
PSPC_IMAGE pInfo,
LPWSTR *ppwszImageFormat)
{
BOOL fResult=FALSE;
LPWSTR pwszFormat=NULL;
LPWSTR pwszLink=NULL;
LPWSTR pwszLinkFormat=NULL;
LPWSTR pwszHex=NULL;
LPWSTR pwszHexFormat=NULL;
UINT ids=0;
DWORD cbNeeded=0;
LPWSTR pwszTemp;
assert(pInfo);
//init
*ppwszImageFormat=NULL;
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwszFormat)
goto MemoryError;
*pwszFormat=L'\0';
if(pInfo->pImageLink)
{
if(!FormatSPCLink(dwFormatType,
dwFormatStrType,
pFormatStruct,
idsPreFix,
pInfo->pImageLink,
&pwszLink))
goto FormatSPCLinkError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_IMAGE_LINK_MULTI;
else
ids=IDS_IMAGE_LINK;
if(!FormatMessageUnicode(&pwszLinkFormat, ids,
&pwszLink))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszLinkFormat)+1));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszLinkFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLinkFormat);
}
if(0!=pInfo->Bitmap.cbData)
{
//strcat ", "
if(0!=wcslen(pwszFormat))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszFormat, wszCOMMA);
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Bitmap.pbData,
pInfo->Bitmap.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszHex=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszHex)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Bitmap.pbData,
pInfo->Bitmap.cbData,
pwszHex,
&cbNeeded))
goto FormatBytesToHexError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_IMAGE_BITMAP_MULTI;
else
ids=IDS_IMAGE_BITMAP;
if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszHexFormat);
//free memory
free(pwszHex);
pwszHex=NULL;
LocalFree((HLOCAL)pwszHexFormat);
pwszHexFormat=NULL;
}
if(0!=pInfo->Metafile.cbData)
{
//strcat ", "
if(0!=wcslen(pwszFormat))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszFormat, wszCOMMA);
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Metafile.pbData,
pInfo->Metafile.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszHex=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszHex)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Metafile.pbData,
pInfo->Metafile.cbData,
pwszHex,
&cbNeeded))
goto FormatBytesToHexError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_IMAGE_METAFILE_MULTI;
else
ids=IDS_IMAGE_METAFILE;
if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszHexFormat);
//free memory
free(pwszHex);
pwszHex=NULL;
LocalFree((HLOCAL)pwszHexFormat);
pwszHexFormat=NULL;
}
if(0!=pInfo->EnhancedMetafile.cbData)
{
//strcat ", "
if(0!=wcslen(pwszFormat))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszFormat, wszCOMMA);
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->EnhancedMetafile.pbData,
pInfo->EnhancedMetafile.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszHex=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszHex)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->EnhancedMetafile.pbData,
pInfo->EnhancedMetafile.cbData,
pwszHex,
&cbNeeded))
goto FormatBytesToHexError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_IMAGE_ENHANCED_METAFILE_MULTI;
else
ids=IDS_IMAGE_ENHANCED_METAFILE;
if(!FormatMessageUnicode(&pwszHexFormat, ids, pwszHex))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszHexFormat);
//free memory
free(pwszHex);
pwszHex=NULL;
LocalFree((HLOCAL)pwszHexFormat);
pwszHexFormat=NULL;
}
if(0!=pInfo->GifFile.cbData)
{
//strcat ", "
if(0!=wcslen(pwszFormat))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszFormat, wszCOMMA);
}
cbNeeded=0;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->GifFile.pbData,
pInfo->GifFile.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszHex=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszHex)
goto MemoryError;
if(!FormatBytesToHex(
0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->GifFile.pbData,
pInfo->GifFile.cbData,
pwszHex,
&cbNeeded))
goto FormatBytesToHexError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_IMAGE_GIFFILE_MULTI;
else
ids=IDS_IMAGE_GIFFILE;
if(!FormatMessageUnicode(&pwszHexFormat, IDS_IMAGE_GIFFILE,
pwszHex))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) *(wcslen(pwszFormat)+wcslen(wszCOMMA)+wcslen(pwszHexFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszHexFormat);
//free memory
free(pwszHex);
pwszHex=NULL;
LocalFree((HLOCAL)pwszHexFormat);
pwszHexFormat=NULL;
}
if(0==wcslen(pwszFormat))
{
//fine if nothing is formatted
*ppwszImageFormat=NULL;
}
else
{
*ppwszImageFormat=(LPWSTR)malloc(sizeof(WCHAR)*(wcslen(pwszFormat)+1));
#if (0) // DSIE: Bug 27432 & 27434
if(NULL == ppwszImageFormat)
#endif
if(NULL == *ppwszImageFormat)
goto MemoryError;
memcpy(*ppwszImageFormat, pwszFormat, sizeof(WCHAR)*(wcslen(pwszFormat)+1));
}
fResult=TRUE;
CommonReturn:
if(pwszHex)
free(pwszHex);
if(pwszHexFormat)
LocalFree((HLOCAL)pwszHexFormat);
if(pwszLink)
free(pwszLink);
if(pwszLinkFormat)
LocalFree((HLOCAL)pwszLinkFormat);
if(pwszFormat)
free(pwszFormat);
return fResult;
ErrorReturn:
if(*ppwszImageFormat)
{
free(*ppwszImageFormat);
*ppwszImageFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatSPCLinkError);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
}
//--------------------------------------------------------------------------
//
// FormatSPAgencyInfo: SPC_SP_AGENCY_INFO_STRUCT
// SPC_SP_AGENCY_INFO_OBJID
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatSPAgencyInfo(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
PSPC_SP_AGENCY_INFO pInfo=NULL;
LPWSTR pwszPolicyInfo=NULL;
LPWSTR pwszPolicyInfoFormat=NULL;
LPWSTR pwszLogoLink=NULL;
LPWSTR pwszLogoLinkFormat=NULL;
LPWSTR pwszPolicyDsplyFormat=NULL;
LPWSTR pwszLogoImage=NULL;
LPWSTR pwszLogoImageFormat=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,SPC_SP_AGENCY_INFO_STRUCT,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//format pPolicyInformation
if(pInfo->pPolicyInformation)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_TWO_TABS;
else
ids=0;
if(!FormatSPCLink(dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
pInfo->pPolicyInformation,
&pwszPolicyInfo))
goto FormatSPCLinkError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AGENCY_POLICY_INFO_MULTI;
else
ids=IDS_AGENCY_POLICY_INFO;
if(!FormatMessageUnicode(&pwszPolicyInfoFormat, ids, pwszPolicyInfo))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyInfoFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyInfoFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszPolicyInfoFormat);
}
//format pwszPolicyDisplayText
if(pInfo->pwszPolicyDisplayText)
{
//strcat ", "
if(0!=wcslen(pwsz))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AGENCY_POLICY_DSPLY_MULTI;
else
ids=IDS_AGENCY_POLICY_DSPLY;
if(!FormatMessageUnicode(&pwszPolicyDsplyFormat, ids, pInfo->pwszPolicyDisplayText))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyDsplyFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyDsplyFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszPolicyDsplyFormat);
}
//pLogoImage
if(pInfo->pLogoImage)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_THREE_TABS;
else
ids=0;
if(!FormatSPCImage(dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
pInfo->pLogoImage,
&pwszLogoImage))
goto FormatSPCImageError;
//spcImage can include nothing
if(NULL!=pwszLogoImage)
{
//strcat ", "
if(0!=wcslen(pwsz))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AGENCY_LOGO_IMAGE_MULTI;
else
ids=IDS_AGENCY_LOGO_IMAGE;
if(!FormatMessageUnicode(&pwszLogoImageFormat,ids,pwszLogoImage))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoImageFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) *(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoImageFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszLogoImageFormat);
}
}
//format pLogoLink
if(pInfo->pLogoLink)
{
//strcat ", "
if(0!=wcslen(pwsz))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_TWO_TABS;
else
ids=0;
if(!FormatSPCLink(dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
pInfo->pLogoLink,
&pwszLogoLink))
goto FormatSPCLinkError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AGENCY_LOGO_LINK_MULTI;
else
ids=IDS_AGENCY_LOGO_LINK;
if(!FormatMessageUnicode(&pwszLogoLinkFormat, ids, pwszLogoLink))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoLinkFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszLogoLinkFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszLogoLinkFormat);
}
if(0==wcslen(pwsz))
{
//no data
pwszFormat=(LPWSTR)malloc((NO_INFO_SIZE+1)*sizeof(WCHAR));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
goto LoadStringError;
}
else
{
pwszFormat=pwsz;
pwsz=NULL;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszPolicyInfo)
free(pwszPolicyInfo);
if(pwszPolicyInfoFormat)
LocalFree((HLOCAL)pwszPolicyInfoFormat);
if(pwszLogoLink)
free(pwszLogoLink);
if(pwszLogoLinkFormat)
LocalFree((HLOCAL)pwszLogoLinkFormat);
if(pwszPolicyDsplyFormat)
LocalFree((HLOCAL)pwszPolicyDsplyFormat);
if(pwszLogoImage)
free(pwszLogoImage);
if(pwszLogoImageFormat)
LocalFree((HLOCAL)pwszLogoImageFormat);
if(pwszFormat)
free(pwszFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatSPCLinkError);
TRACE_ERROR(FormatSPCImageError);
}
//--------------------------------------------------------------------------
//
// GetNoticeNumberString:
//
// The memory should be allocated via malloc
//--------------------------------------------------------------------------
BOOL WINAPI GetNoticeNumberString( DWORD cNoticeNumbers,
int *rgNoticeNumbers,
LPWSTR *ppwszNumber)
{
BOOL fResult=FALSE;
WCHAR wszNumber[INT_SIZE];
DWORD dwIndex=0;
LPWSTR pwszTemp;
*ppwszNumber=NULL;
if(NULL==rgNoticeNumbers || 0==cNoticeNumbers)
goto InvalidArg;
*ppwszNumber=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==*ppwszNumber)
goto MemoryError;
**ppwszNumber=L'\0';
for(dwIndex=0; dwIndex<cNoticeNumbers; dwIndex++)
{
wszNumber[0]='\0';
_itow(rgNoticeNumbers[dwIndex], wszNumber, 10);
if(wcslen(wszNumber) > 0)
{
#if (0) // DSIE: Bug 27436
*ppwszNumber=(LPWSTR)realloc(*ppwszNumber,
sizeof(WCHAR)*(wcslen(*ppwszNumber)+wcslen(wszNumber)+wcslen(wszCOMMA)+1));
if(NULL==*ppwszNumber)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwszNumber,
sizeof(WCHAR)*(wcslen(*ppwszNumber)+wcslen(wszNumber)+wcslen(wszCOMMA)+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwszNumber = pwszTemp;
wcscat(*ppwszNumber, wszNumber);
if(dwIndex != (cNoticeNumbers-1))
wcscat(*ppwszNumber, wszCOMMA);
}
}
if(0==wcslen(*ppwszNumber))
goto InvalidArg;
fResult=TRUE;
CommonReturn:
return fResult;
ErrorReturn:
if(*ppwszNumber)
{
free(*ppwszNumber);
*ppwszNumber=NULL;
}
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatCertQualifier:
//
// The memory should be allocated via malloc
//--------------------------------------------------------------------------
BOOL FormatPolicyUserNotice(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
UINT idsPreFix,
BYTE *pbEncoded,
DWORD cbEncoded,
LPWSTR *ppwsz)
{
BOOL fResult=FALSE;
WCHAR wszNoInfo[NO_INFO_SIZE];
WCHAR wszPreFix[PREFIX_SIZE];
WCHAR wszNextPre[PREFIX_SIZE];
WCHAR wszText[SUBJECT_SIZE];
BOOL fComma=FALSE;
CERT_POLICY_QUALIFIER_USER_NOTICE *pInfo=NULL;
LPWSTR pwszOrg=NULL;
LPWSTR pwszNumber=NULL;
LPWSTR pwszTemp;
*ppwsz=NULL;
if (!DecodeGenericBLOB(dwCertEncodingType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
if(!LoadStringU(hFrmtFuncInst,idsPreFix, wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
goto LoadStringError;
if(!LoadStringU(hFrmtFuncInst,idsPreFix+1, wszNextPre, sizeof(wszNextPre)/sizeof(wszNextPre[0])))
goto LoadStringError;
if(NULL == pInfo->pNoticeReference && NULL == pInfo->pszDisplayText)
{
//load the string "Info Not Available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
*ppwsz=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(wszNoInfo) + wcslen(wszPreFix) + POSTFIX_SIZE + 1));
if(NULL==*ppwsz)
goto MemoryError;
**ppwsz=L'\0';
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszPreFix);
wcscat(*ppwsz, wszNoInfo);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszCRLF);
}
else
{
*ppwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==*ppwsz)
goto MemoryError;
**ppwsz=L'\0';
if(pInfo->pNoticeReference)
{
if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF, wszText, sizeof(wszText)/sizeof(wszText[0])))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
if(NULL==*ppwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwsz = pwszTemp;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszPreFix);
wcscat(*ppwsz, wszText);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszCRLF);
if(pInfo->pNoticeReference->pszOrganization)
{
if(S_OK!=SZtoWSZ(pInfo->pNoticeReference->pszOrganization, &pwszOrg))
goto SZtoWSZError;
if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF_ORG, wszText, sizeof(wszText)/sizeof(wszText[0])))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszOrg)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
if(NULL==*ppwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszOrg)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwsz = pwszTemp;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszNextPre);
wcscat(*ppwsz, wszText);
wcscat(*ppwsz, pwszOrg);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszCRLF);
else
{
wcscat(*ppwsz, wszCOMMA);
fComma=TRUE;
}
}
if(pInfo->pNoticeReference->cNoticeNumbers)
{
if(NULL == pInfo->pNoticeReference->rgNoticeNumbers)
goto InvalidArg;
if(!GetNoticeNumberString(pInfo->pNoticeReference->cNoticeNumbers,
pInfo->pNoticeReference->rgNoticeNumbers,
&pwszNumber))
goto GetNumberError;
if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_REF_NUMBER, wszText, sizeof(wszText)/sizeof(wszText[0])))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszNumber)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
if(NULL==*ppwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pwszNumber)+wcslen(wszNextPre)+POSTFIX_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwsz = pwszTemp;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszNextPre);
wcscat(*ppwsz, wszText);
wcscat(*ppwsz, pwszNumber);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszCRLF);
else
{
wcscat(*ppwsz, wszCOMMA);
fComma=TRUE;
}
}
}
if(pInfo->pszDisplayText)
{
if(!LoadStringU(hFrmtFuncInst,IDS_USER_NOTICE_TEXT, wszText, sizeof(wszText)/sizeof(wszText[0])))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pInfo->pszDisplayText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
if(NULL==*ppwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
sizeof(WCHAR) * (wcslen(*ppwsz)+wcslen(wszText)+wcslen(pInfo->pszDisplayText)+wcslen(wszPreFix)+POSTFIX_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
*ppwsz = pwszTemp;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszPreFix);
wcscat(*ppwsz, wszText);
wcscat(*ppwsz, pInfo->pszDisplayText);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwsz, wszCRLF);
else
{
wcscat(*ppwsz, wszCOMMA);
fComma=TRUE;
}
}
//get rid of the last comma
if(fComma)
*(*ppwsz+wcslen(*ppwsz)-wcslen(wszCOMMA))=L'\0';
}
fResult=TRUE;
CommonReturn:
if(pInfo)
free(pInfo);
if(pwszOrg)
free(pwszOrg);
if(pwszNumber)
free(pwszNumber);
return fResult;
ErrorReturn:
if(*ppwsz)
{
free(*ppwsz);
*ppwsz=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(SZtoWSZError);
TRACE_ERROR(GetNumberError);
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
}
//--------------------------------------------------------------------------
//
// FormatCertQualifier:
//--------------------------------------------------------------------------
BOOL FormatCertQualifier(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
PCERT_POLICY_QUALIFIER_INFO pInfo,
LPWSTR *ppwszFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
UINT ids=0;
PCCRYPT_OID_INFO pOIDInfo=NULL;
LPWSTR pwszName=NULL;
LPWSTR pwszElement=NULL;
LPWSTR pwszOID=NULL;
*ppwszFormat=NULL;
//get the oid name
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pInfo->pszPolicyQualifierId,
0);
if(NULL == pOIDInfo)
{
if(S_OK!=SZtoWSZ(pInfo->pszPolicyQualifierId, &pwszOID))
goto SZtoWSZError;
}
if(pInfo->Qualifier.cbData)
{
if(0==strcmp(szOID_PKIX_POLICY_QUALIFIER_CPS, pInfo->pszPolicyQualifierId))
{
//this is just a unicode format
//turn off the multi line here
cbNeeded=0;
if(!FormatAnyUnicodeStringExtension(
dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
pInfo->pszPolicyQualifierId,
pInfo->Qualifier.pbData,
pInfo->Qualifier.cbData,
NULL,
&cbNeeded))
goto FormatUnicodeError;
pwszName=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszName)
goto MemoryError;
if(!FormatAnyUnicodeStringExtension(
dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
pInfo->pszPolicyQualifierId,
pInfo->Qualifier.pbData,
pInfo->Qualifier.cbData,
pwszName,
&cbNeeded))
goto FormatUnicodeError;
}
else
{
if(0==strcmp(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,pInfo->pszPolicyQualifierId))
{
//this is yet another struct to format. We remember to have
//a 3 tab prefix
if(!FormatPolicyUserNotice(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
IDS_THREE_TABS,
pInfo->Qualifier.pbData,
pInfo->Qualifier.cbData,
&pwszName))
goto FormatUserNoticdeError;
}
else
{
//get the Hex dump of the Key Usage
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Qualifier.pbData,
pInfo->Qualifier.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszName=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszName)
goto MemoryError;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->Qualifier.pbData,
pInfo->Qualifier.cbData,
pwszName,
&cbNeeded))
goto FormatBytesToHexError;
}
}
//add the desired 3 tab prefix and new line for CSP and the new line
//for the multi line case
if((dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) &&
(0!=strcmp(szOID_PKIX_POLICY_QUALIFIER_USERNOTICE,pInfo->pszPolicyQualifierId)))
{
if(!FormatMessageUnicode(&pwszElement, IDS_POLICY_QUALIFIER_ELEMENT,
pwszName))
goto FormatMsgError;
}
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_POLICY_QUALIFIER_MULTI;
else
ids=IDS_POLICY_QUALIFIER;
if(!FormatMessageUnicode(ppwszFormat, ids,
pOIDInfo? pOIDInfo->pwszName : pwszOID,
pwszElement? pwszElement : pwszName))
goto FormatMsgError;
}
else
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_POLICY_QUALIFIER_NO_BLOB_MULTI;
else
ids=IDS_POLICY_QUALIFIER_NO_BLOB;
if(!FormatMessageUnicode(ppwszFormat, ids,
pOIDInfo? pOIDInfo->pwszName : pwszOID))
goto FormatMsgError;
}
fResult=TRUE;
CommonReturn:
if(pwszName)
free(pwszName);
if(pwszElement)
LocalFree((HLOCAL)pwszElement);
if(pwszOID)
free(pwszOID);
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
LocalFree((HLOCAL)(*ppwszFormat));
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatUnicodeError);
TRACE_ERROR(FormatUserNoticdeError);
TRACE_ERROR(SZtoWSZError);
}
//--------------------------------------------------------------------------
//
// FormatCertPolicies: X509_CERT_POLICIES
// szOID_CERT_POLICIES
// szOID_APPLICATION_CERT_POLICIES
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatCertPolicies(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszPolicyFormat=NULL;
LPWSTR pwszQualifiers=NULL;
LPWSTR pwszQualifierFormat=NULL;
LPWSTR pwszOneQualifier=NULL;
LPWSTR pwszOID=NULL;
PCERT_POLICIES_INFO pInfo=NULL;
PCERT_POLICY_INFO pPolicyInfo=NULL;
DWORD dwIndex=0;
DWORD dwQualifierIndex=0;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
PCCRYPT_OID_INFO pOIDInfo=NULL;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_CERT_POLICIES,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
for(dwIndex=0; dwIndex < pInfo->cPolicyInfo; dwIndex++)
{
//strcat ", "
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
pPolicyInfo=&(pInfo->rgPolicyInfo[dwIndex]);
pwszQualifiers=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwszQualifiers)
goto MemoryError;
*pwszQualifiers=L'\0';
//format the qualifiers
for(dwQualifierIndex=0; dwQualifierIndex < pPolicyInfo->cPolicyQualifier;
dwQualifierIndex++)
{
//strcat ", "
if(0!=wcslen(pwszQualifiers))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszQualifiers, wszCOMMA);
}
if(!FormatCertQualifier(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
&(pPolicyInfo->rgPolicyQualifier[dwQualifierIndex]),
&pwszOneQualifier))
goto FormatCertQualifierError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_POLICY_QUALIFIER_INFO_MULTI;
else
ids=IDS_POLICY_QUALIFIER_INFO;
//format
if(!FormatMessageUnicode(&pwszQualifierFormat,ids,
dwIndex+1,
dwQualifierIndex+1,
pwszOneQualifier))
goto FormatMsgError;
//strcat
#if (0) // DSIE: Bug 27436
pwszQualifiers=(LPWSTR)realloc(pwszQualifiers,
sizeof(WCHAR) * (wcslen(pwszQualifiers)+wcslen(wszCOMMA)+wcslen(pwszQualifierFormat)+1));
if(NULL==pwszQualifiers)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszQualifiers,
sizeof(WCHAR) * (wcslen(pwszQualifiers)+wcslen(wszCOMMA)+wcslen(pwszQualifierFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszQualifiers = pwszTemp;
wcscat(pwszQualifiers, pwszQualifierFormat);
LocalFree((HLOCAL)pwszOneQualifier);
pwszOneQualifier=NULL;
LocalFree((HLOCAL)pwszQualifierFormat);
pwszQualifierFormat=NULL;
}
//now, format the certPolicyInfo
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pPolicyInfo->pszPolicyIdentifier,
0);
if(NULL == pOIDInfo)
{
if(S_OK!=SZtoWSZ(pPolicyInfo->pszPolicyIdentifier, &pwszOID))
goto SZtoWSZError;
}
if(0!=pPolicyInfo->cPolicyQualifier)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
ids=IDS_CERT_POLICY_MULTI;
else
ids=IDS_APPLICATION_CERT_POLICY_MULTI;
else
if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
ids=IDS_CERT_POLICY;
else
ids=IDS_APPLICATION_CERT_POLICY;
if(!FormatMessageUnicode(&pwszPolicyFormat,ids,
dwIndex+1, pOIDInfo? pOIDInfo->pwszName : pwszOID,
pwszQualifiers))
goto FormatMsgError;
}
else
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
ids=IDS_CERT_POLICY_NO_QUA_MULTI;
else
ids=IDS_APPLICATION_CERT_POLICY_NO_QUA_MULTI;
else
if (0 == strcmp(lpszStructType, szOID_CERT_POLICIES))
ids=IDS_CERT_POLICY_NO_QUA;
else
ids=IDS_APPLICATION_CERT_POLICY_NO_QUA;
if(!FormatMessageUnicode(&pwszPolicyFormat, ids,
dwIndex+1, pOIDInfo? pOIDInfo->pwszName : pwszOID))
goto FormatMsgError;
}
//strcat
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszPolicyFormat);
free(pwszQualifiers);
pwszQualifiers=NULL;
LocalFree((HLOCAL)pwszPolicyFormat);
pwszPolicyFormat=NULL;
if(pwszOID)
free(pwszOID);
pwszOID=NULL;
}
if(0==wcslen(pwsz))
{
//no data
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
goto LoadStringError;
}
else
{
pwszFormat=pwsz;
pwsz=NULL;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszOID)
free(pwszOID);
if(pwszOneQualifier)
LocalFree((HLOCAL)pwszOneQualifier);
if(pwszQualifierFormat)
LocalFree((HLOCAL)pwszQualifierFormat);
if(pwszQualifiers)
free(pwszQualifiers);
if(pwszPolicyFormat)
LocalFree((HLOCAL)pwszPolicyFormat);
if(pwsz)
free(pwsz);
if(pwszFormat)
free(pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError,E_OUTOFMEMORY);
TRACE_ERROR(FormatCertQualifierError);
TRACE_ERROR(SZtoWSZError);
}
//--------------------------------------------------------------------------
//
// FormatCAVersion: szOID_CERTSRV_CA_VERSION
// Decode as X509_INTEGER
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatCAVersion(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
UINT ids=0;
DWORD dwCAVersion=0;
DWORD cbCAVersion=sizeof(dwCAVersion);
LPWSTR pwszFormat=NULL;
//check for input parameters
if((NULL==pbEncoded && 0!=cbEncoded) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if(!CryptDecodeObject(dwCertEncodingType,X509_INTEGER,pbEncoded, cbEncoded,
0,&dwCAVersion,&cbCAVersion))
goto DecodeGenericError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_CA_VERSION_MULTI;
else
ids=IDS_CA_VERSION;
if(!FormatMessageUnicode(&pwszFormat, ids,
CANAMEIDTOICERT(dwCAVersion), CANAMEIDTOIKEY(dwCAVersion)))
goto FormatMsgError;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatNetscapeCertType:
// szOID_NETSCAPE_CERT_TYPE
// Decode as X509_BITS
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatNetscapeCertType(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
WCHAR wszCertType[CERT_TYPE_SIZE+1];
FORMAT_CERT_TYPE_INFO rgCertType[]={
NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_CLIENT_AUTH, //0x80
NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_SERVER_AUTH, //0x40
NETSCAPE_SMIME_CERT_TYPE, IDS_NETSCAPE_SMIME, //0x20
NETSCAPE_SIGN_CERT_TYPE, IDS_NETSCAPE_SIGN, //0x10
0x08, IDS_UNKNOWN_CERT_TYPE, //0x08
NETSCAPE_SSL_CA_CERT_TYPE, IDS_NETSCAPE_SSL_CA, //0x04
NETSCAPE_SMIME_CA_CERT_TYPE, IDS_NETSCAPE_SMIME_CA, //0x02
NETSCAPE_SIGN_CA_CERT_TYPE, IDS_NETSCAPE_SIGN_CA}; //0x01
DWORD dwCertType=0;
DWORD dwIndex=0;
CRYPT_BIT_BLOB *pInfo=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszByte=NULL;
LPWSTR pwszFormat=NULL;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded && 0!=cbEncoded) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if(!DecodeGenericBLOB(dwCertEncodingType,X509_BITS,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
if(0==pInfo->cbData)
goto InvalidArg;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//the count of bits to consider
dwCertType=sizeof(rgCertType)/sizeof(rgCertType[0]);
//we need to consider the unused bits in the last byte
if((1 == pInfo->cbData) && (8 > pInfo->cUnusedBits))
{
dwCertType=8-pInfo->cUnusedBits;
}
for(dwIndex=0; dwIndex<dwCertType; dwIndex++)
{
if(pInfo->pbData[0] & rgCertType[dwIndex].bCertType)
{
if(!LoadStringU(hFrmtFuncInst, rgCertType[dwIndex].idsCertType, wszCertType, CERT_TYPE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszCertType);
wcscat(pwsz, wszCOMMA);
}
}
//there is data that we can not interpret if the bit number is more than 8
if(8 < (8 * pInfo->cbData - pInfo->cUnusedBits))
{
if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CERT_TYPE, wszCertType, CERT_TYPE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCertType)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszCertType);
wcscat(pwsz, wszCOMMA);
}
if(0==wcslen(pwsz))
{
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (CERT_TYPE_SIZE+1));
if(NULL == pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (CERT_TYPE_SIZE+1));
if(NULL == pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CERT_TYPE, pwsz,
CERT_TYPE_SIZE))
goto LoadStringError;
}
else
{
//get rid of the last comma
*(pwsz+wcslen(pwsz)-wcslen(wszCOMMA))=L'\0';
}
//get the Hex dump of the cert type
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszByte=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszByte)
goto MemoryError;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
pwszByte,
&cbNeeded))
goto FormatBytesToHexError;
//convert the WSZ
if(!FormatMessageUnicode(&pwszFormat, IDS_BIT_BLOB, pwsz,
pwszByte))
goto FormatMsgError;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pInfo)
free(pInfo);
if(pwsz)
free(pwsz);
if(pwszByte)
free(pwszByte);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(LoadStringError);
}
//--------------------------------------------------------------------------
//
// FormatAnyUnicodeStringExtension:
// szOID_ENROLLMENT_NAME_VALUE_PAIR
// Decode as szOID_ENROLLMENT_NAME_VALUE_PAIR
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAnyNameValueStringAttr(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
UINT ids=0;
CRYPT_ENROLLMENT_NAME_VALUE_PAIR *pInfo=NULL;
LPWSTR pwszFormat=NULL;
//check for input parameters
if((NULL==pbEncoded && 0!=cbEncoded) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,szOID_ENROLLMENT_NAME_VALUE_PAIR,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
if(NULL == pInfo->pwszName || NULL == pInfo->pwszValue)
goto InvalidArg;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_NAME_VALUE_MULTI;
else
ids=IDS_NAME_VALUE;
if(!FormatMessageUnicode(&pwszFormat, ids,
pInfo->pwszName, pInfo->pwszValue))
goto FormatMsgError;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pInfo)
free(pInfo);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatAnyUnicodeStringExtension:
// szOID_ENROLL_CERTTYPE_EXTENSION
// szOID_NETSCAPE_REVOCATION_URL
// Decode as X509_ANY_UNICODE_STRING
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAnyUnicodeStringExtension(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
UINT ids=0;
CERT_NAME_VALUE *pInfo=NULL;
LPWSTR pwszFormat=NULL;
//check for input parameters
if((NULL==pbEncoded && 0!=cbEncoded) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_UNICODE_ANY_STRING,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//the data can not be the encoded blob or the octect string
if(!IS_CERT_RDN_CHAR_STRING(pInfo->dwValueType))
goto DecodeGenericError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_UNICODE_STRING_MULTI;
else
ids=IDS_UNICODE_STRING;
if(!FormatMessageUnicode(&pwszFormat, ids,
(LPWSTR)(pInfo->Value.pbData)))
goto FormatMsgError;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pInfo)
free(pInfo);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatDistPointName: Pre-condition: dwDistPointNameChoice!=0
//--------------------------------------------------------------------------
BOOL FormatDistPointName(DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
PCRL_DIST_POINT_NAME pInfo,
LPWSTR *ppwszFormat)
{
BOOL fResult=FALSE;
DWORD cbNeeded=0;
LPWSTR pwszCRLIssuer=NULL;
UINT ids=0;
*ppwszFormat=NULL;
if(CRL_DIST_POINT_FULL_NAME==pInfo->dwDistPointNameChoice)
{
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_THREE_TABS;
cbNeeded=0;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->FullName),
NULL,
&cbNeeded))
goto FormatAltNameError;
pwszCRLIssuer=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszCRLIssuer)
goto MemoryError;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->FullName),
pwszCRLIssuer,
&cbNeeded))
goto FormatAltNameError;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_CRL_DIST_FULL_NAME_MULTI;
else
ids=IDS_CRL_DIST_FULL_NAME;
if(!FormatMessageUnicode(ppwszFormat, ids,pwszCRLIssuer))
goto FormatMsgError;
}
else if(CRL_DIST_POINT_ISSUER_RDN_NAME==pInfo->dwDistPointNameChoice)
{
*ppwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(CRL_DIST_NAME_SIZE+1));
if(NULL==*ppwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst, IDS_CRL_DIST_ISSUER_RDN,
*ppwszFormat,CRL_DIST_NAME_SIZE))
goto LoadStringError;
}
else
{
if(!FormatMessageUnicode(ppwszFormat, IDS_DWORD,
pInfo->dwDistPointNameChoice))
goto FormatMsgError;
}
fResult=TRUE;
CommonReturn:
if(pwszCRLIssuer)
free(pwszCRLIssuer);
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
LocalFree((HLOCAL)(*ppwszFormat));
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatAltNameError);
}
//--------------------------------------------------------------------------
//
// FormatCRLReason: Pre-condition: pReason.cbData != 0
//--------------------------------------------------------------------------
BOOL FormatCRLReason(DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
PCRYPT_BIT_BLOB pInfo,
LPWSTR *ppwszFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwszByte=NULL;
WCHAR wszReason[CRL_REASON_SIZE+1];
DWORD cbNeeded=0;
BOOL fResult=FALSE;
LPWSTR pwszTemp;
*ppwszFormat=NULL;
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwszFormat)
goto MemoryError;
*pwszFormat=L'\0';
//format the 1st byte
if(pInfo->pbData[0] & CRL_REASON_UNUSED_FLAG)
{
if(!LoadStringU(hFrmtFuncInst, IDS_UNSPECIFIED, wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_KEY_COMPROMISE_FLAG)
{
if(!LoadStringU(hFrmtFuncInst, IDS_KEY_COMPROMISE, wszReason,CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_CA_COMPROMISE_FLAG )
{
if(!LoadStringU(hFrmtFuncInst, IDS_CA_COMPROMISE,wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_AFFILIATION_CHANGED_FLAG )
{
if(!LoadStringU(hFrmtFuncInst, IDS_AFFILIATION_CHANGED, wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_SUPERSEDED_FLAG )
{
if(!LoadStringU(hFrmtFuncInst, IDS_SUPERSEDED, wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_CESSATION_OF_OPERATION_FLAG )
{
if(!LoadStringU(hFrmtFuncInst, IDS_CESSATION_OF_OPERATION, wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(pInfo->pbData[0] & CRL_REASON_CERTIFICATE_HOLD_FLAG )
{
if(!LoadStringU(hFrmtFuncInst, IDS_CERTIFICATE_HOLD, wszReason, CRL_REASON_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszFormat)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat,
sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(wszReason)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, wszReason);
wcscat(pwszFormat, wszCOMMA);
}
if(0==wcslen(pwszFormat))
{
#if (0) // DSIE: Bug 27436
pwszFormat=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (UNKNOWN_CRL_REASON_SIZE+1));
#endif
pwszTemp=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (UNKNOWN_CRL_REASON_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_CRL_REASON, pwszFormat,
UNKNOWN_CRL_REASON_SIZE))
goto LoadStringError;
}
else
{
//get rid of the last comma
*(pwszFormat+wcslen(pwszFormat)-wcslen(wszCOMMA))=L'\0';
}
//get the Hex dump of the Key Usage
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszByte=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszByte)
goto MemoryError;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
pwszByte,
&cbNeeded))
goto FormatBytesToHexError;
//convert the WSZ
if(!FormatMessageUnicode(ppwszFormat, IDS_BIT_BLOB, pwszFormat,
pwszByte))
goto FormatMsgError;
fResult=TRUE;
CommonReturn:
if(pwszFormat)
free(pwszFormat);
if(pwszByte)
free(pwszByte);
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
LocalFree((HLOCAL)(*ppwszFormat));
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatCRLDistPoints: X509_CRL_DIST_POINTS
// szOID_CRL_DIST_POINTS
// szOID_FRESHEST_CRL
// szOID_CRL_SELF_CDP
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatCRLDistPoints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszEntryFormat=NULL;
LPWSTR pwszEntryTagFormat=NULL;
LPWSTR pwszPointName=NULL;
LPWSTR pwszNameFormat=NULL;
LPWSTR pwszCRLReason=NULL;
LPWSTR pwszReasonFormat=NULL;
LPWSTR pwszCRLIssuer=NULL;
LPWSTR pwszIssuerFormat=NULL;
PCRL_DIST_POINTS_INFO pInfo=NULL;
DWORD cbNeeded=0;
DWORD dwIndex=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
LPCSTR pszOID;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
//DSIE: Cert server encodes szOID_CRL_SEL_CDP using szOID_CRL_DIST_POINTS,
// so we need to change the lpszStructType for decoding.
if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
{
pszOID = szOID_CRL_DIST_POINTS;
}
else
{
pszOID = lpszStructType;
}
if (!DecodeGenericBLOB(dwCertEncodingType, pszOID, //lpszStructType,
pbEncoded, cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
for(dwIndex=0; dwIndex<pInfo->cDistPoint; dwIndex++)
{
//format distribution name
if(0!=pInfo->rgDistPoint[dwIndex].DistPointName.dwDistPointNameChoice)
{
if(!FormatDistPointName(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
&(pInfo->rgDistPoint[dwIndex].DistPointName),
&pwszPointName))
goto FormatDistPointNameError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_CRL_DIST_NAME_MULTI;
else
ids=IDS_CRL_DIST_NAME;
if(!FormatMessageUnicode(&pwszNameFormat, ids,pwszPointName))
goto FormatMsgError;
}
//format the CRL reason
if(0!=pInfo->rgDistPoint[dwIndex].ReasonFlags.cbData)
{
if(!FormatCRLReason(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->rgDistPoint[dwIndex].ReasonFlags),
&pwszCRLReason))
goto FormatCRLReasonError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_CRL_DIST_REASON_MULTI;
else
ids=IDS_CRL_DIST_REASON;
if(!FormatMessageUnicode(&pwszReasonFormat, ids ,pwszCRLReason))
goto FormatMsgError;
}
//format the Issuer
if(0!=pInfo->rgDistPoint[dwIndex].CRLIssuer.cAltEntry)
{
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_TWO_TABS;
else
ids=0;
cbNeeded=0;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->rgDistPoint[dwIndex].CRLIssuer),
NULL,
&cbNeeded))
goto FormatAltNameError;
pwszCRLIssuer=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszCRLIssuer)
goto MemoryError;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->rgDistPoint[dwIndex].CRLIssuer),
pwszCRLIssuer,
&cbNeeded))
goto FormatAltNameError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_CRL_DIST_ISSUER_MULTI;
else
ids=IDS_CRL_DIST_ISSUER;
if(!FormatMessageUnicode(&pwszIssuerFormat,ids,pwszCRLIssuer))
goto FormatMsgError;
}
cbNeeded=0;
if(pwszNameFormat)
cbNeeded+=wcslen(pwszNameFormat);
if(pwszReasonFormat)
cbNeeded+=wcslen(pwszReasonFormat);
if(pwszIssuerFormat)
cbNeeded+=wcslen(pwszIssuerFormat);
if(0!=cbNeeded)
{
//add ", " between each element for single line format
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
if(0!=wcslen(pwsz))
wcscat(pwsz, wszCOMMA);
}
//strcat all the information, including the COMMA
cbNeeded += wcslen(wszCOMMA)*2;
pwszEntryFormat=(LPWSTR)malloc(sizeof(WCHAR) * (cbNeeded+1));
if(NULL==pwszEntryFormat)
goto MemoryError;
*pwszEntryFormat=L'\0';
//strcat all three fields one at a time
if(pwszNameFormat)
wcscat(pwszEntryFormat, pwszNameFormat);
if(pwszReasonFormat)
{
if(0!=wcslen(pwszEntryFormat))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszEntryFormat, wszCOMMA);
}
wcscat(pwszEntryFormat, pwszReasonFormat);
}
if(pwszIssuerFormat)
{
if(0!=wcslen(pwszEntryFormat))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwszEntryFormat, wszCOMMA);
}
wcscat(pwszEntryFormat, pwszIssuerFormat);
}
//format the entry
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
//
// DSIE: Load appropriate format string.
//
if (0 == strcmp(lpszStructType, szOID_FRESHEST_CRL))
ids=IDS_FRESHEST_CRL_MULTI;
else if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
ids=IDS_CRL_SELF_CDP_MULTI;
else
ids=IDS_CRL_DIST_ENTRY_MULTI;
else
if (0 == strcmp(lpszStructType, szOID_FRESHEST_CRL))
ids=IDS_FRESHEST_CRL;
else if (0 == strcmp(lpszStructType, szOID_CRL_SELF_CDP))
ids=IDS_CRL_SELF_CDP;
else
ids=IDS_CRL_DIST_ENTRY;
if(!FormatMessageUnicode(&pwszEntryTagFormat, ids, dwIndex+1,
pwszEntryFormat))
goto FormatMsgError;
//strcat the entry
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszEntryTagFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszEntryTagFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszEntryTagFormat);
//free memory
free(pwszEntryFormat);
pwszEntryFormat=NULL;
LocalFree(pwszEntryTagFormat);
pwszEntryTagFormat=NULL;
}
//free memory
if(pwszPointName)
{
LocalFree((HLOCAL)pwszPointName);
pwszPointName=NULL;
}
if(pwszCRLReason)
{
LocalFree((HLOCAL)(pwszCRLReason));
pwszCRLReason=NULL;
}
if(pwszCRLIssuer)
{
free(pwszCRLIssuer);
pwszCRLIssuer=NULL;
}
if(pwszNameFormat)
{
LocalFree((HLOCAL)pwszNameFormat);
pwszNameFormat=NULL;
}
if(pwszReasonFormat)
{
LocalFree((HLOCAL)pwszReasonFormat);
pwszReasonFormat=NULL;
}
if(pwszIssuerFormat)
{
LocalFree((HLOCAL)pwszIssuerFormat);
pwszIssuerFormat=NULL;
}
}
if(0==wcslen(pwsz))
{
//no data
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
goto LoadStringError;
}
else
{
pwszFormat=pwsz;
pwsz=NULL;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszEntryFormat)
free(pwszEntryFormat);
if(pwszEntryTagFormat)
LocalFree((HLOCAL)pwszEntryTagFormat);
//free memory
if(pwszPointName)
LocalFree((HLOCAL)pwszPointName);
if(pwszCRLReason)
LocalFree((HLOCAL)(pwszCRLReason));
if(pwszCRLIssuer)
free(pwszCRLIssuer);
if(pwszNameFormat)
LocalFree((HLOCAL)pwszNameFormat);
if(pwszReasonFormat)
LocalFree((HLOCAL)pwszReasonFormat);
if(pwszIssuerFormat)
LocalFree((HLOCAL)pwszIssuerFormat);
if(pwsz)
free(pwsz);
if(pwszFormat)
free(pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatDistPointNameError);
TRACE_ERROR(FormatCRLReasonError);
TRACE_ERROR(FormatAltNameError);
}
//--------------------------------------------------------------------------
//
// FormatCertPolicyID:
//
// Pre-condition: pCertPolicyID has to include the valid information.that is,
// cCertPolicyElementId can not be 0.
//--------------------------------------------------------------------------
BOOL FormatCertPolicyID(PCERT_POLICY_ID pCertPolicyID, LPWSTR *ppwszFormat)
{
BOOL fResult=FALSE;
LPSTR pszFormat=NULL;
DWORD dwIndex=0;
HRESULT hr=S_OK;
LPSTR pwszTemp;
*ppwszFormat=NULL;
if(0==pCertPolicyID->cCertPolicyElementId)
goto InvalidArg;
pszFormat=(LPSTR)malloc(sizeof(CHAR));
if(NULL==pszFormat)
goto MemoryError;
*pszFormat='\0';
for(dwIndex=0; dwIndex<pCertPolicyID->cCertPolicyElementId; dwIndex++)
{
#if (0) // DSIE: Bug 27436
pszFormat=(LPSTR)realloc(pszFormat, strlen(pszFormat)+
strlen(pCertPolicyID->rgpszCertPolicyElementId[dwIndex])+strlen(strCOMMA)+1);
if(NULL==pszFormat)
goto MemoryError;
#endif
pwszTemp=(LPSTR)realloc(pszFormat, strlen(pszFormat)+
strlen(pCertPolicyID->rgpszCertPolicyElementId[dwIndex])+strlen(strCOMMA)+1);
if(NULL==pwszTemp)
goto MemoryError;
pszFormat = pwszTemp;
strcat(pszFormat,pCertPolicyID->rgpszCertPolicyElementId[dwIndex]);
strcat(pszFormat, strCOMMA);
}
//get rid of the last COMMA
*(pszFormat+strlen(pszFormat)-strlen(strCOMMA))='\0';
//convert to WCHAR
if(S_OK!=(hr=SZtoWSZ(pszFormat, ppwszFormat)))
goto SZtoWSZError;
fResult=TRUE;
CommonReturn:
if(pszFormat)
free(pszFormat);
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
free(*ppwszFormat);
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
SET_ERROR_VAR(SZtoWSZError,hr);
}
//--------------------------------------------------------------------------
//
// FormatKeyRestriction: X509_KEY_USAGE_RESTRICTION
// szOID_KEY_USAGE_RESTRICTION
//
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatKeyRestriction(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
PCERT_KEY_USAGE_RESTRICTION_INFO pInfo=NULL;
LPWSTR pwszPolicy=NULL;
LPWSTR pwszPolicyFormat=NULL;
LPWSTR pwszKeyUsage=NULL;
LPWSTR pwszKeyUsageFormat=NULL;
DWORD cbNeeded=0;
DWORD dwIndex=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_USAGE_RESTRICTION,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
for(dwIndex=0; dwIndex<pInfo->cCertPolicyId; dwIndex++)
{
if(0!=((pInfo->rgCertPolicyId)[dwIndex].cCertPolicyElementId))
{
//concatecate the comma if not the 1st item
if(0!=wcslen(pwsz))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
if(!FormatCertPolicyID(&((pInfo->rgCertPolicyId)[dwIndex]), &pwszPolicy))
goto FormatCertPolicyIDError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_RES_ID_MULTI;
else
ids=IDS_KEY_RES_ID;
if(!FormatMessageUnicode(&pwszPolicyFormat, ids,dwIndex+1,pwszPolicy))
goto FormatMsgError;
//allocate memory, including the ", "
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszPolicyFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszPolicyFormat);
free(pwszPolicy);
pwszPolicy=NULL;
LocalFree((HLOCAL)pwszPolicyFormat);
pwszPolicyFormat=NULL;
}
}
//format the RestrictedKeyUsage
if(0!=pInfo->RestrictedKeyUsage.cbData)
{
//concatecate the comma if not the 1st item
if(0!=wcslen(pwsz))
{
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
cbNeeded=0;
if(!FormatKeyUsageBLOB(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->RestrictedKeyUsage),
NULL,
&cbNeeded))
goto FormatKeyUsageBLOBError;
pwszKeyUsage=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyUsage)
goto MemoryError;
if(!FormatKeyUsageBLOB(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->RestrictedKeyUsage),
pwszKeyUsage,
&cbNeeded))
goto FormatKeyUsageBLOBError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_RES_USAGE_MULTI;
else
ids=IDS_KEY_RES_USAGE;
//format the element string
if(!FormatMessageUnicode(&pwszKeyUsageFormat, ids, pwszKeyUsage))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyUsageFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyUsageFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszKeyUsageFormat);
}
if(0==wcslen(pwsz))
{
//no data
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
goto LoadStringError;
}
else
{
pwszFormat=pwsz;
pwsz=NULL;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszPolicy)
free(pwszPolicy);
if(pwszPolicyFormat)
LocalFree((HLOCAL)pwszPolicyFormat);
if(pwszKeyUsage)
free(pwszKeyUsage);
if(pwszKeyUsageFormat)
LocalFree((HLOCAL)pwszKeyUsageFormat);
if(pwszFormat)
free(pwszFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatCertPolicyIDError);
TRACE_ERROR(FormatKeyUsageBLOBError);
}
//-----------------------------------------------------------------------
//
// FormatFileTime
//
// Pre-condition: pFileTime points to valid data
//
//------------------------------------------------------------------------
BOOL FormatFileTime(FILETIME *pFileTime,LPWSTR *ppwszFormat)
{
BOOL fResult;
int cch;
int cch2;
LPWSTR psz;
SYSTEMTIME st;
FILETIME localTime;
DWORD locale;
BOOL bRTLLocale;
DWORD dwFlags = DATE_LONGDATE;
// See if the user locale id is RTL (Arabic, Urdu, Farsi or Hebrew).
locale = GetUserDefaultLCID();
bRTLLocale = ((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_URDU) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_FARSI) ||
(PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW));
locale = MAKELCID( MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT) ;
if (bRTLLocale)
{
DWORD dwLayout;
if (GetProcessDefaultLayout(&dwLayout))
{
if (dwLayout & LAYOUT_RTL)
{
dwFlags |= DATE_RTLREADING;
}
else
{
dwFlags |= DATE_LTRREADING;
}
}
else
{
dwFlags |= DATE_LTRREADING;
}
}
if (!FileTimeToLocalFileTime(pFileTime, &localTime))
{
goto ToLocalTimeError;
}
if (!FileTimeToSystemTime(&localTime, &st))
{
//
// if the conversion to local time failed, then just use the original time
//
if (!FileTimeToSystemTime(pFileTime, &st))
{
goto ToSystemTimeError;
}
}
cch = (GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) +
GetDateFormatU(locale, dwFlags, &st, NULL, NULL, 0) + 5);
if (NULL == (psz = (LPWSTR) LocalAlloc(LPTR, (cch+5) * sizeof(WCHAR))))
{
goto OutOfMemoryError;
}
cch2 = GetDateFormatU(locale, dwFlags, &st, NULL, psz, cch);
psz[cch2-1] = ' ';
GetTimeFormatU(LOCALE_USER_DEFAULT, 0, &st, NULL, &psz[cch2], cch-cch2);
*ppwszFormat = psz;
fResult = TRUE;
CommonReturn:
return fResult;
ErrorReturn:
if(*ppwszFormat)
{
LocalFree((HLOCAL)(*ppwszFormat));
*ppwszFormat=NULL;
}
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(ToLocalTimeError);
TRACE_ERROR(ToSystemTimeError);
TRACE_ERROR(OutOfMemoryError);
}
//--------------------------------------------------------------------------
//
// FormatKeyAttributes: X509_KEY_ATTRIBUTES
// szOID_KEY_ATTRIBUTES
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatKeyAttributes(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszKeyIDFormat=NULL;
LPWSTR pwszKeyID=NULL;
LPWSTR pwszKeyUsageFormat=NULL;
LPWSTR pwszKeyUsage=NULL;
LPWSTR pwszKeyBeforeFormat=NULL;
LPWSTR pwszKeyBefore=NULL;
LPWSTR pwszKeyAfterFormat=NULL;
LPWSTR pwszKeyAfter=NULL;
PCERT_KEY_ATTRIBUTES_INFO pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_ATTRIBUTES,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
if(0!=pInfo->KeyId.cbData)
{
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszKeyID=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyID)
goto MemoryError;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
pwszKeyID,
&cbNeeded))
goto FormatBytesToHexError;
//format the element string
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_ATTR_ID_MULTI;
else
ids=IDS_KEY_ATTR_ID;
if(!FormatMessageUnicode(&pwszKeyIDFormat, ids, pwszKeyID))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszKeyIDFormat);
}
//check the no data situation
if(0!=pInfo->IntendedKeyUsage.cbData)
{
//strcat a ", " symbol for signle line format
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
if(0!=wcslen(pwsz))
wcscat(pwsz, wszCOMMA);
}
cbNeeded=0;
if(!FormatKeyUsageBLOB(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->IntendedKeyUsage),
NULL,
&cbNeeded))
goto FormatKeyUsageBLOBError;
pwszKeyUsage=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyUsage)
goto MemoryError;
if(!FormatKeyUsageBLOB(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->IntendedKeyUsage),
pwszKeyUsage,
&cbNeeded))
goto FormatKeyUsageBLOBError;
//format the element string
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_ATTR_USAGE_MULTI;
else
ids=IDS_KEY_ATTR_USAGE;
if(!FormatMessageUnicode(&pwszKeyUsageFormat, ids, pwszKeyUsage))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyUsageFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyUsageFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszKeyUsageFormat);
}
if(NULL!=pInfo->pPrivateKeyUsagePeriod)
{
//format only if there is some information
if(!((0==pInfo->pPrivateKeyUsagePeriod->NotBefore.dwHighDateTime)
&&(0==pInfo->pPrivateKeyUsagePeriod->NotBefore.dwLowDateTime)))
{
//strcat a ", " symbol for signle line format
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
if(0!=wcslen(pwsz))
wcscat(pwsz, wszCOMMA);
}
if(!FormatFileTime(&(pInfo->pPrivateKeyUsagePeriod->NotBefore),
&pwszKeyBefore))
goto FormatFileTimeError;
//format the element string
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_ATTR_BEFORE_MULTI;
else
ids=IDS_KEY_ATTR_BEFORE;
if(!FormatMessageUnicode(&pwszKeyBeforeFormat, ids,
pwszKeyBefore))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR)*(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyBeforeFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR)*(wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyBeforeFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszKeyBeforeFormat);
}
if(!((0==pInfo->pPrivateKeyUsagePeriod->NotAfter.dwHighDateTime)
&&(0==pInfo->pPrivateKeyUsagePeriod->NotAfter.dwLowDateTime)))
{
//strcat a ", " symbol for signle line format
if(0== (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
if(0!=wcslen(pwsz))
wcscat(pwsz, wszCOMMA);
}
if(!FormatFileTime(&(pInfo->pPrivateKeyUsagePeriod->NotAfter),
&pwszKeyAfter))
goto FormatFileTimeError;
//format the element string
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_KEY_ATTR_AFTER_MULTI;
else
ids=IDS_KEY_ATTR_AFTER;
if(!FormatMessageUnicode(&pwszKeyAfterFormat, ids,
pwszKeyAfter))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyAfterFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyAfterFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszKeyAfterFormat);
}
}
if(0==wcslen(pwsz))
{
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat,NO_INFO_SIZE))
goto LoadStringError;
}
else
{
pwszFormat=pwsz;
pwsz=NULL;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszKeyIDFormat)
LocalFree((HLOCAL)pwszKeyIDFormat);
if(pwszKeyID)
free(pwszKeyID);
if(pwszKeyUsageFormat)
LocalFree((HLOCAL)pwszKeyUsageFormat);
if(pwszKeyUsage)
free(pwszKeyUsage);
if(pwszKeyBeforeFormat)
LocalFree((HLOCAL)pwszKeyBeforeFormat);
if(pwszKeyBefore)
LocalFree((HLOCAL)pwszKeyBefore);
if(pwszKeyAfterFormat)
LocalFree((HLOCAL)pwszKeyAfterFormat);
if(pwszKeyAfter)
LocalFree((HLOCAL)pwszKeyAfter);
if(pwszFormat)
free(pwszFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatKeyUsageBLOBError);
TRACE_ERROR(FormatFileTimeError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatAuthortiyInfoAccess: X509_AUTHORITY_INFO_ACCESS
// szOID_AUTHORITY_INFO_ACCESS
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAuthortiyInfoAccess(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fMethodAllocated=FALSE;
WCHAR wszNoInfo[NO_INFO_SIZE];
WCHAR wszUnknownAccess[UNKNOWN_ACCESS_METHOD_SIZE];
PCCRYPT_OID_INFO pOIDInfo=NULL;
CERT_ALT_NAME_INFO CertAltNameInfo;
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszMethod=NULL;
LPWSTR pwszAltName=NULL;
LPWSTR pwszEntryFormat=NULL;
PCERT_AUTHORITY_INFO_ACCESS pInfo=NULL;
DWORD dwIndex=0;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_INFO_ACCESS,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
if(0==pInfo->cAccDescr)
{
//load the string "Info Not Available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat=wszNoInfo;
}
else
{
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//load the string "Unknown Access Method:
if(!LoadStringU(hFrmtFuncInst,IDS_UNKNOWN_ACCESS_METHOD, wszUnknownAccess,
sizeof(wszUnknownAccess)/sizeof(wszUnknownAccess[0])))
goto LoadStringError;
for(dwIndex=0; dwIndex < pInfo->cAccDescr; dwIndex++)
{
fMethodAllocated=FALSE;
//need a ", " between each element for single line format
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) )
wcscat(pwsz, wszCOMMA);
}
//get the name of the access method
if(pInfo->rgAccDescr[dwIndex].pszAccessMethod)
{
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
(void *)(pInfo->rgAccDescr[dwIndex].pszAccessMethod),
CRYPT_EXT_OR_ATTR_OID_GROUP_ID);
//get the access method OID
if(pOIDInfo)
{
//allocate memory, including the NULL terminator
pwszMethod=(LPWSTR)malloc((wcslen(pOIDInfo->pwszName)+1)*
sizeof(WCHAR));
if(NULL==pwszMethod)
goto MemoryError;
fMethodAllocated=TRUE;
wcscpy(pwszMethod,pOIDInfo->pwszName);
}else
pwszMethod=wszUnknownAccess;
}
memset(&CertAltNameInfo, 0, sizeof(CERT_ALT_NAME_INFO));
CertAltNameInfo.cAltEntry=1;
CertAltNameInfo.rgAltEntry=&(pInfo->rgAccDescr[dwIndex].AccessLocation);
//need to tell if it is for multi line format. We need two \t\t
//in front of each alt name entry
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_TWO_TABS;
else
ids=0;
//get the alternative name entry
cbNeeded=0;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&CertAltNameInfo,
NULL,
&cbNeeded))
goto FormatAltNameError;
pwszAltName=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszAltName)
goto MemoryError;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&CertAltNameInfo,
pwszAltName,
&cbNeeded))
goto FormatAltNameError;
//format the entry
if(pInfo->rgAccDescr[dwIndex].pszAccessMethod)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AUTHORITY_ACCESS_INFO_MULTI;
else
ids=IDS_AUTHORITY_ACCESS_INFO;
if(!FormatMessageUnicode(&pwszEntryFormat, ids,
dwIndex+1, pwszMethod, pInfo->rgAccDescr[dwIndex].pszAccessMethod,
pwszAltName))
goto FormatMsgError;
}
else
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AUTHORITY_ACCESS_NO_METHOD_MULTI;
else
ids=IDS_AUTHORITY_ACCESS_NO_METHOD;
if(!FormatMessageUnicode(&pwszEntryFormat, ids, dwIndex+1, pwszAltName))
goto FormatMsgError;
}
//reallocat the memory. Leave space for szComma
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszEntryFormat)+
wcslen(wszCOMMA)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszEntryFormat)+
wcslen(wszCOMMA)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, pwszEntryFormat);
//free memory
LocalFree((HLOCAL)pwszEntryFormat);
pwszEntryFormat=NULL;
free(pwszAltName);
pwszAltName=NULL;
if(TRUE==fMethodAllocated)
free(pwszMethod);
pwszMethod=NULL;
}
//convert to WCHAR
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwsz)
free(pwsz);
if(pwszEntryFormat)
LocalFree((HLOCAL)pwszEntryFormat);
if(pwszAltName)
free(pwszAltName);
if(fMethodAllocated)
{
if(pwszMethod)
free(pwszMethod);
}
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(FormatAltNameError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatKeyUsageBLOB
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatKeyUsageBLOB(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
PCRYPT_BIT_BLOB pInfo,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFinal=NULL;
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszByte=NULL;
WCHAR wszKeyUsage[KEY_USAGE_SIZE+1];
DWORD cbNeeded=0;
BOOL fResult=FALSE;
LPWSTR pwszTemp;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//format the 1st byte
if(pInfo->pbData[0] & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
{
if(!LoadStringU(hFrmtFuncInst, IDS_DIG_SIG, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_NON_REPUDIATION_KEY_USAGE)
{
if(!LoadStringU(hFrmtFuncInst, IDS_NON_REPUDIATION, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_KEY_ENCIPHERMENT_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_KEY_ENCIPHERMENT, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_DATA_ENCIPHERMENT_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_DATA_ENCIPHERMENT, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_KEY_AGREEMENT_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_KEY_AGREEMENT, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_KEY_CERT_SIGN_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_CERT_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_OFFLINE_CRL_SIGN_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_OFFLINE_CRL_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_CRL_SIGN_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_CRL_SIGN, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
if(pInfo->pbData[0] & CERT_ENCIPHER_ONLY_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_ENCIPHER_ONLY, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
//deal with the second byte
if(pInfo->cbData>=2)
{
if(pInfo->pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE )
{
if(!LoadStringU(hFrmtFuncInst, IDS_DECIPHER_ONLY, wszKeyUsage, KEY_USAGE_SIZE))
goto LoadStringError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszKeyUsage)+1+wcslen(wszCOMMA)));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz, wszKeyUsage);
wcscat(pwsz, wszCOMMA);
}
}
if(0==wcslen(pwsz))
{
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (UNKNOWN_KEY_USAGE_SIZE+1));
// if(NULL==pwszFormat) DSIE: Bug 27348
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz, sizeof(WCHAR) * (UNKNOWN_KEY_USAGE_SIZE+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
if(!LoadStringU(hFrmtFuncInst, IDS_UNKNOWN_KEY_USAGE, pwsz,
UNKNOWN_KEY_USAGE_SIZE))
goto LoadStringError;
}
else
{
//get rid of the last comma
*(pwsz+wcslen(pwsz)-wcslen(wszCOMMA))=L'\0';
}
//get the Hex dump of the Key Usage
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszByte=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszByte)
goto MemoryError;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo->pbData,
pInfo->cbData,
pwszByte,
&cbNeeded))
goto FormatBytesToHexError;
//convert the WSZ
if(!FormatMessageUnicode(&pwszFormat, IDS_BIT_BLOB, pwsz,
pwszByte))
goto FormatMsgError;
//
// DSIE: Fix bug 91502, 256396.
//
pwszFinal=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormat)+1+wcslen(wszCRLF)));
if(NULL==pwszFinal)
goto MemoryError;
wcscpy(pwszFinal, pwszFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwszFinal, wszCRLF);
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFinal)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFinal, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if (pwszFinal)
free(pwszFinal);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
if(pwsz)
free(pwsz);
if(pwszByte)
free(pwszByte);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatKeyUsage: X509_KEY_USAGE
// szOID_KEY_USAGE
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatKeyUsage(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
WCHAR wszNoInfo[NO_INFO_SIZE];
PCRYPT_BIT_BLOB pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_KEY_USAGE,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string "Info Not Available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
//check the no data situation
if(0==pInfo->cbData)
pwszFormat=wszNoInfo;
else
{
if(1==pInfo->cbData)
{
if(0==pInfo->pbData[0])
pwszFormat=wszNoInfo;
}
else
{
if(2==pInfo->cbData)
{
if((0==pInfo->pbData[0])&&(0==pInfo->pbData[1]))
pwszFormat=wszNoInfo;
}
}
}
if(NULL==pwszFormat)
{
fResult=FormatKeyUsageBLOB(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
pInfo,
pbFormat,
pcbFormat);
if(FALSE==fResult)
goto FormatKeyUsageBLOBError;
}
else
{
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
}
CommonReturn:
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatKeyUsageBLOBError);
}
//--------------------------------------------------------------------------
//
// FormatSMIMECapabilities: PKCS_SMIME_CAPABILITIES
// szOID_RSA_SMIMECapabilities
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatSMIMECapabilities(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszElementFormat=NULL;
LPWSTR pwszParam=NULL;
WCHAR wszNoInfo[NO_INFO_SIZE];
BOOL fParamAllocated=FALSE;
PCRYPT_SMIME_CAPABILITIES pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
DWORD dwIndex =0;
UINT idsSub=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,PKCS_SMIME_CAPABILITIES,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//check to see if information if available
if(0==pInfo->cCapability)
{
//load the string "Info Not Available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat=wszNoInfo;
}
else
{
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
for(dwIndex=0; dwIndex < pInfo->cCapability; dwIndex++)
{
fParamAllocated=FALSE;
//strcat ", " if single line. No need for multi-line
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
if(0!=(pInfo->rgCapability)[dwIndex].Parameters.cbData)
{
cbNeeded=0;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
(pInfo->rgCapability)[dwIndex].Parameters.pbData,
(pInfo->rgCapability)[dwIndex].Parameters.cbData,
NULL,
&cbNeeded))
goto FormatBytesToHexError;
pwszParam=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszParam)
goto MemoryError;
fParamAllocated=TRUE;
if(!FormatBytesToHex(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
(pInfo->rgCapability)[dwIndex].Parameters.pbData,
(pInfo->rgCapability)[dwIndex].Parameters.cbData,
pwszParam,
&cbNeeded))
goto FormatBytesToHexError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_MIME_CAPABILITY_MULTI;
else
idsSub=IDS_MIME_CAPABILITY;
//format the element string
if(!FormatMessageUnicode(&pwszElementFormat, idsSub,
dwIndex+1,
(pInfo->rgCapability)[dwIndex].pszObjId,
pwszParam))
goto FormatMsgError;
}
else
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_MIME_CAPABILITY_NO_PARAM_MULTI;
else
idsSub=IDS_MIME_CAPABILITY_NO_PARAM;
//format the element string
if(!FormatMessageUnicode(&pwszElementFormat, idsSub,
dwIndex+1,
(pInfo->rgCapability)[dwIndex].pszObjId))
goto FormatMsgError;
}
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszElementFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszElementFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
//strcat the element
wcscat(pwsz, pwszElementFormat);
//free the memory
LocalFree((HLOCAL)pwszElementFormat);
pwszElementFormat=NULL;
if(fParamAllocated)
free(pwszParam);
pwszParam=NULL;
}
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszElementFormat)
LocalFree((HLOCAL)pwszElementFormat);
if(fParamAllocated)
{
if(pwszParam)
free(pwszParam);
}
if(pInfo)
free(pInfo);
if(pwsz)
free(pwsz);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
}
//--------------------------------------------------------------------------
//
// FormatFinancialCriteria: SPC_FINANCIAL_CRITERIA_OBJID
// SPC_FINANCIAL_CRITERIA_STRUCT
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatFinancialCriteria(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
WCHAR wszYesNo[YES_NO_SIZE];
WCHAR wszAvailable[AVAIL_SIZE];
PSPC_FINANCIAL_CRITERIA pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT idsInfo=0;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,SPC_FINANCIAL_CRITERIA_STRUCT,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string for financial info
if(TRUE==pInfo->fFinancialInfoAvailable)
{
if(TRUE==pInfo->fMeetsCriteria)
idsInfo=IDS_YES;
else
idsInfo=IDS_NO;
//load the string for "yes" or "no"
if(!LoadStringU(hFrmtFuncInst,idsInfo, wszYesNo, sizeof(wszYesNo)/sizeof(wszYesNo[0])))
goto LoadStringError;
//mark the avaiblility of the financial info
idsInfo=IDS_AVAILABLE;
}
else
idsInfo=IDS_NOT_AVAILABLE;
if(!LoadStringU(hFrmtFuncInst,idsInfo, wszAvailable,
sizeof(wszAvailable)/sizeof(wszAvailable[0])))
goto LoadStringError;
//format the output string
if(TRUE==pInfo->fFinancialInfoAvailable)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsInfo=IDS_SPC_FINANCIAL_AVAIL_MULTI;
else
idsInfo=IDS_SPC_FINANCIAL_AVAIL;
if(!FormatMessageUnicode(&pwszFormat, idsInfo,
wszAvailable, wszYesNo))
goto FormatMsgError;
}
else
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsInfo=IDS_SPC_FINANCIAL_NOT_AVAIL_MULTI;
else
idsInfo=IDS_SPC_FINANCIAL_NOT_AVAIL;
if(!FormatMessageUnicode(&pwszFormat, idsInfo,
wszAvailable))
goto FormatMsgError;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatNextUpdateLocation: szOID_NEXT_UPDATE_LOCATION
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatNextUpdateLocation(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
PCERT_ALT_NAME_INFO pInfo=NULL;
BOOL fResult=FALSE;
//check for input parameters
if((NULL==pbEncoded && cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,szOID_NEXT_UPDATE_LOCATION,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//format the alternative name
fResult=FormatAltNameInfo(dwCertEncodingType, dwFormatType,dwFormatStrType,
pFormatStruct,
0, //no prefix
TRUE,
pInfo, pbFormat, pcbFormat);
if(FALSE==fResult)
goto FormatAltNameError;
CommonReturn:
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatAltNameError);
}
//--------------------------------------------------------------------------
//
// FormatSubjectKeyID: szOID_SUBJECT_KEY_IDENTIFIER
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatSubjectKeyID(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
PCRYPT_DATA_BLOB pInfo=NULL;
BOOL fResult=FALSE;
WCHAR wszNoInfo[NO_INFO_SIZE];
DWORD cbNeeded=0;
// DSIE: Fix bug 91502
LPWSTR pwsz=NULL;
LPWSTR pwszFormat=NULL;
LPWSTR pwszKeyID=NULL;
LPWSTR pwszKeyIDFormat=NULL;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded && cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,szOID_SUBJECT_KEY_IDENTIFIER,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//format the key subject ID
//handle NULL data case
if(0==pInfo->cbData)
{
//load the string "Info Not Available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat = wszNoInfo;
}
else
{
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
cbNeeded=0;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->pbData,
pInfo->cbData,
NULL,
&cbNeeded))
goto KeyIDBytesToHexError;
pwszKeyID=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyID)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->pbData,
pInfo->cbData,
pwszKeyID,
&cbNeeded))
goto KeyIDBytesToHexError;
if(!FormatMessageUnicode(&pwszKeyIDFormat,IDS_UNICODE_STRING,pwszKeyID))
goto FormatMsgError;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyIDFormat)+wcslen(wszCRLF)+1));
else
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(pwszKeyIDFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
//strcat the KeyID
wcscat(pwsz,pwszKeyIDFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszKeyID)
free(pwszKeyID);
if(pwszKeyIDFormat)
LocalFree((HLOCAL)pwszKeyIDFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(KeyIDBytesToHexError);
//TRACE_ERROR(FormatBytestToHexError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatAuthorityKeyID: szOID_AUTHORITY_KEY_IDENTIFIER
// X509_AUTHORITY_KEY_ID
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAuthorityKeyID(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszKeyID=NULL;
LPWSTR pwszKeyIDFormat=NULL;
LPWSTR pwszCertIssuer=NULL;
LPWSTR pwszCertIssuerFormat=NULL;
LPWSTR pwszCertNumber=NULL;
LPWSTR pwszCertNumberFormat=NULL;
BYTE *pByte=NULL;
DWORD dwByteIndex=0;
WCHAR wszNoInfo[NO_INFO_SIZE];
PCERT_AUTHORITY_KEY_ID_INFO pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded && cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_KEY_ID,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string "Info Not Available"
if((0==pInfo->KeyId.cbData)&&(0==pInfo->CertIssuer.cbData)
&&(0==pInfo->CertSerialNumber.cbData))
{
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat=wszNoInfo;
}
else
{
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//format the three fields in the struct: KeyID; CertIssuer; CertSerialNumber
if(0!=pInfo->KeyId.cbData)
{
cbNeeded=0;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
NULL,
&cbNeeded))
goto KeyIDBytesToHexError;
pwszKeyID=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyID)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
pwszKeyID,
&cbNeeded))
goto KeyIDBytesToHexError;
if(!FormatMessageUnicode(&pwszKeyIDFormat, IDS_AUTH_KEY_ID,pwszKeyID))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
#if (0) //DSIE: Potential AV. Need two more chars, \r\n, for multi-lines.
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
#else
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+wcslen(wszCRLF)+1));
else
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszKeyIDFormat)+1));
#endif
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
//strcat the KeyID
wcscat(pwsz,pwszKeyIDFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
}
//format certIssuer
if(0!=pInfo->CertIssuer.cbData)
{
//strcat ", " if there is data before
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
if(!CryptDllFormatNameAll(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
IDS_ONE_TAB,
TRUE, //memory allocation
pInfo->CertIssuer.pbData,
pInfo->CertIssuer.cbData,
(void **)&pwszCertIssuer,
NULL))
goto GetCertNameError;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_AUTH_CERT_ISSUER_MULTI;
else
ids=IDS_AUTH_CERT_ISSUER;
if(!FormatMessageUnicode(&pwszCertIssuerFormat, ids,pwszCertIssuer))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertIssuerFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertIssuerFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz,pwszCertIssuerFormat);
//no need for \n for CERT_NAME
}
//format CertSerialNumber
if(0!=pInfo->CertSerialNumber.cbData)
{
//strcat ", " if there is data before
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
//copy the serial number into the correct order
pByte=(BYTE *)malloc(pInfo->CertSerialNumber.cbData);
if(NULL==pByte)
goto MemoryError;
for(dwByteIndex=0; dwByteIndex <pInfo->CertSerialNumber.cbData;
dwByteIndex++)
{
pByte[dwByteIndex]=*(pInfo->CertSerialNumber.pbData+
pInfo->CertSerialNumber.cbData-1-dwByteIndex);
}
cbNeeded=0;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pByte,
pInfo->CertSerialNumber.cbData,
NULL,
&cbNeeded))
goto CertNumberBytesToHexError;
pwszCertNumber=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszCertNumber)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pByte,
pInfo->CertSerialNumber.cbData,
pwszCertNumber,
&cbNeeded))
goto CertNumberBytesToHexError;
if(!FormatMessageUnicode(&pwszCertNumberFormat, IDS_AUTH_CERT_NUMBER,pwszCertNumber))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertNumberFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszCertNumberFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz,pwszCertNumberFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
}
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pByte)
free(pByte);
if(pwszKeyID)
free(pwszKeyID);
if(pwszKeyIDFormat)
LocalFree((HLOCAL)pwszKeyIDFormat);
if(pwszCertIssuer)
free(pwszCertIssuer);
if(pwszCertIssuerFormat)
LocalFree((HLOCAL)pwszCertIssuerFormat);
if(pwszCertNumber)
free(pwszCertNumber);
if(pwszCertNumberFormat)
LocalFree((HLOCAL)pwszCertNumberFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(KeyIDBytesToHexError);
TRACE_ERROR(GetCertNameError);
TRACE_ERROR(CertNumberBytesToHexError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatAuthorityKeyID2: szOID_AUTHORITY_KEY_IDENTIFIER2
// X509_AUTHORITY_KEY_ID2
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAuthorityKeyID2(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszKeyID=NULL;
LPWSTR pwszKeyIDFormat=NULL;
LPWSTR pwszCertIssuer=NULL;
LPWSTR pwszCertIssuerFormat=NULL;
LPWSTR pwszCertNumber=NULL;
LPWSTR pwszCertNumberFormat=NULL;
BYTE *pByte=NULL;
DWORD dwByteIndex=0;
WCHAR wszNoInfo[NO_INFO_SIZE];
PCERT_AUTHORITY_KEY_ID2_INFO pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT ids=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded && cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_AUTHORITY_KEY_ID2,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string "Info Not Available"
if((0==pInfo->KeyId.cbData)&&(0==pInfo->AuthorityCertIssuer.cAltEntry)
&&(0==pInfo->AuthorityCertSerialNumber.cbData))
{
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat=wszNoInfo;
}
else
{
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//format the three fields in the struct: KeyID; CertIssuer; CertSerialNumber
if(0!=pInfo->KeyId.cbData)
{
cbNeeded=0;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
NULL,
&cbNeeded))
goto KeyIDBytesToHexError;
pwszKeyID=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszKeyID)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pInfo->KeyId.pbData,
pInfo->KeyId.cbData,
pwszKeyID,
&cbNeeded))
goto KeyIDBytesToHexError;
if(!FormatMessageUnicode(&pwszKeyIDFormat, IDS_AUTH_KEY_ID,pwszKeyID))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+
wcslen(pwszKeyIDFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+
wcslen(pwszKeyIDFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz,pwszKeyIDFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
}
//format certIssuer
if(0!=pInfo->AuthorityCertIssuer.cAltEntry)
{
//strcat ", " if there is data before
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
cbNeeded=0;
//need a \t before each entry of the alternative name
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
ids=IDS_ONE_TAB;
else
ids=0;
//format the alternative name
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->AuthorityCertIssuer),
NULL,
&cbNeeded))
goto FormatAltNameError;
pwszCertIssuer=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszCertIssuer)
goto MemoryError;
if(!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&(pInfo->AuthorityCertIssuer),
pwszCertIssuer,
&cbNeeded))
goto FormatAltNameError;
//format the element. Has to distinguish between the multi line
//and single line for alternative name:
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
{
if(!FormatMessageUnicode(&pwszCertIssuerFormat, IDS_AUTH_CERT_ISSUER_MULTI,pwszCertIssuer))
goto FormatMsgError;
}
else
{
if(!FormatMessageUnicode(&pwszCertIssuerFormat, IDS_AUTH_CERT_ISSUER,pwszCertIssuer))
goto FormatMsgError;
}
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
+wcslen(pwszCertIssuerFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
+wcslen(pwszCertIssuerFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz,pwszCertIssuerFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
}
//format CertSerialNumber
if(0!=pInfo->AuthorityCertSerialNumber.cbData)
{
//strcat ", " if there is data before
if(0!=wcslen(pwsz))
{
if(0==(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
wcscat(pwsz, wszCOMMA);
}
//copy the serial number into the correct order
pByte=(BYTE *)malloc(pInfo->AuthorityCertSerialNumber.cbData);
if(NULL==pByte)
goto MemoryError;
for(dwByteIndex=0; dwByteIndex <pInfo->AuthorityCertSerialNumber.cbData;
dwByteIndex++)
{
pByte[dwByteIndex]=*(pInfo->AuthorityCertSerialNumber.pbData+
pInfo->AuthorityCertSerialNumber.cbData-1-dwByteIndex);
}
cbNeeded=0;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pByte,
pInfo->AuthorityCertSerialNumber.cbData,
NULL,
&cbNeeded))
goto CertNumberBytesToHexError;
pwszCertNumber=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszCertNumber)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
NULL,
NULL,
pByte,
pInfo->AuthorityCertSerialNumber.cbData,
pwszCertNumber,
&cbNeeded))
goto CertNumberBytesToHexError;
if(!FormatMessageUnicode(&pwszCertNumberFormat, IDS_AUTH_CERT_NUMBER,pwszCertNumber))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
+wcslen(pwszCertNumberFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)
+wcslen(pwszCertNumberFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
wcscat(pwsz,pwszCertNumberFormat);
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
}
//convert the WCHAR version
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pByte)
free(pByte);
if(pwszKeyID)
free(pwszKeyID);
if(pwszKeyIDFormat)
LocalFree((HLOCAL)pwszKeyIDFormat);
if(pwszCertIssuer)
free(pwszCertIssuer);
if(pwszCertIssuerFormat)
LocalFree((HLOCAL)pwszCertIssuerFormat);
if(pwszCertNumber)
free(pwszCertNumber);
if(pwszCertNumberFormat)
LocalFree((HLOCAL)pwszCertNumberFormat);
if(pwsz)
free(pwsz);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(KeyIDBytesToHexError);
TRACE_ERROR(FormatAltNameError);
TRACE_ERROR(CertNumberBytesToHexError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatBasicConstraints: szOID_BASIC_CONSTRAINTS
// X509_BASIC_CONSTRAINTS
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatBasicConstraints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
WCHAR wszSubject[SUBJECT_SIZE * 2];
WCHAR wszNone[NONE_SIZE];
LPWSTR pwszFormatSub=NULL;
LPWSTR pwszFormatWhole=NULL;
LPWSTR pwszSubtreeName=NULL;
LPWSTR pwszSubtreeFormat=NULL;
DWORD dwIndex=0;
PCERT_BASIC_CONSTRAINTS_INFO pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT idsSub=0;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_BASIC_CONSTRAINTS,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load the string for the subjectType
//init to "\0"
*wszSubject=L'\0';
if(0!=pInfo->SubjectType.cbData)
{
//get the subjectType info
if ((pInfo->SubjectType.pbData[0]) & CERT_CA_SUBJECT_FLAG)
{
if(!LoadStringU(hFrmtFuncInst,IDS_SUB_CA, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
goto LoadStringError;
}
if ((pInfo->SubjectType.pbData[0]) & CERT_END_ENTITY_SUBJECT_FLAG)
{
if(wcslen(wszSubject)!=0)
{
wcscat(wszSubject, wszCOMMA);
}
if(!LoadStringU(hFrmtFuncInst,IDS_SUB_EE, wszSubject+wcslen(wszSubject),
SUBJECT_SIZE))
goto LoadStringError;
}
//load string "NONE"
if(0==wcslen(wszSubject))
{
if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszSubject, sizeof(wszSubject)/sizeof(wszSubject[0])))
goto LoadStringError;
}
}
//path contraints
if (pInfo->fPathLenConstraint)
{
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_BASIC_CONS2_PATH_MULTI;
else
idsSub=IDS_BASIC_CONS2_PATH;
if(!FormatMessageUnicode(&pwszFormatSub,idsSub,
wszSubject, pInfo->dwPathLenConstraint))
goto FormatMsgError;
}
else
{
if(!LoadStringU(hFrmtFuncInst,IDS_NONE, wszNone, sizeof(wszNone)/sizeof(wszNone[0])))
goto LoadStringError;
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_BASIC_CONS2_NONE_MULTI;
else
idsSub=IDS_BASIC_CONS2_NONE;
if(!FormatMessageUnicode(&pwszFormatSub,idsSub,
wszSubject, wszNone))
goto FormatMsgError;
}
pwszFormatWhole=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszFormatSub)+1));
if(!pwszFormatWhole)
goto MemoryError;
wcscpy(pwszFormatWhole, pwszFormatSub);
//now, format SubTreeContraints one at a time
for(dwIndex=0; dwIndex<pInfo->cSubtreesConstraint; dwIndex++)
{
//get WCHAR version of the name
if(!CryptDllFormatNameAll(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
IDS_ONE_TAB,
TRUE, //memory allocation
pInfo->rgSubtreesConstraint[dwIndex].pbData,
pInfo->rgSubtreesConstraint[dwIndex].cbData,
(void **)&pwszSubtreeName,
NULL))
goto GetCertNameError;
//decide between single line and mulitple line format
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsSub=IDS_SUBTREE_CONSTRAINT_MULTI;
else
idsSub=IDS_SUBTREE_CONSTRAINT;
if(!FormatMessageUnicode(&pwszSubtreeFormat,idsSub,
dwIndex+1, pwszSubtreeName))
goto FormatNameError;
#if (0) // DSIE: Bug 27436
pwszFormatWhole=(LPWSTR)realloc(pwszFormatWhole,
sizeof(WCHAR) * (wcslen(pwszFormatWhole)+1+wcslen(pwszSubtreeFormat)));
if(NULL == pwszFormatWhole)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwszFormatWhole,
sizeof(WCHAR) * (wcslen(pwszFormatWhole)+1+wcslen(pwszSubtreeFormat)));
if(NULL == pwszTemp)
goto MemoryError;
pwszFormatWhole = pwszTemp;
wcscat(pwszFormatWhole,pwszSubtreeFormat);
LocalFree((HLOCAL)pwszSubtreeFormat);
pwszSubtreeFormat=NULL;
free(pwszSubtreeName);
pwszSubtreeName=NULL;
}
//format to the wide char version
pwszFormat=pwszFormatWhole;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszFormatSub)
LocalFree((HLOCAL)pwszFormatSub);
if(pwszSubtreeFormat)
LocalFree((HLOCAL)pwszSubtreeFormat);
if(pwszFormatWhole)
free(pwszFormatWhole);
if(pwszSubtreeName)
free(pwszSubtreeName);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
TRACE_ERROR(FormatNameError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(GetCertNameError);
}
//--------------------------------------------------------------------------
//
// FormatCRLReasonCode:szOID_CRL_REASON_CODE
// X509_CRL_REASON_CODE
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatCRLReasonCode(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
WCHAR wszReason[CRL_REASON_SIZE];
LPWSTR pwszFormat=NULL;
int *pInfo=NULL;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
UINT idsCRLReason=0;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_CRL_REASON_CODE,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//decide which ids to use
switch(*pInfo)
{
case CRL_REASON_UNSPECIFIED:
idsCRLReason=IDS_UNSPECIFIED;
break;
case CRL_REASON_KEY_COMPROMISE:
idsCRLReason=IDS_KEY_COMPROMISE;
break;
case CRL_REASON_CA_COMPROMISE:
idsCRLReason=IDS_CA_COMPROMISE;
break;
case CRL_REASON_AFFILIATION_CHANGED:
idsCRLReason=IDS_AFFILIATION_CHANGED;
break;
case CRL_REASON_SUPERSEDED:
idsCRLReason=IDS_SUPERSEDED;
break;
case CRL_REASON_CESSATION_OF_OPERATION:
idsCRLReason=IDS_CESSATION_OF_OPERATION;
break;
case CRL_REASON_CERTIFICATE_HOLD:
idsCRLReason=IDS_CERTIFICATE_HOLD;
break;
case CRL_REASON_REMOVE_FROM_CRL:
idsCRLReason=IDS_REMOVE_FROM_CRL;
break;
default:
idsCRLReason=IDS_UNKNOWN_CRL_REASON;
break;
}
//load string
if(!LoadStringU(hFrmtFuncInst,idsCRLReason, wszReason, sizeof(wszReason)/sizeof(wszReason[0])))
goto LoadStringError;
//format
if(!FormatMessageUnicode(&pwszFormat, IDS_CRL_REASON, wszReason, *pInfo))
goto FormatMsgError;
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatEnhancedKeyUsage: szOID_ENHANCED_KEY_USAGE
// X509_ENHANCED_KEY_USAGE
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatEnhancedKeyUsage(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fOIDNameAllocated=FALSE;
WCHAR wszNoInfo[NO_INFO_SIZE];
WCHAR wszUnknownOID[UNKNOWN_KEY_USAGE_SIZE];
PCCRYPT_OID_INFO pOIDInfo=NULL;
LPWSTR pwszFormat=NULL;
LPWSTR pwszOIDName=NULL;
PCERT_ENHKEY_USAGE pInfo=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszOIDFormat=NULL;
DWORD dwIndex=0;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
LPWSTR pwszTemp;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_ENHANCED_KEY_USAGE,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//load string NONE if there is no value available
if(0==pInfo->cUsageIdentifier)
{
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
pwszFormat=wszNoInfo;
}
else
{
//load the string for "unknown key usage"
if(!LoadStringU(hFrmtFuncInst,IDS_UNKNOWN_KEY_USAGE, wszUnknownOID,
sizeof(wszUnknownOID)/sizeof(wszUnknownOID[0])))
goto LoadStringError;
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
*pwsz=L'\0';
//build the comma/\n seperated string
for(dwIndex=0; dwIndex<pInfo->cUsageIdentifier; dwIndex++)
{
fOIDNameAllocated=FALSE;
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
(void *)(pInfo->rgpszUsageIdentifier[dwIndex]),
CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
if(pOIDInfo)
{
//allocate memory, including the NULL terminator
pwszOIDName=(LPWSTR)malloc((wcslen(pOIDInfo->pwszName)+1)*
sizeof(WCHAR));
if(NULL==pwszOIDName)
goto MemoryError;
fOIDNameAllocated=TRUE;
wcscpy(pwszOIDName,pOIDInfo->pwszName);
}else
pwszOIDName=wszUnknownOID;
if(!FormatMessageUnicode(&pwszOIDFormat, IDS_ENHANCED_KEY_USAGE, pwszOIDName,
(pInfo->rgpszUsageIdentifier)[dwIndex]))
goto FormatMsgError;
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+
wcslen(wszCOMMA)+wcslen(pwszOIDFormat)+1));
if(NULL==pwsz)
goto MemoryError;
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+
wcslen(wszCOMMA)+wcslen(pwszOIDFormat)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
//strcat the OID
wcscat(pwsz, pwszOIDFormat);
//strcat the , or '\n'
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(pwsz, wszCRLF);
else
{
if(dwIndex!=(pInfo->cUsageIdentifier-1))
wcscat(pwsz, wszCOMMA);
}
LocalFree((HLOCAL)pwszOIDFormat);
pwszOIDFormat=NULL;
if(fOIDNameAllocated)
free(pwszOIDName);
pwszOIDName=NULL;
}
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwsz)
free(pwsz);
if(pwszOIDFormat)
LocalFree((HLOCAL)pwszOIDFormat);
if(fOIDNameAllocated)
{
if(pwszOIDName)
free(pwszOIDName);
}
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// GetOtherName:
//
// The idsPreFix is for multi line formatting only.
// It should never be 0.
//--------------------------------------------------------------------------
BOOL GetOtherName( DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
CERT_OTHER_NAME *pOtherName,
UINT idsPreFix,
LPWSTR *ppwszOtherName)
{
BOOL fResult=FALSE;
PCCRYPT_OID_INFO pOIDInfo=NULL;
DWORD cbSize=0;
WCHAR wszPreFix[PREFIX_SIZE];
LPWSTR pwszObjId = NULL;
LPWSTR pwszName=NULL;
LPWSTR pwszFormat=NULL;
if(NULL == pOtherName || NULL == ppwszOtherName)
goto InvalidArg;
*ppwszOtherName=NULL;
//get the OID name
pOIDInfo=CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
pOtherName->pszObjId,
0);
//get the value. If OID is szOID_NT_PRINCIPAL_NAME, we format it
//as the unicode string. Otherwise, we hex dump
if(0 == strcmp(szOID_NT_PRINCIPAL_NAME, pOtherName->pszObjId))
{
//turn off the multi line here
if(!FormatAnyUnicodeStringExtension(
dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
pOtherName->pszObjId,
pOtherName->Value.pbData,
pOtherName->Value.cbData,
NULL,
&cbSize))
goto FormatUnicodeError;
pwszName=(LPWSTR)malloc(cbSize);
if(NULL==pwszName)
goto MemoryError;
if(!FormatAnyUnicodeStringExtension(
dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
pOtherName->pszObjId,
pOtherName->Value.pbData,
pOtherName->Value.cbData,
pwszName,
&cbSize))
goto FormatUnicodeError;
}
else
{
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
NULL,
pOtherName->Value.pbData,
pOtherName->Value.cbData,
NULL,
&cbSize))
goto FormatByesToHexError;
pwszName=(LPWSTR)malloc(cbSize);
if(NULL==pwszName)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType & (~CRYPT_FORMAT_STR_MULTI_LINE),
pFormatStruct,
NULL,
pOtherName->Value.pbData,
pOtherName->Value.cbData,
pwszName,
&cbSize))
goto FormatByesToHexError;
}
if(pOIDInfo)
{
if(!FormatMessageUnicode(&pwszFormat,
IDS_OTHER_NAME_OIDNAME,
pOIDInfo->pwszName,
pwszName))
goto FormatMsgError;
}
else
{
//
// Convert OID to Unicode.
//
if (!AllocateAnsiToUnicode(pOtherName->pszObjId, &pwszObjId))
goto AnsiToUnicodeError;
if(!FormatMessageUnicode(&pwszFormat,IDS_OTHER_NAME_OID, pwszObjId, pwszName))
goto FormatMsgError;
}
//copy the prefix and content
if(!LoadStringU(hFrmtFuncInst,idsPreFix, wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
goto LoadStringError;
*ppwszOtherName=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(wszPreFix) + wcslen(pwszFormat) + 1));
if(NULL == *ppwszOtherName)
goto MemoryError;
**ppwszOtherName=L'\0';
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
wcscat(*ppwszOtherName, wszPreFix);
wcscat(*ppwszOtherName, pwszFormat);
fResult=TRUE;
CommonReturn:
if (pwszObjId)
free(pwszObjId);
if(pwszName)
free(pwszName);
if(pwszFormat)
LocalFree((HLOCAL)pwszFormat);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(FormatByesToHexError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(AnsiToUnicodeError);
TRACE_ERROR(FormatUnicodeError);
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatMsgError);
}
//--------------------------------------------------------------------------
//
// FormatAltNameInfo:
//
//--------------------------------------------------------------------------
BOOL FormatAltNameInfo(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
UINT idsPreFix,
BOOL fNewLine,
PCERT_ALT_NAME_INFO pInfo,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwsz=NULL;
LPWSTR pwszAltEntryFormat=NULL;
LPWSTR pwszAltEntry=NULL;
WCHAR wszNoInfo[NO_INFO_SIZE];
WCHAR wszAltName[ALT_NAME_SIZE];
WCHAR wszPreFix[PRE_FIX_SIZE];
BOOL fEntryAllocated=FALSE;
DWORD dwIndex=0;
DWORD cbNeeded=0;
BOOL fResult=FALSE;
HRESULT hr=S_OK;
UINT idsAltEntryName=0;
LPWSTR pwszTemp;
//load the string "info not available"
if(!LoadStringU(hFrmtFuncInst,IDS_NO_ALT_NAME, wszNoInfo, sizeof(wszNoInfo)/sizeof(wszNoInfo[0])))
goto LoadStringError;
//build the list of alternative name entries
//1st, check if any information is available
if(0==pInfo->cAltEntry)
{
pwszFormat=wszNoInfo;
}
else
{
//load the pre-dix
if(0!=idsPreFix)
{
if(!LoadStringU(hFrmtFuncInst, idsPreFix,
wszPreFix, sizeof(wszPreFix)/sizeof(wszPreFix[0])))
goto LoadStringError;
}
pwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==pwsz)
goto MemoryError;
//NULL terminate the string
*pwsz=L'\0';
//build the list of alternative name entries
for(dwIndex=0; dwIndex<pInfo->cAltEntry; dwIndex++)
{
// DSIE: Fix bug 128630.
cbNeeded = 0;
fEntryAllocated=FALSE;
switch((pInfo->rgAltEntry)[dwIndex].dwAltNameChoice)
{
case CERT_ALT_NAME_OTHER_NAME:
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsAltEntryName=IDS_OTHER_NAME_MULTI;
else
idsAltEntryName=IDS_OTHER_NAME;
if(!GetOtherName(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
(pInfo->rgAltEntry)[dwIndex].pOtherName,
(0!=idsPreFix) ? idsPreFix+1 : IDS_ONE_TAB,
&pwszAltEntry))
goto GetOtherNameError;
fEntryAllocated=TRUE;
break;
case CERT_ALT_NAME_RFC822_NAME:
idsAltEntryName=IDS_RFC822_NAME;
pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszRfc822Name;
break;
case CERT_ALT_NAME_DNS_NAME:
idsAltEntryName=IDS_DNS_NAME;
pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszDNSName;
break;
case CERT_ALT_NAME_X400_ADDRESS:
idsAltEntryName=IDS_X400_ADDRESS;
pwszAltEntry=wszNoInfo;
break;
case CERT_ALT_NAME_DIRECTORY_NAME:
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
idsAltEntryName=IDS_DIRECTORY_NAME_MULTI;
else
idsAltEntryName=IDS_DIRECTORY_NAME;
if(!CryptDllFormatNameAll(
dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
(0!=idsPreFix) ? idsPreFix+1 : IDS_ONE_TAB,
TRUE, //memory allocation
(pInfo->rgAltEntry)[dwIndex].DirectoryName.pbData,
(pInfo->rgAltEntry)[dwIndex].DirectoryName.cbData,
(void **)&pwszAltEntry,
NULL))
goto GetCertNameError;
fEntryAllocated=TRUE;
break;
case CERT_ALT_NAME_EDI_PARTY_NAME:
idsAltEntryName=IDS_EDI_PARTY_NAME;
pwszAltEntry=wszNoInfo;
break;
case CERT_ALT_NAME_URL:
idsAltEntryName=IDS_URL;
pwszAltEntry=(pInfo->rgAltEntry)[dwIndex].pwszURL;
break;
case CERT_ALT_NAME_IP_ADDRESS:
idsAltEntryName=IDS_IP_ADDRESS;
#if (0) // DSIE: 7/25/2000
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
(pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
(pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
NULL,
&cbNeeded))
goto FormatByesToHexError;
pwszAltEntry=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszAltEntry)
goto MemoryError;
if(!FormatBytesToHex(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
(pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
(pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
pwszAltEntry,
&cbNeeded))
goto FormatByesToHexError;
#else
if (!FormatIPAddress(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
idsPreFix,
(pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
(pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
pwszAltEntry,
&cbNeeded))
goto FormatIPAddressError;
pwszAltEntry=(LPWSTR)malloc(cbNeeded);
if(NULL==pwszAltEntry)
goto MemoryError;
if (!FormatIPAddress(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
idsPreFix,
(pInfo->rgAltEntry)[dwIndex].IPAddress.pbData,
(pInfo->rgAltEntry)[dwIndex].IPAddress.cbData,
pwszAltEntry,
&cbNeeded))
goto FormatIPAddressError;
#endif
fEntryAllocated=TRUE;
break;
case CERT_ALT_NAME_REGISTERED_ID:
idsAltEntryName=IDS_REGISTERED_ID;
if(S_OK!=(hr=SZtoWSZ((pInfo->rgAltEntry)[dwIndex].pszRegisteredID,
&pwszAltEntry)))
goto SZtoWSZError;
fEntryAllocated=TRUE;
break;
default:
idsAltEntryName=IDS_UNKNOWN_VALUE;
pwszAltEntry=wszNoInfo;
break;
}
//load the alternative name string
if(!LoadStringU(hFrmtFuncInst,idsAltEntryName, wszAltName, sizeof(wszAltName)/sizeof(wszAltName[0])))
goto LoadStringError;
//format message
if(idsAltEntryName!=IDS_UNKNOWN_VALUE)
{
if(!FormatMessageUnicode(&pwszAltEntryFormat,IDS_ALT_NAME_ENTRY, wszAltName,
pwszAltEntry))
goto FormatMsgError;
}
else
{
if(!FormatMessageUnicode(&pwszAltEntryFormat,IDS_ALT_NAME_ENTRY_UNKNOWN, wszAltName,
(pInfo->rgAltEntry)[dwIndex].dwAltNameChoice))
goto FormatMsgError;
}
//concatenate the string, including the postfix and prefix if necessary
if(0!=idsPreFix)
{
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(wszPreFix)+wcslen(pwszAltEntryFormat)+1));
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(wszPreFix)+wcslen(pwszAltEntryFormat)+1));
}
else
{
#if (0) // DSIE: Bug 27436
pwsz=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszAltEntryFormat)+1));
#endif
pwszTemp=(LPWSTR)realloc(pwsz,
sizeof(WCHAR) * (wcslen(pwsz)+wcslen(wszCOMMA)+wcslen(pwszAltEntryFormat)+1));
}
#if (0) // DSIE: Bug 27436
if(NULL==pwsz)
goto MemoryError;
#endif
if(NULL==pwszTemp)
goto MemoryError;
pwsz = pwszTemp;
//strcat the preFix
if(0!=idsPreFix)
wcscat(pwsz, wszPreFix);
//strcat the entry
wcscat(pwsz, pwszAltEntryFormat);
//strcat the postFix
if(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
{
if((TRUE==fNewLine) || (dwIndex != (pInfo->cAltEntry-1)))
{
//no need for \n if the name is directory name (CERT_NAME)
//in multi line format
if(idsAltEntryName !=IDS_DIRECTORY_NAME_MULTI)
wcscat(pwsz, wszCRLF);
}
}
else
{
if(dwIndex != (pInfo->cAltEntry-1))
wcscat(pwsz, wszCOMMA);
}
LocalFree((HLOCAL)pwszAltEntryFormat);
pwszAltEntryFormat=NULL;
if(fEntryAllocated)
free(pwszAltEntry);
pwszAltEntry=NULL;
}
//if the last entry in the alternative name is IDS_DIRECTORY_NAME_MULTI,
//we need to get rid of the last \n if fNewLine is FALSE
if(FALSE==fNewLine)
{
if(idsAltEntryName==IDS_DIRECTORY_NAME_MULTI)
{
*(pwsz+wcslen(pwsz)-wcslen(wszCRLF))=L'\0';
}
}
//conver to the WCHAR format
pwszFormat=pwsz;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwsz)
free(pwsz);
if(pwszAltEntryFormat)
LocalFree((HLOCAL)pwszAltEntryFormat);
if(fEntryAllocated)
{
if(pwszAltEntry)
free(pwszAltEntry);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(FormatMsgError);
SET_ERROR_VAR(SZtoWSZError, hr);
TRACE_ERROR(GetCertNameError);
#if (0) //DSIE
TRACE_ERROR(FormatByesToHexError);
#else
TRACE_ERROR(FormatIPAddressError);
#endif
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(GetOtherNameError);
}
//--------------------------------------------------------------------------
//
// FormatAltName: X509_ALTERNATE_NAME
// szOID_SUBJECT_ALT_NAME
// szOID_ISSUER_ALT_NAME
// szOID_SUBJECT_ALT_NAME2
// szOID_ISSUER_ALT_NAME2
//
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatAltName(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult=FALSE;
PCERT_ALT_NAME_INFO pInfo=NULL;
//check for input parameters
if((NULL==pbEncoded&& cbEncoded!=0) ||
(NULL==pcbFormat))
goto InvalidArg;
if(cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType,X509_ALTERNATE_NAME,
pbEncoded,cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
fResult=FormatAltNameInfo(dwCertEncodingType, dwFormatType,dwFormatStrType,
pFormatStruct,
0,
TRUE,
pInfo, pbFormat, pcbFormat);
if(FALSE==fResult)
goto FormatAltNameError;
CommonReturn:
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatAltNameError);
}
//--------------------------------------------------------------------------
//
// GetCertNameMulti
//
// Get the multi line display of the certificate name
//--------------------------------------------------------------------------
BOOL GetCertNameMulti(LPWSTR pwszNameStr,
UINT idsPreFix,
LPWSTR *ppwsz)
{
BOOL fResult=FALSE;
WCHAR wszPreFix[PRE_FIX_SIZE];
LPWSTR pwszStart=NULL;
LPWSTR pwszEnd=NULL;
DWORD dwCopy=0;
LPWSTR pwszNameStart=NULL;
BOOL fDone=FALSE;
BOOL fInQuote=FALSE;
LPWSTR pwszTemp;
//init
*ppwsz=NULL;
//load string for the preFix
if(0!=idsPreFix && 1!=idsPreFix)
{
if(!LoadStringU(hFrmtFuncInst, idsPreFix, wszPreFix, PRE_FIX_SIZE))
goto LoadStringError;
}
*ppwsz=(LPWSTR)malloc(sizeof(WCHAR));
if(NULL==*ppwsz)
goto MemoryError;
**ppwsz=L'\0';
//now, start the search for the symbol '+' or ','
pwszStart=pwszNameStr;
pwszEnd=pwszNameStr;
//parse the whole string
for(;FALSE==fDone; pwszEnd++)
{
//mark fInQuote to TRUE if we are inside " "
if(L'\"'==*pwszEnd)
fInQuote=!fInQuote;
if((L'+'==*pwszEnd) || (L','==*pwszEnd) ||(L'\0'==*pwszEnd))
{
//make sure + and ; are not quoted
if((L'+'==*pwszEnd) || (L','==*pwszEnd))
{
if(TRUE==fInQuote)
continue;
}
//skip the leading spaces
for(;*pwszStart != L'\0'; pwszStart++)
{
if(*pwszStart != L' ')
break;
}
//we are done if NULL is reached
if(L'\0'==*pwszStart)
break;
//calculate the length to copy
dwCopy=(DWORD)(pwszEnd-pwszStart);
if(0!=idsPreFix && 1!=idsPreFix)
{
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
(wcslen(*ppwsz)+dwCopy+wcslen(wszPreFix)+wcslen(wszCRLF)+1)*sizeof(WCHAR));
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
(wcslen(*ppwsz)+dwCopy+wcslen(wszPreFix)+wcslen(wszCRLF)+1)*sizeof(WCHAR));
}
else
{
#if (0) // DSIE: Bug 27436
*ppwsz=(LPWSTR)realloc(*ppwsz,
(wcslen(*ppwsz)+dwCopy+wcslen(wszCRLF)+1)*sizeof(WCHAR));
#endif
pwszTemp=(LPWSTR)realloc(*ppwsz,
(wcslen(*ppwsz)+dwCopy+wcslen(wszCRLF)+1)*sizeof(WCHAR));
}
#if (0) // DSIE: Bug 27436
if(NULL == *ppwsz)
goto MemoryError;
#endif
if(NULL == pwszTemp)
goto MemoryError;
*ppwsz = pwszTemp;
//copy the prefix
if(0!=idsPreFix && 1!=idsPreFix)
wcscat(*ppwsz, wszPreFix);
pwszNameStart=(*ppwsz)+wcslen(*ppwsz);
//copy the string to *ppwsz
memcpy(pwszNameStart, pwszStart, dwCopy*sizeof(WCHAR));
pwszNameStart += dwCopy;
//NULL terminate the string
*pwszNameStart=L'\0';
//copy the "\n"
wcscat(*ppwsz, wszCRLF);
//reset pwszStart and pwszEnd.
pwszStart=pwszEnd+1;
if(L'\0'==*pwszEnd)
fDone=TRUE;
}
}
fResult=TRUE;
CommonReturn:
return fResult;
ErrorReturn:
if(*ppwsz)
{
free(*ppwsz);
*ppwsz=NULL;
}
fResult=FALSE;
goto CommonReturn;
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(LoadStringError);
}
//--------------------------------------------------------------------------
//
// FormatMessageUnicode
//
//--------------------------------------------------------------------------
BOOL FormatMessageUnicode(LPWSTR * ppwszFormat, UINT ids, ...)
{
// get format string from resources
WCHAR wszFormat[1000];
va_list argList;
DWORD cbMsg=0;
BOOL fResult=FALSE;
if(NULL == ppwszFormat)
goto InvalidArgErr;
#if (0) //DSIE: Bug 160605
if(!LoadStringU(hFrmtFuncInst, ids, wszFormat, sizeof(wszFormat)))
#else
if(!LoadStringU(hFrmtFuncInst, ids, wszFormat, sizeof(wszFormat) / sizeof(wszFormat[0])))
#endif
goto LoadStringError;
// format message into requested buffer
va_start(argList, ids);
cbMsg = FormatMessageU(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
wszFormat,
0, // dwMessageId
0, // dwLanguageId
(LPWSTR) (ppwszFormat),
0, // minimum size to allocate
&argList);
va_end(argList);
if(!cbMsg)
#if (1) // DSIE: Fix bug #128630
//
// FormatMessageU() will return 0 byte, if data to be
// formatted is empty. CertSrv generates extensions
// with empty data for name constraints, so we need to
// make sure we return an empty string, "", instead of
// an error and NULL pointer.
//
if (0 == GetLastError())
{
if (NULL == (*ppwszFormat = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR))))
goto MemoryError;
}
else
#endif
goto FormatMessageError;
fResult=TRUE;
CommonReturn:
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(InvalidArgErr, E_INVALIDARG);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
}
//--------------------------------------------------------------------------
//
// FormatMessageStr
//
//--------------------------------------------------------------------------
/*BOOL FormatMessageStr(LPSTR *ppszFormat,UINT ids,...)
{
// get format string from resources
CHAR szFormat[1000];
va_list argList;
BOOL fResult=FALSE;
HRESULT hr=S_OK;
if(!LoadStringA(hFrmtFuncInst, ids, szFormat, sizeof(szFormat)))
goto LoadStringError;
// format message into requested buffer
va_start(argList, ids);
if(0==FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
szFormat,
0, // dwMessageId
0, // dwLanguageId
(LPSTR) ppszFormat,
0, // minimum size to allocate
&argList))
goto FormatMessageError;
va_end(argList);
fResult=TRUE;
CommonReturn:
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatMessageError);
} */
//--------------------------------------------------------------------------
//
// Decode a generic BLOB
//
//--------------------------------------------------------------------------
BOOL DecodeGenericBLOB(DWORD dwEncodingType, LPCSTR lpszStructType,
const BYTE *pbEncoded, DWORD cbEncoded,void **ppStructInfo)
{
DWORD cbStructInfo=0;
//decode the object. No copying
if(!CryptDecodeObject(dwEncodingType,lpszStructType,pbEncoded, cbEncoded,
0,NULL, &cbStructInfo))
return FALSE;
*ppStructInfo=malloc(cbStructInfo);
if(!(*ppStructInfo))
{
SetLastError((DWORD) E_OUTOFMEMORY);
return FALSE;
}
return CryptDecodeObject(dwEncodingType,lpszStructType,pbEncoded, cbEncoded,
0,*ppStructInfo,&cbStructInfo);
}
////////////////////////////////////////////////////////
//
// Convert STR to WSTR
//
HRESULT SZtoWSZ(LPSTR szStr,LPWSTR *pwsz)
{
DWORD dwSize=0;
DWORD dwError=0;
*pwsz=NULL;
//return NULL
if(!szStr)
return S_OK;
dwSize=MultiByteToWideChar(0, 0,szStr, -1,NULL,0);
if(dwSize==0)
{
dwError=GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
//allocate memory
*pwsz=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
if(*pwsz==NULL)
return E_OUTOFMEMORY;
if(MultiByteToWideChar(0, 0,szStr, -1,
*pwsz,dwSize))
{
return S_OK;
}
else
{
free(*pwsz);
*pwsz=NULL;
dwError=GetLastError();
return HRESULT_FROM_WIN32(dwError);
}
}
//--------------------------------------------------------------------------
//
// Convert dwFormatType to dwStrType
//
//--------------------------------------------------------------------------
DWORD FormatToStr(DWORD dwFormatType)
{
DWORD dwStrType=0;
//we default to CERT_X500_NAME_STR
if(0==dwFormatType)
{
return CERT_X500_NAME_STR;
}
if(dwFormatType & CRYPT_FORMAT_SIMPLE)
dwStrType |= CERT_SIMPLE_NAME_STR;
if(dwFormatType & CRYPT_FORMAT_X509)
dwStrType |= CERT_X500_NAME_STR;
if(dwFormatType & CRYPT_FORMAT_OID)
dwStrType |= CERT_OID_NAME_STR;
if(dwFormatType & CRYPT_FORMAT_RDN_SEMICOLON)
dwStrType |= CERT_NAME_STR_SEMICOLON_FLAG;
if(dwFormatType & CRYPT_FORMAT_RDN_CRLF)
dwStrType |= CERT_NAME_STR_CRLF_FLAG;
if(dwFormatType & CRYPT_FORMAT_RDN_UNQUOTE)
dwStrType |= CERT_NAME_STR_NO_QUOTING_FLAG;
if(dwFormatType & CRYPT_FORMAT_RDN_REVERSE)
dwStrType |= CERT_NAME_STR_REVERSE_FLAG;
return dwStrType;
}
//+-----------------------------------------------------------------------------
// Post Win2k.
//------------------------------------------------------------------------------
//+-----------------------------------------------------------------------------
//
// FormatInteger X509_INTEGER
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatInteger (
DWORD dwCertEncodingType,
DWORD dwFormatStrType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat,
DWORD ids)
{
BOOL fResult;
DWORD cbNeeded;
int *pInfo = NULL;
LPWSTR pwszFormat = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) ||
(0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_INTEGER,
pbEncoded,
cbEncoded,
(void **)&pInfo))
{
goto DecodeGenericError;
}
//
// Some extension name=%1!d!%2!s!
//
if (!FormatMessageUnicode(&pwszFormat,
ids,
*pInfo,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
//
// Free resources.
//
if (pInfo)
{
free(pInfo);
}
if (pwszFormat)
{
LocalFree((HLOCAL) pwszFormat);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatCrlNumber szOID_CRL_NUMBER
// szOID_DELTA_CRL_INDICATOR
// szOID_CRL_VIRTUAL_BASE
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatCrlNumber (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
DWORD ids = 0;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decide between single line and mulitple line format.
//
if (bMultiLines)
{
ids = 0 == strcmp(lpszStructType, szOID_CRL_NUMBER) ? IDS_CRL_NUMBER :
0 == strcmp(lpszStructType, szOID_DELTA_CRL_INDICATOR) ? IDS_DELTA_CRL_INDICATOR : IDS_CRL_VIRTUAL_BASE;
}
else
{
ids = IDS_INTEGER;
}
//
// Decode extension to get length.
//
// %1!d!%2!s!
// CRL Number=%1!d!%2!s!
// Delta CRL Number=%1!d!%2!s!
// Virtual Base CRL Number=%1!d!%2!s!
//
if (!FormatInteger(dwCertEncodingType,
dwFormatStrType,
pbEncoded,
cbEncoded,
NULL,
&cbNeeded,
ids))
{
goto FormatIntegerError;
}
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Decode again to get data.
//
if (!FormatInteger(dwCertEncodingType,
dwFormatStrType,
pbEncoded,
cbEncoded,
pbFormat,
&cbNeeded,
ids))
{
goto FormatIntegerError;
}
//
// Copy size .
//
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(FormatIntegerError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatCrlNextPublish szOID_CRL_NEXT_PUBLISH
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatCrlNextPublish (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
FILETIME * pInfo = NULL;
LPWSTR pwszFileTime = NULL;
LPWSTR pwszFormat = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_CHOICE_OF_TIME,
pbEncoded,
cbEncoded,
(void **) &pInfo))
{
goto DecodeGenericError;
}
//
// Get formatted date/time.
//
if (!FormatFileTime(pInfo, &pwszFileTime))
{
goto FormatFileTimeError;
}
if (!FormatMessageUnicode(&pwszFormat,
IDS_STRING,
pwszFileTime,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pInfo)
{
free(pInfo);
}
if (pwszFileTime)
{
LocalFree((HLOCAL) pwszFileTime);
}
if (pwszFormat)
{
LocalFree((HLOCAL) pwszFormat);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
TRACE_ERROR(FormatFileTimeError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatIssuingDistPoint X509_ISSUING_DIST_POINT
// szOID_ISSUING_DIST_POINT
//
// typedef struct _CRL_ISSUING_DIST_POINT {
// CRL_DIST_POINT_NAME DistPointName; // OPTIONAL
// BOOL fOnlyContainsUserCerts;
// BOOL fOnlyContainsCACerts;
// CRYPT_BIT_BLOB OnlySomeReasonFlags; // OPTIONAL
// BOOL fIndirectCRL;
// } CRL_ISSUING_DIST_POINT, *PCRL_ISSUING_DIST_POINT;
//
// typedef struct _CRL_DIST_POINT_NAME {
// DWORD dwDistPointNameChoice;
// union {
// CERT_ALT_NAME_INFO FullName; // 1
// // Not implemented IssuerRDN; // 2
// };
// } CRL_DIST_POINT_NAME, *PCRL_DIST_POINT_NAME;
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatIssuingDistPoint (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
DWORD ids = 0;
WCHAR wszYes[YES_NO_SIZE];
WCHAR wszNo[YES_NO_SIZE];
LPWSTR pwszTemp = NULL;
LPWSTR pwszFormat = NULL;
LPWSTR pwszPointName = NULL;
LPWSTR pwszNameFormat = NULL;
LPWSTR pwszOnlyContainsUserCerts = NULL;
LPWSTR pwszOnlyContainsCACerts = NULL;
LPWSTR pwszIndirectCRL = NULL;
LPWSTR pwszCRLReason=NULL;
LPWSTR pwszReasonFormat=NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
PCRL_ISSUING_DIST_POINT pInfo = NULL;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
lpszStructType,
pbEncoded,
cbEncoded,
(void **)&pInfo))
{
goto DecodeGenericError;
}
//
// Allocate format buffer.
//
if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
{
goto MemoryError;
}
*pwszFormat = L'\0';
//
// Format distribution name, if exists.
//
if (CRL_DIST_POINT_NO_NAME != pInfo->DistPointName.dwDistPointNameChoice)
{
if (!FormatDistPointName(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
&(pInfo->DistPointName),
&pwszPointName))
{
goto FormatDistPointNameError;
}
//
// Decide between single line and mulitple line format.
//
ids = bMultiLines ? IDS_ONLY_SOME_CRL_DIST_NAME_MULTI: IDS_ONLY_SOME_CRL_DIST_NAME;
if (!FormatMessageUnicode(&pwszNameFormat, ids, pwszPointName))
{
goto FormatMessageError;
}
//
// Reallocate and concate to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszNameFormat) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszNameFormat);
LocalFree((HLOCAL) pwszPointName);
pwszPointName = NULL;
LocalFree((HLOCAL) pwszNameFormat);
pwszNameFormat = NULL;
}
//
// Format onlyContainsXXX fields.
//
if (!LoadStringU(hFrmtFuncInst,
IDS_YES,
wszYes,
sizeof(wszYes) / sizeof(wszYes[0])))
{
goto LoadStringError;
}
if (!LoadStringU(hFrmtFuncInst,
IDS_NO,
wszNo,
sizeof(wszNo) / sizeof(wszNo[0])))
{
goto LoadStringError;
}
//
// %1!s!Only Contains User Certs=%2!s!%3!s!
//
if (!FormatMessageUnicode(&pwszOnlyContainsUserCerts,
IDS_ONLY_CONTAINS_USER_CERTS,
bMultiLines ? wszEMPTY : wszCOMMA,
pInfo->fOnlyContainsUserCerts ? wszYes : wszNo,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// %1!s!Only Contains CA Certs=%2!s!%3!s!
//
if (!FormatMessageUnicode(&pwszOnlyContainsCACerts,
IDS_ONLY_CONTAINS_CA_CERTS,
bMultiLines ? wszEMPTY : wszCOMMA,
pInfo->fOnlyContainsCACerts ? wszYes : wszNo,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// %1!s!Indirect CRL=%2!s!%3!s!
//
if (!FormatMessageUnicode(&pwszIndirectCRL,
IDS_INDIRECT_CRL,
bMultiLines ? wszEMPTY : wszCOMMA,
pInfo->fIndirectCRL ? wszYes : wszNo,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Reallocate and concate to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) *
(wcslen(pwszFormat) + wcslen(pwszOnlyContainsUserCerts) +
wcslen(pwszOnlyContainsCACerts) + wcslen(pwszIndirectCRL) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszOnlyContainsUserCerts);
wcscat(pwszFormat, pwszOnlyContainsCACerts);
wcscat(pwszFormat, pwszIndirectCRL);
//
// Format the CRL reason.
//
if (0 != pInfo->OnlySomeReasonFlags.cbData)
{
if (!FormatCRLReason(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
lpszStructType,
&(pInfo->OnlySomeReasonFlags),
&pwszCRLReason))
{
goto FormatCRLReasonError;
}
//
// Format Decide between single line and mulitple line format.
//
if (!FormatMessageUnicode(&pwszReasonFormat,
bMultiLines ? IDS_CRL_DIST_REASON_MULTI : IDS_CRL_DIST_REASON,
pwszCRLReason))
{
goto FormatMessageError;
}
//
// Reallocate and concate to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszReasonFormat) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszReasonFormat);
LocalFree((HLOCAL) pwszCRLReason);
pwszCRLReason = NULL;
LocalFree((HLOCAL) pwszReasonFormat);
pwszReasonFormat = NULL;
}
//
// length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
//
// Free resources.
//
if (pwszCRLReason)
{
LocalFree((HLOCAL) pwszCRLReason);
}
if (pwszReasonFormat)
{
LocalFree((HLOCAL) pwszReasonFormat);
}
if(pwszIndirectCRL)
{
LocalFree((HLOCAL) pwszIndirectCRL);
}
if(pwszOnlyContainsCACerts)
{
LocalFree((HLOCAL) pwszOnlyContainsCACerts);
}
if(pwszOnlyContainsUserCerts)
{
LocalFree((HLOCAL) pwszOnlyContainsUserCerts);
}
if(pwszPointName)
{
LocalFree((HLOCAL) pwszPointName);
}
if (pwszNameFormat)
{
LocalFree((HLOCAL) pwszNameFormat);
}
if (pwszFormat)
{
free(pwszFormat);
}
if (pInfo)
{
free(pInfo);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MemoryError,E_OUTOFMEMORY);
TRACE_ERROR(FormatDistPointNameError);
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatCRLReasonError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatNameConstraintsSubtree.
//
// typedef struct _CERT_GENERAL_SUBTREE {
// CERT_ALT_NAME_ENTRY Base;
// DWORD dwMinimum;
// BOOL fMaximum;
// DWORD dwMaximum;
// } CERT_GENERAL_SUBTREE, *PCERT_GENERAL_SUBTREE;
//
//
// Note: Intended to be called only by FormatNameConstrants. So no validity
// checks are done on parameters.
//
//------------------------------------------------------------------------------
//static
BOOL
FormatNameConstraintsSubtree (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
void *pbFormat,
DWORD *pcbFormat,
DWORD idSubtree,
DWORD cSubtree,
PCERT_GENERAL_SUBTREE pSubtree)
{
BOOL fResult;
DWORD dwIndex;
DWORD cbNeeded;
WCHAR wszOneTab[PRE_FIX_SIZE] = wszEMPTY;
LPWSTR pwszType = NULL;
LPWSTR pwszSubtree = NULL;
LPWSTR pwszAltName = NULL;
LPWSTR pwszFormat = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Any subtree?
//
if (0 == cSubtree)
{
//
// Permitted=None%1!s!
// Excluded=None%1!s!
//
if (IDS_NAME_CONSTRAINTS_PERMITTED == idSubtree)
{
idSubtree = IDS_NAME_CONSTRAINTS_PERMITTED_NONE;
}
else // if (IDS_NAME_CONSTRAINTS_EXCLUDED == idSubtree)
{
idSubtree = IDS_NAME_CONSTRAINTS_EXCLUDED_NONE;
}
if (!FormatMessageUnicode(&pwszType,
idSubtree,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
}
else
{
//
// "Permitted%1!s!"
// "Excluded%1!s!"
//
if (!FormatMessageUnicode(&pwszType,
idSubtree,
bMultiLines ? wszCRLF : wszCOLON))
{
goto FormatMessageError;
}
//
// Load tab strings.
//
if (!LoadStringU(hFrmtFuncInst,
IDS_ONE_TAB,
wszOneTab,
sizeof(wszOneTab) / sizeof(wszOneTab[0])))
{
goto LoadStringError;
}
}
//
// Allocate format buffer.
//
if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR) * (wcslen(pwszType) + 1))))
{
goto MemoryError;
}
//
// Initialize formatted string.
//
wcscpy(pwszFormat, pwszType);
//
// Format each subtree parts.
//
for (dwIndex = 0; dwIndex < cSubtree; dwIndex++, pSubtree++)
{
LPWSTR pwszTemp;
//
// Maximum specified?
//
if (pSubtree->fMaximum)
{
//
// "%1!s![%2!d!]Subtrees (%3!d!..%4!d!):%5!s!"
//
if (!FormatMessageUnicode(&pwszSubtree,
IDS_NAME_CONSTRAINTS_SUBTREE,
bMultiLines ? wszOneTab : dwIndex ? wszCOMMA : wszEMPTY,
dwIndex + 1,
pSubtree->dwMinimum,
pSubtree->dwMaximum,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
}
else
{
//
// "%1!s![%2!d!]Subtrees (%3!d!...):%4!s"
//
if (!FormatMessageUnicode(&pwszSubtree,
IDS_NAME_CONSTRAINTS_SUBTREE_NO_MAX,
bMultiLines ? wszOneTab : dwIndex ? wszCOMMA : wszEMPTY,
dwIndex + 1,
pSubtree->dwMinimum,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
}
//
// Reallocate and concate to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + 1 + wcslen(pwszSubtree)));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszSubtree);
LocalFree((HLOCAL) pwszSubtree);
pwszSubtree = NULL;
//
// Format name.
//
CERT_ALT_NAME_INFO CertAltNameInfo;
memset(&CertAltNameInfo, 0, sizeof(CERT_ALT_NAME_INFO));
CertAltNameInfo.cAltEntry = 1;
CertAltNameInfo.rgAltEntry = &(pSubtree->Base);
// Need to tell if it is for multi line format. We need two \t\t
// in front of each alt name entry
DWORD ids = bMultiLines ? IDS_TWO_TABS : 0;
// Get the alternative name entry
cbNeeded = 0;
if (!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&CertAltNameInfo,
NULL,
&cbNeeded))
{
goto FormatAltNameError;
}
if (NULL == (pwszAltName = (LPWSTR) malloc(cbNeeded)))
{
goto MemoryError;
}
if (!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
ids,
FALSE,
&CertAltNameInfo,
pwszAltName,
&cbNeeded))
{
goto FormatAltNameError;
}
//
// Append "\r\n" if multi-line.
//
if (bMultiLines)
{
pwszTemp = (LPWSTR) realloc(pwszAltName, sizeof(WCHAR) * (wcslen(pwszAltName) + wcslen(wszCRLF) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszAltName = pwszTemp;
wcscat(pwszAltName, wszCRLF);
}
//
// Reallocate and concate to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + 1 + wcslen(pwszAltName)));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszAltName);
free(pwszAltName);
pwszAltName = NULL;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
//
// Free resources.
//
if (pwszType)
{
LocalFree((HLOCAL) pwszType);
}
if (pwszSubtree)
{
LocalFree((HLOCAL) pwszSubtree);
}
if (pwszAltName)
{
free((HLOCAL) pwszAltName);
}
if (pwszFormat)
{
free(pwszFormat);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
TRACE_ERROR(FormatMessageError);
TRACE_ERROR(LoadStringError);
SET_ERROR(MemoryError,E_OUTOFMEMORY);
TRACE_ERROR(FormatAltNameError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatNameConstrains: szOID_NAME_CONSTRAINTS
// X509_NAME_CONSTRAINTS
//
// typedef struct _CERT_NAME_CONSTRAINTS_INFO {
// DWORD cPermittedSubtree;
// PCERT_GENERAL_SUBTREE rgPermittedSubtree;
// DWORD cExcludedSubtree;
// PCERT_GENERAL_SUBTREE rgExcludedSubtree;
// } CERT_NAME_CONSTRAINTS_INFO, *PCERT_NAME_CONSTRAINTS_INFO;
//
//------------------------------------------------------------------------------
//static
BOOL
WINAPI
FormatNameConstraints (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult = FALSE;
DWORD cbPermitNeeded = 0;
DWORD cbExcludeNeeded = 0;
DWORD cbTotalNeeded = 0;
PCERT_NAME_CONSTRAINTS_INFO pInfo = NULL;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
lpszStructType,
pbEncoded,
cbEncoded,
(void **)&pInfo))
{
goto DecodeGenericError;
}
//
// Find out memory size needed.
//
if ((!FormatNameConstraintsSubtree(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
&cbPermitNeeded,
IDS_NAME_CONSTRAINTS_PERMITTED,
pInfo->cPermittedSubtree,
pInfo->rgPermittedSubtree)) ||
(!FormatNameConstraintsSubtree(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
&cbExcludeNeeded,
IDS_NAME_CONSTRAINTS_EXCLUDED,
pInfo->cExcludedSubtree,
pInfo->rgExcludedSubtree)))
{
goto ErrorReturn;
}
//
// Total length needed.
//
cbTotalNeeded = cbPermitNeeded + cbExcludeNeeded;
if (0 == cbTotalNeeded)
{
*pcbFormat = cbTotalNeeded;
goto SuccessReturn;
}
//
// One char less after we concate both strings.
//
if (cbPermitNeeded > 0 && cbExcludeNeeded > 0)
{
cbTotalNeeded -= sizeof(WCHAR);
//
// If not multi-lines and both strings are present, allow 2 more
// chars for ", " to separate the strings.
//
if (!(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE))
{
cbTotalNeeded += sizeof(WCHAR) * wcslen(wszCOMMA);
}
}
//
// length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbTotalNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbTotalNeeded)
{
*pcbFormat = cbTotalNeeded;
goto MoreDataError;
}
//
// Now format both subtrees.
//
if (!FormatNameConstraintsSubtree(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
pbFormat,
&cbPermitNeeded,
IDS_NAME_CONSTRAINTS_PERMITTED,
pInfo->cPermittedSubtree,
pInfo->rgPermittedSubtree))
{
goto ErrorReturn;
}
//
// If not multi-lines and both strings are present, then add ", "
// to separate them.
//
if (!(dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE) &&
(cbPermitNeeded > 0) && (cbExcludeNeeded > 0))
{
wcscat((LPWSTR) pbFormat, wszCOMMA);
}
pbFormat = (void *) ((BYTE *) pbFormat + wcslen((LPWSTR) pbFormat) * sizeof(WCHAR));
if (!FormatNameConstraintsSubtree(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
pbFormat,
&cbExcludeNeeded,
IDS_NAME_CONSTRAINTS_EXCLUDED,
pInfo->cExcludedSubtree,
pInfo->rgExcludedSubtree))
{
goto ErrorReturn;
}
//
// Copy the size needed.
//
*pcbFormat = cbTotalNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
//
// Free resources.
//
if (pInfo)
{
free(pInfo);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatCertSrvPreviousCertHash szOID_CERTSRV_PREVIOUS_CERT_HASH
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatCertSrvPreviousCertHash (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
CRYPT_DATA_BLOB * pInfo = NULL;
WCHAR * pwszHex = NULL;
WCHAR * pwszFormat = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_OCTET_STRING,
pbEncoded,
cbEncoded,
(void **) &pInfo))
{
goto DecodeGenericError;
}
//
// Get formatted hex string.
//
if(!FormatBytesToHex(0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->pbData,
pInfo->cbData,
NULL,
&cbNeeded))
{
goto FormatBytesToHexError;
}
if (!(pwszHex = (LPWSTR) malloc(cbNeeded)))
{
goto MemoryError;
}
if(!FormatBytesToHex(0,
dwFormatType,
dwFormatStrType,
pFormatStruct,
NULL,
pInfo->pbData,
pInfo->cbData,
pwszHex,
&cbNeeded))
{
goto FormatBytesToHexError;
}
if (!FormatMessageUnicode(&pwszFormat,
IDS_STRING,
pwszHex,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// Length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pInfo)
{
free(pInfo);
}
if (pwszHex)
{
free(pwszHex);
}
if (pwszFormat)
{
LocalFree((HLOCAL) pwszFormat);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatBytesToHexError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatPolicyMappings X509_POLICY_MAPPINGS
// szOID_POLICY_MAPPINGS
// szOID_APPLICATION_POLICY_MAPPINGS
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatPolicyMappings (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD dwIndex = 0;
DWORD cbNeeded = 0;
char szEmpty[1] = {'\0'};
LPSTR pszObjectId = NULL;
LPWSTR pwszFormat = NULL;
LPWSTR pwszTemp = NULL;
LPWSTR pwszLine = NULL;
LPWSTR pwszPolicy = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
CERT_POLICY_MAPPINGS_INFO * pInfo = NULL;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_POLICY_MAPPINGS,
pbEncoded,
cbEncoded,
(void **) &pInfo))
{
goto DecodeGenericError;
}
//
// Make sure data is valid.
//
if (pInfo->cPolicyMapping && !pInfo->rgPolicyMapping)
{
goto BadDataError;
}
//
// Initialize formatted string.
//
if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
{
goto MemoryError;
}
*pwszFormat = NULL;
//
// Loop thru each mapping.
//
for (dwIndex = 0; dwIndex < pInfo->cPolicyMapping; dwIndex++)
{
//
// Format Issuer Domain Policy, if available.
//
if (pInfo->rgPolicyMapping[dwIndex].pszIssuerDomainPolicy)
{
pszObjectId = pInfo->rgPolicyMapping[dwIndex].pszIssuerDomainPolicy;
}
else
{
pszObjectId = szEmpty;
}
if (!FormatObjectId(pszObjectId,
CRYPT_POLICY_OID_GROUP_ID,
FALSE,
&pwszPolicy))
{
goto FormatObjectIdError;
}
//
// "[%1!d!]Issuer Domain=%2!s!%3!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_ISSUER_DOMAIN_POLICY,
dwIndex + 1,
pwszPolicy,
bMultiLines ? wszCRLF : wszCOMMA))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszPolicy);
pwszPolicy = NULL;
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
//
// Format Subject Domain Policy, if available.
//
if (pInfo->rgPolicyMapping[dwIndex].pszSubjectDomainPolicy)
{
pszObjectId = pInfo->rgPolicyMapping[dwIndex].pszSubjectDomainPolicy;
}
else
{
pszObjectId = szEmpty;
}
if (!FormatObjectId(pszObjectId,
CRYPT_POLICY_OID_GROUP_ID,
FALSE,
&pwszPolicy))
{
goto FormatObjectIdError;
}
//
// "%1!s!Subject Domain=%2!s!%3!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_SUBJECT_DOMAIN_POLICY,
bMultiLines ? wszTAB : wszEMPTY,
pwszPolicy,
bMultiLines ? wszCRLF : (dwIndex + 1) < pInfo->cPolicyMapping ? wszCOMMA : wszEMPTY))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszPolicy);
pwszPolicy = NULL;
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// Length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pwszLine)
{
LocalFree((HLOCAL) pwszLine);
}
if (pwszPolicy)
{
LocalFree((HLOCAL) pwszPolicy);
}
if (pwszFormat)
{
free(pwszFormat);
}
if (pInfo)
{
free(pInfo);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(BadDataError, E_POINTER);
TRACE_ERROR(FormatObjectIdError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatPolicyConstraints X509_POLICY_CONSTRAINTS
// szOID_POLICY_CONSTRAINTS
// szOID_APPLICATION_POLICY_CONSTRAINTS
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatPolicyConstraints (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
LPWSTR pwszFormat = NULL;
LPWSTR pwszTemp = NULL;
LPWSTR pwszLine = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
CERT_POLICY_CONSTRAINTS_INFO * pInfo = NULL;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_POLICY_CONSTRAINTS,
pbEncoded,
cbEncoded,
(void **) &pInfo))
{
goto DecodeGenericError;
}
//
// Initialize formatted string.
//
if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
{
goto MemoryError;
}
*pwszFormat = NULL;
//
// Format Required Explicit Policy Skip Certs, if available.
//
if (pInfo->fRequireExplicitPolicy)
{
//
// "Required Explicit Policy Skip Certs=%1!d!%2!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_REQUIRED_EXPLICIT_POLICY_SKIP_CERTS,
pInfo->dwRequireExplicitPolicySkipCerts,
bMultiLines ? wszCRLF : wszCOMMA))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
}
//
// Format Inhibit Policy Mapping Skip Certs, if available.
//
if (pInfo->fInhibitPolicyMapping)
{
//
// "Inhibit Policy Mapping Skip Certs=%1!d!%2!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_INHIBIT_POLICY_MAPPING_SKIP_CERTS,
pInfo->dwInhibitPolicyMappingSkipCerts,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// Length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pwszLine)
{
LocalFree((HLOCAL) pwszLine);
}
if (pwszFormat)
{
free(pwszFormat);
}
if (pInfo)
{
free(pInfo);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//+-----------------------------------------------------------------------------
//
// FormatCertificateTemplate X509_CERTIFICATE_TEMPLATE
// szOID_CERTIFICATE_TEMPLATE
//
//------------------------------------------------------------------------------
static BOOL
WINAPI
FormatCertificateTemplate (
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
BOOL fResult;
DWORD cbNeeded = 0;
LPWSTR pwszFormat = NULL;
LPWSTR pwszObjId = NULL;
LPWSTR pwszTemp = NULL;
LPWSTR pwszLine = NULL;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
CERT_TEMPLATE_EXT * pInfo = NULL;
//
// Check input parameters.
//
if ((NULL == pbEncoded && 0 != cbEncoded) ||
(NULL == pcbFormat) || (0 == cbEncoded))
{
goto InvalidArg;
}
//
// Decode extension.
//
if (!DecodeGenericBLOB(dwCertEncodingType,
X509_CERTIFICATE_TEMPLATE,
pbEncoded,
cbEncoded,
(void **) &pInfo))
{
goto DecodeGenericError;
}
//
// Initialize formatted string.
//
if (!(pwszFormat = (LPWSTR) malloc(sizeof(WCHAR))))
{
goto MemoryError;
}
*pwszFormat = NULL;
#if (0) //DSIE: Bug 157853
//
// Convert OID to Unicode.
//
if (!AllocateAnsiToUnicode(pInfo->pszObjId, &pwszObjId))
{
goto AnsiToUnicodeError;
}
#else
if (!FormatObjectId(pInfo->pszObjId,
CRYPT_TEMPLATE_OID_GROUP_ID,
FALSE,
&pwszObjId))
{
goto FormatObjectIdError;
}
#endif
//
// "Template=%1!s!%2!s!Major Version Number=%3!d!%4!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_CERTIFICATE_TEMPLATE_MAJOR_VERSION,
pwszObjId,
bMultiLines ? wszCRLF : wszCOMMA,
pInfo->dwMajorVersion,
bMultiLines ? wszCRLF : wszCOMMA))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
//
// Format Minor Version, if available.
//
if (pInfo->fMinorVersion)
{
//
// "Minor Version Number=%1!d!%2!s!"
//
if (!FormatMessageUnicode(&pwszLine,
IDS_CERTIFICATE_TEMPLATE_MINOR_VERSION,
pInfo->dwMinorVersion,
bMultiLines ? wszCRLF : wszEMPTY))
{
goto FormatMessageError;
}
//
// Reallocate and concate line to format buffer.
//
pwszTemp = (LPWSTR) realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat) + wcslen(pwszLine) + 1));
if (NULL == pwszTemp)
{
goto MemoryError;
}
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszLine);
LocalFree((HLOCAL) pwszLine);
pwszLine = NULL;
}
//
// Total length needed.
//
cbNeeded = sizeof(WCHAR) * (wcslen(pwszFormat) + 1);
//
// Length only calculation?
//
if (NULL == pbFormat)
{
*pcbFormat = cbNeeded;
goto SuccessReturn;
}
//
// Caller provided us with enough memory?
//
if (*pcbFormat < cbNeeded)
{
*pcbFormat = cbNeeded;
goto MoreDataError;
}
//
// Copy size and data.
//
memcpy(pbFormat, pwszFormat, cbNeeded);
*pcbFormat = cbNeeded;
SuccessReturn:
fResult = TRUE;
CommonReturn:
if (pwszObjId)
{
#if (0) //DSIE: Bug 157853
free(pwszObjId);
#else
LocalFree((HLOCAL) pwszObjId);
#endif
}
if (pwszLine)
{
LocalFree((HLOCAL) pwszLine);
}
if (pwszFormat)
{
free(pwszFormat);
}
if (pInfo)
{
free(pInfo);
}
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg,E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
#if (0) //DSIE: Bug 157853
TRACE_ERROR(AnsiToUnicodeError);
#else
TRACE_ERROR(FormatObjectIdError);
#endif
TRACE_ERROR(FormatMessageError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
}
//--------------------------------------------------------------------------
//
// FormatXCertDistPoints: X509_CROSS_CERT_DIST_POINTS
// szOID_CROSS_CERT_DIST_POINTS
//--------------------------------------------------------------------------
static BOOL
WINAPI
FormatXCertDistPoints(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
LPWSTR pwszFormat=NULL;
LPWSTR pwszDeltaTime=NULL;
LPWSTR pwszEntryLine=NULL;
LPWSTR pwszDistPoint=NULL;
PCROSS_CERT_DIST_POINTS_INFO pInfo=NULL;
DWORD cbNeeded=0;
DWORD dwIndex=0;
BOOL fResult=FALSE;
BOOL bMultiLines = dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE;
LPWSTR pwszTemp;
//check for input parameters
if ((NULL==pbEncoded && cbEncoded!=0) || (NULL==pcbFormat))
goto InvalidArg;
if (cbEncoded==0)
{
*pcbFormat=0;
goto InvalidArg;
}
if (!DecodeGenericBLOB(dwCertEncodingType, lpszStructType,
pbEncoded, cbEncoded, (void **)&pInfo))
goto DecodeGenericError;
//
// "Delta Sync Time=%1!d! seconds%2!s!"
//
if (!FormatMessageUnicode(&pwszDeltaTime,
IDS_XCERT_DELTA_SYNC_TIME,
pInfo->dwSyncDeltaTime,
bMultiLines ? wszCRLF : wszCOMMA))
{
goto FormatMessageError;
}
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR) * (wcslen(pwszDeltaTime)+1));
if(NULL==pwszFormat)
goto MemoryError;
wcscpy(pwszFormat, pwszDeltaTime);
//format the xcert dist point entries.
for (dwIndex=0; dwIndex<pInfo->cDistPoint; dwIndex++)
{
cbNeeded=0;
if (!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
bMultiLines ? IDS_ONE_TAB : 0,
FALSE,
&pInfo->rgDistPoint[dwIndex],
NULL,
&cbNeeded))
goto FormatAltNameError;
pwszEntryLine=(LPWSTR)malloc(cbNeeded);
if (NULL==pwszEntryLine)
goto MemoryError;
if (!FormatAltNameInfo(dwCertEncodingType,
dwFormatType,
dwFormatStrType,
pFormatStruct,
bMultiLines ? IDS_ONE_TAB : 0,
FALSE,
&pInfo->rgDistPoint[dwIndex],
pwszEntryLine,
&cbNeeded))
goto FormatAltNameError;
//"[%1!d!]Cross-Certificate Distribution Point: %2!s!%3!s!%4!s!"
if(!FormatMessageUnicode(&pwszDistPoint,
IDS_XCERT_DIST_POINT,
dwIndex + 1,
bMultiLines ? wszCRLF : wszEMPTY,
pwszEntryLine,
bMultiLines || (dwIndex == pInfo->cDistPoint - 1) ? wszCRLF : wszCOMMA))
goto FormatMessageError;
pwszTemp=(LPWSTR)realloc(pwszFormat, sizeof(WCHAR) * (wcslen(pwszFormat)+wcslen(pwszDistPoint)+1));
if(NULL==pwszTemp)
goto MemoryError;
pwszFormat = pwszTemp;
wcscat(pwszFormat, pwszDistPoint);
//free memory
free(pwszEntryLine);
pwszEntryLine=NULL;
LocalFree((HLOCAL) pwszDistPoint);
pwszDistPoint=NULL;
}
if(0==wcslen(pwszFormat))
{
//no data
pwszFormat=(LPWSTR)malloc(sizeof(WCHAR)*(NO_INFO_SIZE+1));
if(NULL==pwszFormat)
goto MemoryError;
if(!LoadStringU(hFrmtFuncInst,IDS_NO_INFO, pwszFormat, NO_INFO_SIZE))
goto LoadStringError;
}
cbNeeded=sizeof(WCHAR)*(wcslen(pwszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
fResult=TRUE;
goto CommonReturn;
}
if((*pcbFormat)<cbNeeded)
{
*pcbFormat=cbNeeded;
goto MoreDataError;
}
//copy the data
memcpy(pbFormat, pwszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
fResult=TRUE;
CommonReturn:
if(pwszDeltaTime)
LocalFree((HLOCAL) pwszDeltaTime);
if(pwszDistPoint)
LocalFree((HLOCAL) pwszDistPoint);
if(pwszEntryLine)
free(pwszEntryLine);
if (pwszFormat)
free(pwszFormat);
if(pInfo)
free(pInfo);
return fResult;
ErrorReturn:
fResult=FALSE;
goto CommonReturn;
SET_ERROR(InvalidArg, E_INVALIDARG);
TRACE_ERROR(DecodeGenericError);
SET_ERROR(MoreDataError,ERROR_MORE_DATA);
TRACE_ERROR(LoadStringError);
TRACE_ERROR(FormatMessageError);
SET_ERROR(MemoryError, E_OUTOFMEMORY);
TRACE_ERROR(FormatAltNameError);
}