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