|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: tstore2.cpp
//
// Contents: Cert Store API Tests: Create and Add a chain of certificates
// and CRLs to the store.
//
// See Usage() for a list of test options.
//
//
// Functions: main
//
// History: 07-Mar-96 philh created
// 31-May-96 helles Removed check for a particular error code,
// NTE_PROV_TYPE_NOT_DEF, since this can get
// overwritten due to known problem with
// the msvcr40d.dll on Win95.
// 07-Jun-96 HelleS Added printing the command line
// 20-Aug-96 jeffspel name changes
//
//--------------------------------------------------------------------------
#define CMS_PKCS7 1
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "setcert.h"
#include "signcde.h"
#include "softpub.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
#include <stddef.h>
//#define TEST_PROV_DSS PROV_DSS
#define TEST_PROV_DSS PROV_DSS_DH
// # of bytes for a hash. Such as, SHA1 (20) or MD5 (16)
#define MAX_HASH_LEN 20
#if 1
// client authentication doesn't know about sha1
#define SIGNATURE_ALG_OBJID szOID_RSA_MD5RSA
#else
#define SIGNATURE_ALG_OBJID szOID_OIWSEC_sha1RSASign
#endif
#define DSS_SIGNATURE_ALG_OBJID szOID_X957_SHA1DSA
#define ENH_1024_CONTAINER_NAME_A "Regression 1024"
#define ENH_1024_CONTAINER_NAME_W L"Regression 1024"
#define ENH_2048_CONTAINER_NAME_A "Regression 2048"
#define ENH_2048_CONTAINER_NAME_W L"Regression 2048"
#define DSS_512_CONTAINER_NAME_A "Regression 512"
#define DSS_512_CONTAINER_NAME_W L"Regression 512"
//+-------------------------------------------------------------------------
// Parameters, data used to encode the messages.
//--------------------------------------------------------------------------
static DWORD dwCertEncodingType = X509_ASN_ENCODING; static DWORD dwMsgEncodingType = PKCS_7_ASN_ENCODING; static DWORD dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING; static SYSTEMTIME TestTime; static LPSTR pszContainer = NULL; static LPWSTR pwszContainer = NULL; static HCRYPTPROV hRSACryptProv = 0; static HCRYPTPROV hEnh1024CryptProv = 0; static HCRYPTPROV hEnh2048CryptProv = 0; static HCRYPTPROV hDSSCryptProv = 0; static HCRYPTPROV hDSS512CryptProv = 0; static BOOL fGenerate = FALSE; static BOOL fExportable = FALSE; static BOOL fUserProtected = FALSE; static BOOL fProviders = FALSE; static BOOL fMachine = FALSE; static BOOL fInheritParameters = FALSE;
#define TIME_INVALID_PARA_FLAG 0x00000001
#define REVOKED_PARA_FLAG 0x00000002
#define PROV_PARA_FLAG 0x00000004
#define XCHG_PARA_FLAG 0x00000008
#define CA_PARA_FLAG 0x00000010
#define NO_NAME_PARA_FLAG 0x00000020
#define ALT_DIR_NAME_PARA_FLAG 0x00000040
#define SET_PARA_FLAG 0x00000080
#define ALL_EXT_PARA_FLAG 0x00000100
#define SPC_EXT_PARA_FLAG 0x00000200
#define SPC_COM_PARA_FLAG 0x00000400
#define SPC_AGENCY_PARA_FLAG 0x00000800
#define SPC_AGENCY_INFO_PARA_FLAG 0x00001000
// "Valid" certs to give to other companies to test interoperability
#define VALID_PARA_FLAG 0x00002000
#define DELTA_CRL_PARA_FLAG 0x00004000
#define AUX1_PARA_FLAG 0x00010000
#define AUX2_PARA_FLAG 0x00020000
// For duplicate, use previous cert's serial number
#define DUPLICATE_PARA_FLAG 0x00040000
#define NO_EXT_PARA_FLAG 0x00080000
#define DUPLICATE_CRL_PARA_FLAG 0x00100000
#define NO_CRL_EXT_PARA_FLAG 0x00200000
#define GENERALIZED_TIME_PARA_FLAG 0x00400000
#define NETSCAPE_PARA_FLAG 0x00800000
#define CTL1_PARA_FLAG 0x01000000
#define CTL2_PARA_FLAG 0x02000000
#define USE1_PARA_FLAG 0x04000000
#define USE2_PARA_FLAG 0x08000000
#define HTTP_PARA_FLAG 0x10000000
#define DSS_PARA_FLAG 0x80000000
#define DSS_512_PARA_FLAG 0x40000000
#define ENH_1024_PARA_FLAG 0x40000000
#define ENH_2048_PARA_FLAG 0x20000000
#define szSignManifold "Signer Manifold"
#define szXchgManifold "Recipient Manifold"
typedef struct _CERT_PARA { LPSTR pszName; DWORD dwIssuer; DWORD dwFlags; LPSTR pszManifold; } CERT_PARA;
#define BASE_OR_DELTA_CA_ISSUER 1
#define UPDATE_CTL_SIGNER 1
#define POLICY_ROOT 0
#define POLICY_CA 1
#define CERT_CNT 76
static CERT_PARA CertPara[CERT_CNT] = { "root", 0, CA_PARA_FLAG, // 0
NULL, "CA", 0, CA_PARA_FLAG | DUPLICATE_CRL_PARA_FLAG, // 1
NULL, "TestRoot", 2, CA_PARA_FLAG | ENH_2048_PARA_FLAG | VALID_PARA_FLAG, // 2
NULL, "TestSigner", 2, PROV_PARA_FLAG | VALID_PARA_FLAG | USE1_PARA_FLAG, // 3
szSignManifold, "TestRecipient",2, PROV_PARA_FLAG | XCHG_PARA_FLAG | VALID_PARA_FLAG | USE1_PARA_FLAG, // 4
szXchgManifold, "me", 1, PROV_PARA_FLAG | ENH_1024_PARA_FLAG | USE2_PARA_FLAG, // 5
NULL, "me", 1, PROV_PARA_FLAG | ENH_1024_PARA_FLAG | XCHG_PARA_FLAG, // 6
NULL, "setrevoked", 1, REVOKED_PARA_FLAG | PROV_PARA_FLAG | SET_PARA_FLAG | ENH_2048_PARA_FLAG, // 7
NULL, "setrevoked", 1, REVOKED_PARA_FLAG | XCHG_PARA_FLAG | SET_PARA_FLAG | PROV_PARA_FLAG | ENH_2048_PARA_FLAG,// 8
NULL, "time invalid", 1, TIME_INVALID_PARA_FLAG, // 9
NULL, "setkeith", 1, SET_PARA_FLAG, // 10
NULL, "setkeith", 1, XCHG_PARA_FLAG | USE2_PARA_FLAG | // 11
SET_PARA_FLAG, NULL, "kevin", 1, 0, // 12
NULL, "kevin", 1, XCHG_PARA_FLAG | USE2_PARA_FLAG, // 13
NULL, "all ext", 1, ALL_EXT_PARA_FLAG | AUX1_PARA_FLAG | SET_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG | AUX2_PARA_FLAG | USE1_PARA_FLAG | USE2_PARA_FLAG, // 14
NULL, "MSPub", 17, SPC_EXT_PARA_FLAG | SPC_COM_PARA_FLAG | PROV_PARA_FLAG | USE1_PARA_FLAG, // 15
NULL, "PhilPub", 17, SPC_EXT_PARA_FLAG | PROV_PARA_FLAG | USE2_PARA_FLAG, // 16
NULL, "MSAgency", 1, SPC_EXT_PARA_FLAG | SPC_AGENCY_PARA_FLAG | PROV_PARA_FLAG | CA_PARA_FLAG, // 17
NULL, "AgencyInfo", 1, SPC_AGENCY_INFO_PARA_FLAG, // 18
NULL, "duplicate1", 1, AUX1_PARA_FLAG | NO_EXT_PARA_FLAG | USE1_PARA_FLAG, // 19
NULL, "duplicate2", 1, AUX2_PARA_FLAG | NO_EXT_PARA_FLAG | DUPLICATE_PARA_FLAG | USE2_PARA_FLAG, // 20
NULL, "GeneralRoot", 21, CA_PARA_FLAG | GENERALIZED_TIME_PARA_FLAG | PROV_PARA_FLAG | DSS_PARA_FLAG, // 21
NULL, "GeneralTime", 21, GENERALIZED_TIME_PARA_FLAG | PROV_PARA_FLAG | DSS_512_PARA_FLAG | DSS_PARA_FLAG, // 22
NULL, "Generalrevoked", 21, REVOKED_PARA_FLAG | DSS_PARA_FLAG, // 23
NULL, "NoCRLExtCA", 0, CA_PARA_FLAG | NO_CRL_EXT_PARA_FLAG, // 24
NULL, "NoCRLExtrevoked", 24, REVOKED_PARA_FLAG, // 25
NULL, "NetscapeCA", 0, NETSCAPE_PARA_FLAG | CA_PARA_FLAG | DSS_PARA_FLAG | REVOKED_PARA_FLAG, // 26
NULL, "Netscape", 26, NETSCAPE_PARA_FLAG | REVOKED_PARA_FLAG, // 27
NULL, "Ctl0", 1, CTL1_PARA_FLAG | NO_EXT_PARA_FLAG, // 28
NULL, "Ctl1", 2, CTL1_PARA_FLAG, // 29
NULL, "Ctl1Invalid", 2, CTL1_PARA_FLAG | TIME_INVALID_PARA_FLAG | DUPLICATE_PARA_FLAG, // 30
NULL, "Ctl2", 1, CTL2_PARA_FLAG, // 31
NULL, "Ctl2Invalid", 1, CTL2_PARA_FLAG | TIME_INVALID_PARA_FLAG | DUPLICATE_PARA_FLAG, // 32
NULL, "Http2", 1, CTL2_PARA_FLAG | HTTP_PARA_FLAG | NO_EXT_PARA_FLAG, // 33
NULL, "Http2Invalid", 1, CTL2_PARA_FLAG | TIME_INVALID_PARA_FLAG | DUPLICATE_PARA_FLAG | HTTP_PARA_FLAG | NO_EXT_PARA_FLAG, // 34
NULL, "NoNameIssuer1", 0, CA_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG, // 35
NULL, "NoNameSubject1", 35, NO_NAME_PARA_FLAG, // 36
NULL, "NoNameIssuer2", 0, CA_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG, // 37
NULL, "NoNameSubject2", 37, NO_NAME_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG, // 38
NULL, "Hellman", 21, XCHG_PARA_FLAG | NO_EXT_PARA_FLAG | PROV_PARA_FLAG | DSS_PARA_FLAG, // 39
NULL, "TestSigner2", 2, PROV_PARA_FLAG | VALID_PARA_FLAG | USE1_PARA_FLAG, // 40
szSignManifold, "TestRecipient2", 2, PROV_PARA_FLAG | XCHG_PARA_FLAG | VALID_PARA_FLAG | USE1_PARA_FLAG, // 41
szXchgManifold, "TestSigner3", 2, PROV_PARA_FLAG | VALID_PARA_FLAG | USE1_PARA_FLAG, // 42
szSignManifold, "UTF8", 2, VALID_PARA_FLAG | NO_EXT_PARA_FLAG, // 43
NULL, "DssRoot", 44, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | DSS_PARA_FLAG, // 44
NULL, "DssCA", 44, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | DSS_PARA_FLAG, // 45
NULL, "DssEnd", 45, VALID_PARA_FLAG | NO_EXT_PARA_FLAG | PROV_PARA_FLAG | DSS_PARA_FLAG, // 46
NULL, "ZeroNotAfter", 2, VALID_PARA_FLAG | PROV_PARA_FLAG, // 47
NULL, "V1", 48, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | NO_CRL_EXT_PARA_FLAG, // 48
NULL, "V2", 48, VALID_PARA_FLAG | NO_EXT_PARA_FLAG, // 49
NULL, "DeltaEndValid", 1, DELTA_CRL_PARA_FLAG, // 50
NULL, "DeltaNoValid", 1, DELTA_CRL_PARA_FLAG | NO_EXT_PARA_FLAG, // 51
NULL, "DeltaEndRevoked", 1, DELTA_CRL_PARA_FLAG | // 52
REVOKED_PARA_FLAG, NULL, "DeltaCAValid", 1, DELTA_CRL_PARA_FLAG | // 53
CA_PARA_FLAG, NULL, "DeltaCARevoked", 1, DELTA_CRL_PARA_FLAG | // 54
CA_PARA_FLAG | REVOKED_PARA_FLAG, NULL, "NoCDPValid", 1, DELTA_CRL_PARA_FLAG, // 55
NULL, "NoCDPRevoked", 1, DELTA_CRL_PARA_FLAG | // 56
REVOKED_PARA_FLAG, NULL, "UnsupportedCDP", 1, DELTA_CRL_PARA_FLAG | // 57
REVOKED_PARA_FLAG, NULL, "NotPermitted", 1, ALT_DIR_NAME_PARA_FLAG, // 58
NULL, "Excluded", 1, ALT_DIR_NAME_PARA_FLAG, // 59
NULL,
"TestAIARoot", 60, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 60
NO_CRL_EXT_PARA_FLAG, NULL, "TestAIARevokeRoot", 61, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 61
NO_CRL_EXT_PARA_FLAG, NULL, "TestAIACA", 60, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 62
NO_CRL_EXT_PARA_FLAG, NULL, "TestAIACA", 61, CA_PARA_FLAG | NO_EXT_PARA_FLAG | NO_CRL_EXT_PARA_FLAG | REVOKED_PARA_FLAG, // 63
NULL, "TestAIAEnd", 63, NO_EXT_PARA_FLAG, // 64
NULL, "MissingNCCA", 0, CA_PARA_FLAG, // 65
NULL, "MissingNCEnd", 65, 0, // 66
NULL, "TestAIAExpireRoot", 67, CA_PARA_FLAG | NO_EXT_PARA_FLAG | // 67
NO_CRL_EXT_PARA_FLAG, NULL, "TestAIACA", 67, CA_PARA_FLAG | NO_EXT_PARA_FLAG | NO_CRL_EXT_PARA_FLAG | TIME_INVALID_PARA_FLAG, // 68
NULL,
"InvalidKeyUsageCA", 2, CA_PARA_FLAG | VALID_PARA_FLAG, // 69
NULL, "InvalidKeyUsageEnd", 69, NO_EXT_PARA_FLAG, // 70
NULL,
"RolloverRoot", 71, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | DSS_PARA_FLAG, // 71
NULL, "RolloverCA", 71, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | DSS_PARA_FLAG, // 72
NULL, "RolloverEnd", 72, VALID_PARA_FLAG | DSS_PARA_FLAG, // 73
NULL,
"RolloverRoot", 2, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG| ENH_1024_PARA_FLAG, NULL, // 74
"RolloverRoot", 74, CA_PARA_FLAG | VALID_PARA_FLAG | NO_EXT_PARA_FLAG | DSS_PARA_FLAG, // 75
NULL, };
#define ROLLOVER_CROSS_CERT 74
#define EXPIRED_CRL_FLAG 0x00000001
#define REMOVE_FROM_CRL_FLAG 0x00000002
#define HOLD_CRL_FLAG 0x00000004
#define FRESHEST_CRL_FLAG 0x00000010
#define NO_FRESHEST_CDP_CRL_FLAG 0x00000020
#define NO_IDP_CRL_FLAG 0x00000100
#define ONLY_USERS_CRL_FLAG 0x00000200
#define ONLY_CAS_CRL_FLAG 0x00000400
#define UNSUPPORTED_IDP_OPTIONS_CRL_FLAG 0x00000800
#define UNSUPPORTED_CRITICAL_EXT_CRL_FLAG 0x00001000
#define NO_ENTRIES_CRL_FLAG 0x00002000
typedef struct _BASE_DELTA_CRL_PARA { int iBase; DWORD dwFlags; } BASE_DELTA_CRL_PARA;
static BASE_DELTA_CRL_PARA BaseDeltaCrlPara[] = { // Users Only: Base and Delta
1, ONLY_USERS_CRL_FLAG, 1, ONLY_USERS_CRL_FLAG | FRESHEST_CRL_FLAG,
// CAs Only: Base and Delta
2, ONLY_CAS_CRL_FLAG, 2, ONLY_CAS_CRL_FLAG | FRESHEST_CRL_FLAG,
// Base has entries, Delta has no entries
3, HOLD_CRL_FLAG, 3, NO_ENTRIES_CRL_FLAG | FRESHEST_CRL_FLAG,
// Base has no entries, Delta has entries
4, NO_ENTRIES_CRL_FLAG, 4, FRESHEST_CRL_FLAG,
// Base has entries, Delta has remove entries
5, HOLD_CRL_FLAG, 5, REMOVE_FROM_CRL_FLAG | FRESHEST_CRL_FLAG,
// Valid base, delta has unsupported IDP options
6, HOLD_CRL_FLAG, 6, FRESHEST_CRL_FLAG | UNSUPPORTED_IDP_OPTIONS_CRL_FLAG,
// Expired base, valid delta
7, EXPIRED_CRL_FLAG, 7, FRESHEST_CRL_FLAG,
// Valid base, expired delta
8, 0, 8, EXPIRED_CRL_FLAG | FRESHEST_CRL_FLAG,
// Expired base, without a freshest CDP extension
9, EXPIRED_CRL_FLAG | NO_FRESHEST_CDP_CRL_FLAG, 9, FRESHEST_CRL_FLAG,
// Base without IDP and no freshest, delta CRL
10, NO_IDP_CRL_FLAG | NO_FRESHEST_CDP_CRL_FLAG,
// Base and Delta CRL with unsupported critical ext
11, UNSUPPORTED_CRITICAL_EXT_CRL_FLAG, 11, UNSUPPORTED_CRITICAL_EXT_CRL_FLAG | FRESHEST_CRL_FLAG,
// Valid base with number > above delta indicator
100, 0, }; #define BASE_DELTA_CRL_CNT \
(sizeof(BaseDeltaCrlPara)/sizeof(BaseDeltaCrlPara[0]))
typedef struct _UPDATE_CTL_PARA { BOOL fTimeInvalid; LPSTR pszUsageObjId; LPSTR pszListIdentifier; LPWSTR pwszUrl; } UPDATE_CTL_PARA;
static UPDATE_CTL_PARA UpdateCtlPara[] = { FALSE, "1.3.2000.1", "UpdateCtl1", L"file://testupdate1.ctl", TRUE, "1.3.2000.1", "UpdateCtl1", L"file://testupdate1.ctl", FALSE, "1.3.2000.2", "UpdateCtl2", L"file://testupdate2.ctl", TRUE, "1.3.2000.2", "UpdateCtl2", L"file://testupdate2.ctl", }; #define UPDATE_CTL_CNT (sizeof(UpdateCtlPara)/sizeof(UpdateCtlPara[0]))
#define STRING_OTHER_NAME_OID "1.2.3.4.2600.1"
#define OCTET_OTHER_NAME_OID "1.2.3.4.2600.2"
#define RDN_CNT 4
#define ATTR_CNT 4
#define ATTR_0_OBJID szOID_COMMON_NAME
#define ATTR_1_OBJID "1.2.1"
#define ATTR_2_OBJID "1.2.2"
#define UTF8_NAME L"*** UTF8 ***"
// Attr[0] - CertPara[].pszName
// Attr[1] - "xchg" | "sign"
// Attr[2] - "default" | pszContainer
static LPSTR rgpszUsageIdentifier[] = { "1.2.3.0", // 0
"1.2.3.1", // 1
"1.2.3.2", // 2
"1.2.3.2.1" // 3
};
static CTL_USAGE rgCtlUsage[] = { 1, &rgpszUsageIdentifier[0], // 0
1, &rgpszUsageIdentifier[1], // 1
2, &rgpszUsageIdentifier[2], // 2
3, &rgpszUsageIdentifier[1] // 3
};
static PCCERT_CONTEXT rgpCertContext[CERT_CNT];
void MySystemTimeToFileTime( SYSTEMTIME *pSystemTime, FILETIME *pFileTime ) { SYSTEMTIME TmpTime;
if (!SystemTimeToFileTime(pSystemTime, pFileTime)) { TmpTime = *pSystemTime;
// Following is a fix for Feb 29, 2000 when advancing the year forward or backward.
TmpTime.wDay = 1; SystemTimeToFileTime(&TmpTime, pFileTime); } }
//+-------------------------------------------------------------------------
// Error output routines
//--------------------------------------------------------------------------
static void PrintError(LPCSTR pszMsg) { printf("%s\n", pszMsg); } static void PrintLastError(LPCSTR pszMsg) { DWORD dwErr = GetLastError(); printf("%s failed => 0x%x (%d) \n", pszMsg, dwErr, dwErr); }
//+-------------------------------------------------------------------------
// Test allocation and free routines
//--------------------------------------------------------------------------
static LPVOID WINAPI TestAlloc( IN size_t cbBytes ) { LPVOID pv; pv = malloc(cbBytes); if (pv == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); PrintLastError("TestAlloc"); } return pv; }
static VOID WINAPI TestFree( IN LPVOID pv ) { if (pv) free(pv); }
//+-------------------------------------------------------------------------
// Allocate and convert a multi-byte string to a wide string
//--------------------------------------------------------------------------
static LPWSTR AllocAndSzToWsz(LPCSTR psz) { size_t cb; LPWSTR pwsz = NULL;
if (-1 == (cb = mbstowcs( NULL, psz, strlen(psz)))) goto bad_param; cb += 1; // terminating NULL
if (NULL == (pwsz = (LPWSTR)TestAlloc( cb * sizeof(WCHAR)))) { PrintLastError("AllocAndSzToWsz"); goto failed; } if (-1 == mbstowcs( pwsz, psz, cb)) goto bad_param; goto common_return;
bad_param: PrintError("Bad AllocAndSzToWsz"); failed: if (pwsz) { TestFree(pwsz); pwsz = NULL; } common_return: return pwsz; }
static HCRYPTPROV GetCryptProv( DWORD dwProvType, LPCSTR pszProvider = NULL, LPCSTR pszInContainer = pszContainer, DWORD dwBitLen = 0 ) { HCRYPTPROV hProv = 0; BOOL fResult; DWORD dwFlags;
if (fMachine) dwFlags = CRYPT_MACHINE_KEYSET; else dwFlags = 0;
fResult = CryptAcquireContext( &hProv, pszInContainer, pszProvider, dwProvType, dwFlags );
if (fResult) { if (fGenerate) { // Delete the existing keys
CryptReleaseContext(hProv, 0); printf("Deleting existing private keys\n"); // Note: for CRYPT_DELETEKEYSET, the returned hProv is undefined
// and must not be released.
fResult = CryptAcquireContext( &hProv, pszInContainer, pszProvider, dwProvType, dwFlags | CRYPT_DELETEKEYSET ); if (!fResult) { PrintLastError("CryptAcquireContext(CRYPT_DELETEKEYSET)"); return 0; } hProv = 0; } }
if (0 == hProv) { printf("Creating new private keys\n"); fResult = CryptAcquireContext( &hProv, pszInContainer, pszProvider, dwProvType, dwFlags | CRYPT_NEWKEYSET ); if (!fResult || hProv == 0) { PrintLastError("CryptAcquireContext(CRYPT_NEWKEYSET)"); return 0; } }
HCRYPTKEY hKey = 0; dwFlags = dwBitLen << 16; if (fExportable) dwFlags |= CRYPT_EXPORTABLE; if (fUserProtected) dwFlags |= CRYPT_USER_PROTECTED;
if (CryptGetUserKey( hProv, AT_SIGNATURE, &hKey )) { printf("Using existing SIGNATURE private key\n"); CryptDestroyKey(hKey); hKey = 0; } else { printf("Generating SIGNATURE private key\n"); fResult = CryptGenKey( hProv, AT_SIGNATURE, dwFlags, &hKey ); if (!fResult || hKey == 0) PrintLastError("CryptGenKey(AT_SIGNATURE)"); else CryptDestroyKey(hKey); }
if (PROV_DSS == dwProvType) return hProv;
if (CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hKey )) { printf("Using existing EXCHANGE private key\n"); CryptDestroyKey(hKey); hKey = 0; } else { printf("Generating EXCHANGE private key\n"); hKey = 0; fResult = CryptGenKey( hProv, AT_KEYEXCHANGE, dwFlags, &hKey ); if (!fResult || hKey == 0) PrintLastError("CryptGenKey(AT_KEYEXCHANGE)"); else CryptDestroyKey(hKey); }
return hProv; }
static HCERTSTORE OpenStore(LPCSTR pszStoreFilename) { HCERTSTORE hStore; HANDLE hFile = 0;
if( INVALID_HANDLE_VALUE == (hFile = CreateFile(pszStoreFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL))) { hStore = CertOpenStore( CERT_STORE_PROV_MEMORY, dwCertEncodingType, 0, // hCryptProv
0, // dwFlags
NULL // pvPara
); } else { hStore = CertOpenStore( CERT_STORE_PROV_FILE, dwCertEncodingType, 0, // hCryptProv
0, // dwFlags
hFile ); CloseHandle(hFile); }
if (hStore == NULL) PrintLastError("CertOpenStore");
return hStore; }
static void SaveStore(HCERTSTORE hStore, LPCSTR pszSaveFilename) { HANDLE hFile; hFile = CreateFile(pszSaveFilename, GENERIC_WRITE, 0, // fdwShareMode
NULL, // lpsa
CREATE_ALWAYS, 0, // fdwAttrsAndFlags
0); // TemplateFile
if (INVALID_HANDLE_VALUE == hFile) { printf( "can't open %s\n", pszSaveFilename); PrintLastError("CloseStore::CreateFile"); } else { if (!CertSaveStore( hStore, 0, // dwEncodingType,
CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_FILE, (void *) hFile, 0 // dwFlags
)) PrintLastError("CertSaveStore"); CloseHandle(hFile); } }
static CRYPT_ENCODE_PARA TestEncodePara = { offsetof(CRYPT_ENCODE_PARA, pfnFree) + sizeof(TestEncodePara.pfnFree), TestAlloc, TestFree };
static BOOL AllocAndEncodeObject( IN LPCSTR lpszStructType, IN const void *pvStructInfo, OUT BYTE **ppbEncoded, OUT DWORD *pcbEncoded ) { BOOL fResult;
fResult = CryptEncodeObjectEx( dwCertEncodingType, lpszStructType, pvStructInfo, CRYPT_ENCODE_ALLOC_FLAG, &TestEncodePara, (void *) ppbEncoded, pcbEncoded );
if (!fResult) { if ((DWORD_PTR) lpszStructType <= 0xFFFF) printf("CryptEncodeObject(StructType: %d)", (DWORD)(DWORD_PTR) lpszStructType); else printf("CryptEncodeObject(StructType: %s)", lpszStructType); PrintLastError(""); }
return fResult; }
static BOOL CreateEnhancedKeyUsage( IN DWORD dwFlags, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { PCTL_USAGE pCtlUsage;
dwFlags &= USE1_PARA_FLAG | USE2_PARA_FLAG;
switch (dwFlags) { case 0: pCtlUsage = &rgCtlUsage[0]; break; case USE1_PARA_FLAG: pCtlUsage = &rgCtlUsage[1]; break; case USE2_PARA_FLAG: pCtlUsage = &rgCtlUsage[2]; break; case USE1_PARA_FLAG | USE2_PARA_FLAG: default: pCtlUsage = &rgCtlUsage[3]; break; }
return AllocAndEncodeObject( X509_ENHANCED_KEY_USAGE, (const void *) pCtlUsage, ppbEncoded, pcbEncoded ); }
static BOOL CreateNextUpdateLocation( DWORD dwCert, BOOL fProp, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded, IN OPTIONAL LPWSTR pwszUrl = NULL ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CERT_ALT_NAME_INFO AltNameInfo; CERT_ALT_NAME_ENTRY rgAltNameEntry[5];
rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgAltNameEntry[0].pwszRfc822Name = L"RFC822"; rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[1].pwszURL = L"file://file1.ctl"; rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[2].pwszURL = L"http://timestamp/ctltest/http1.ctl";
rgAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[3].pwszURL = L"file://file2.ctl"; rgAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[4].pwszURL = L"http://timestamp/ctltest/http2.ctl";
if (dwCert == UPDATE_CTL_SIGNER) { rgAltNameEntry[1].pwszURL = L"file://nonexistant1.ctl"; rgAltNameEntry[2].pwszURL = L"file://nonexistant2.ctl"; if (pwszUrl) rgAltNameEntry[3].pwszURL = pwszUrl; else rgAltNameEntry[3].pwszURL = L"file://testupdate1.ctl"; rgAltNameEntry[4].pwszURL = L"file://nonexistant3.ctl"; AltNameInfo.cAltEntry = 5; AltNameInfo.rgAltEntry = &rgAltNameEntry[0]; } else if (fProp) { if (CertPara[dwCert].dwFlags & HTTP_PARA_FLAG) AltNameInfo.cAltEntry = 2; else AltNameInfo.cAltEntry = 1; AltNameInfo.rgAltEntry = &rgAltNameEntry[3]; } else { if (CertPara[dwCert].dwFlags & HTTP_PARA_FLAG) AltNameInfo.cAltEntry = 5; else AltNameInfo.cAltEntry = 2; AltNameInfo.rgAltEntry = &rgAltNameEntry[0]; }
if (!AllocAndEncodeObject( X509_ALTERNATE_NAME, &AltNameInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL AddCert( HCERTSTORE hStore, DWORD dwCert, BYTE *pbEncoded, DWORD cbEncoded) { BOOL fResult; PCCERT_CONTEXT pCert = NULL;
fResult = CertAddEncodedCertificateToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL); if (!fResult) { if (GetLastError() == CRYPT_E_EXISTS) { printf("Cert already exists in store. Adding duplicate\n"); fResult = CertAddEncodedCertificateToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_ALWAYS, &pCert); } if (!fResult) PrintLastError("CertAddEncodedCertificateToStore"); } else { fResult = CertAddEncodedCertificateToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_USE_EXISTING, &pCert); if (!fResult) PrintLastError("CertAddEncodedCertificateToStore"); } if (pCert) { if (CertPara[dwCert].dwFlags & PROV_PARA_FLAG) { CRYPT_KEY_PROV_INFO KeyProvInfo; memset(&KeyProvInfo, 0, sizeof(KeyProvInfo)); if ((CertPara[dwCert].dwFlags & DSS_PARA_FLAG) && (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG)) KeyProvInfo.pwszContainerName = DSS_512_CONTAINER_NAME_W; else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG) KeyProvInfo.pwszContainerName = ENH_1024_CONTAINER_NAME_W; else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG) KeyProvInfo.pwszContainerName = ENH_2048_CONTAINER_NAME_W; else if (pwszContainer) KeyProvInfo.pwszContainerName = pwszContainer; if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) KeyProvInfo.dwProvType = TEST_PROV_DSS; else KeyProvInfo.dwProvType = PROV_RSA_FULL; if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) { KeyProvInfo.dwFlags = CERT_SET_KEY_PROV_HANDLE_PROP_ID; KeyProvInfo.dwKeySpec = AT_KEYEXCHANGE; } else KeyProvInfo.dwKeySpec = AT_SIGNATURE; if (fMachine) KeyProvInfo.dwFlags |= CRYPT_MACHINE_KEYSET;
fResult = CertSetCertificateContextProperty( pCert, CERT_KEY_PROV_INFO_PROP_ID, 0, // dwFlags
&KeyProvInfo ); if (!fResult) PrintLastError("CertSetCertificateContextProperty"); }
if (((CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) && (CertPara[dwCert].dwFlags & (NO_EXT_PARA_FLAG | VALID_PARA_FLAG))) || (CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) == (USE1_PARA_FLAG | USE2_PARA_FLAG)) {
CRYPT_DATA_BLOB Data; DWORD dwFlags = CertPara[dwCert].dwFlags; if (0 == (CertPara[dwCert].dwFlags & (NO_EXT_PARA_FLAG | VALID_PARA_FLAG))) dwFlags = 0; if (CreateEnhancedKeyUsage( dwFlags, &Data.pbData, &Data.cbData)) { if (!CertSetCertificateContextProperty( pCert, CERT_CTL_USAGE_PROP_ID, 0, // dwFlags
&Data )) PrintLastError( "CertSetCertificateContextProperty(CTL_USAGE)"); TestFree(Data.pbData); } }
if (CertPara[dwCert].dwFlags & AUX1_PARA_FLAG) { DWORD i; CRYPT_DATA_BLOB Data[4]; BYTE rgbAux0[] = {0x11, 0x0}; BYTE rgbAux1[] = {0x11, 0x1}; BYTE rgbAux2[] = {0x11, 0x2, 0x2}; BYTE rgbAux3[] = {0x11, 0x3, 0x3, 0x3};
Data[0].pbData = NULL; Data[0].cbData = 0; Data[1].pbData = rgbAux1; Data[1].cbData = sizeof(rgbAux1); Data[2].pbData = rgbAux2; Data[2].cbData = sizeof(rgbAux2); Data[3].pbData = rgbAux3; Data[3].cbData = sizeof(rgbAux3);
for (i = 0; i < 4; i++) { if (!CertSetCertificateContextProperty( pCert, CERT_FIRST_USER_PROP_ID + i, 0, // dwFlags
&Data[i] )) { fResult = FALSE; PrintLastError("CertSetCertificateContextProperty"); break; } } }
if (CertPara[dwCert].dwFlags & AUX2_PARA_FLAG) { DWORD i; CRYPT_DATA_BLOB Data[3]; BYTE rgbAux0[] = {0x22, 0x2, 0x2}; BYTE rgbAux1[] = {0x22, 0x3, 0x3, 0x3}; BYTE rgbAux2[] = {0x22, 0x4, 0x4, 0x4, 0x4, 0x12, 0x34};
Data[0].pbData = rgbAux0; Data[0].cbData = sizeof(rgbAux0); Data[1].pbData = rgbAux1; Data[1].cbData = sizeof(rgbAux1); Data[2].pbData = rgbAux2; Data[2].cbData = sizeof(rgbAux2);
for (i = 0; i < 3; i++) { if (!CertSetCertificateContextProperty( pCert, CERT_FIRST_USER_PROP_ID + 2 + i, 0, // dwFlags
&Data[i] )) { fResult = FALSE; PrintLastError("CertSetCertificateContextProperty"); break; } }
if (CertPara[dwCert].dwFlags & AUX1_PARA_FLAG) { // Delete CERT_FIRST_USER_PROP_ID + 1
if (!CertSetCertificateContextProperty( pCert, CERT_FIRST_USER_PROP_ID + 1, 0, // dwFlags
NULL )) { fResult = FALSE; PrintLastError("CertSetCertificateContextProperty"); } } } CertFreeCertificateContext(pCert); } return fResult; }
static BOOL AddCrl( HCERTSTORE hStore, DWORD dwCert, DWORD dwAuxFlags, BYTE *pbEncoded, DWORD cbEncoded, BOOL fDuplicate = FALSE ) { BOOL fResult; PCCRL_CONTEXT pCrl = NULL;
fResult = CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL); if (!fResult) { if (GetLastError() == CRYPT_E_EXISTS) { if (fDuplicate || 0 == strcmp("TestAIACA", CertPara[dwCert].pszName)) { printf("CRL already exists in store. Adding duplicate\n"); fResult = CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_ALWAYS, &pCrl); } } if (!fResult) PrintLastError("CertAddEncodedCRLToStore"); } else { if (fDuplicate) printf("AddCrl failed => ADD_NEW duplicate succeeded\n");
fResult = CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_USE_EXISTING, &pCrl); if (!fResult) PrintLastError("CertAddEncodedCRLToStore"); } if (pCrl) { if (dwAuxFlags & AUX1_PARA_FLAG) { DWORD i; CRYPT_DATA_BLOB Data[4]; BYTE rgbAux0[] = {0x11, 0x0}; BYTE rgbAux1[] = {0x11, 0x1}; BYTE rgbAux2[] = {0x11, 0x2, 0x2}; BYTE rgbAux3[] = {0x11, 0x3, 0x3, 0x3};
Data[0].pbData = NULL; Data[0].cbData = 0; Data[1].pbData = rgbAux1; Data[1].cbData = sizeof(rgbAux1); Data[2].pbData = rgbAux2; Data[2].cbData = sizeof(rgbAux2); Data[3].pbData = rgbAux3; Data[3].cbData = sizeof(rgbAux3);
for (i = 0; i < 4; i++) { if (!CertSetCRLContextProperty( pCrl, CERT_FIRST_USER_PROP_ID + i, 0, // dwFlags
&Data[i] )) { fResult = FALSE; PrintLastError("CertSetCRLContextProperty"); break; } } }
if (dwAuxFlags & AUX2_PARA_FLAG) { DWORD i; CRYPT_DATA_BLOB Data[3]; BYTE rgbAux0[] = {0x22, 0x2, 0x2}; BYTE rgbAux1[] = {0x22, 0x3, 0x3, 0x3}; BYTE rgbAux2[] = {0x22, 0x4, 0x4, 0x4, 0x4, 0x12, 0x34};
Data[0].pbData = rgbAux0; Data[0].cbData = sizeof(rgbAux0); Data[1].pbData = rgbAux1; Data[1].cbData = sizeof(rgbAux1); Data[2].pbData = rgbAux2; Data[2].cbData = sizeof(rgbAux2);
for (i = 0; i < 3; i++) { if (!CertSetCRLContextProperty( pCrl, CERT_FIRST_USER_PROP_ID + 2 + i, 0, // dwFlags
&Data[i] )) { fResult = FALSE; PrintLastError("CertSetCRLContextProperty"); break; } } } CertFreeCRLContext(pCrl); } return fResult; }
static BOOL AddCtl( HCERTSTORE hStore, DWORD dwCert, BYTE *pbEncoded, DWORD cbEncoded) { BOOL fResult; PCCTL_CONTEXT pCtl = NULL;
fResult = CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_NEW, NULL); if (!fResult) { if (GetLastError() == CRYPT_E_EXISTS) { printf("CTL already exists in store. Adding duplicate\n"); fResult = CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_ALWAYS, &pCtl); } if (!fResult) PrintLastError("CertAddEncodedCTLToStore"); } else { fResult = CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_USE_EXISTING, &pCtl); if (!fResult) PrintLastError("CertAddEncodedCTLToStore"); } if (pCtl) { if (0 == (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG)) { CRYPT_DATA_BLOB Data;
if (CreateNextUpdateLocation( dwCert, TRUE, // fProp
&Data.pbData, &Data.cbData)) { if (!CertSetCTLContextProperty( pCtl, CERT_NEXT_UPDATE_LOCATION_PROP_ID, 0, // dwFlags
&Data )) PrintLastError( "CertSetCertificateContextProperty(NEXT_UPDATE)"); TestFree(Data.pbData); } } CertFreeCTLContext(pCtl); } return fResult; }
#define AKI2_KEYID 0
#define AKI2_NONE 1
#define AKI2_FULL 2
#define AKI2_BAD_KEYID 3
#define AKI2_BAD_ISSUER 4
#define AKI2_BAD_SERIAL_NUMBER 5
#define AKI2_CNT 6
// On 02-May-01 updated to not look at the IssuerAndSerialNumber in the CRL's
// AKI
#define AKI2_BAD_CNT 1
static BOOL EncodeCert(DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded); static BOOL EncodeCrl( DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded, DWORD dwAki = AKI2_KEYID ); static BOOL EncodeBaseOrDeltaCrl( DWORD dwIssuer, int iBase, DWORD dwFlags, BYTE **ppbEncoded, DWORD *pcbEncoded ); static BOOL EncodeCtl(DWORD dwCert, DWORD dwEncodeFlags, BYTE **ppbEncoded, DWORD *pcbEncoded);
static BOOL EncodeUpdateCtl( BOOL fTimeInvalid, LPSTR pszUsageObjId, LPSTR pszListIdentifier, LPWSTR pwszUrl, BYTE **ppbEncoded, DWORD *pcbEncoded );
static void Usage(void) { printf("Usage: tstore2 [options] <StoreFilename>\n"); printf("Options are:\n"); printf(" -h - This message\n"); printf(" -c<name> - Crypto key container name\n"); printf(" -g - Generate new keys\n"); printf(" -E - Exportable private keys\n"); printf(" -U - User protected private keys\n"); printf(" -M - Store in local Machine, not current User\n"); printf(" -P - Use enhanced and DSS providers\n"); printf(" -I - Inherit DSS public key parameters\n"); printf(" -K - Keep extra Crls\n"); printf("\n"); }
int _cdecl main(int argc, char * argv[]) { LPSTR pszStoreFilename = NULL; HANDLE hStore = 0; BYTE *pbEncoded = NULL; DWORD cbEncoded; DWORD i; BOOL fKeepCrls = FALSE;
while (--argc>0) { if (**++argv == '-') { switch(argv[0][1]) { case 'c': pszContainer = argv[0]+2; pwszContainer = AllocAndSzToWsz(pszContainer); if (*pszContainer == '\0') { printf("Need to specify crypto key container name\n"); Usage(); return -1; } break; case 'g': fGenerate = TRUE; break; case 'E': fExportable = TRUE; break; case 'U': fUserProtected = TRUE; break; case 'M': fMachine = TRUE; break; case 'P': fProviders = TRUE; break; case 'I': fInheritParameters = TRUE; break; case 'K': fKeepCrls = TRUE; break; case 'h': default: Usage(); return -1; } } else pszStoreFilename = argv[0]; }
if (pszStoreFilename == NULL) { printf("missing store filename\n"); Usage(); return -1; }
printf("command line: %s\n", GetCommandLine());
// Get time used time stamping and serial numbers
GetSystemTime(&TestTime); TestTime.wMilliseconds = 0;
printf("Getting RSA provider\n"); hRSACryptProv = GetCryptProv(PROV_RSA_FULL, MS_DEF_PROV_A); if (hRSACryptProv == 0) return -1;
printf("Getting DSS provider\n"); hDSSCryptProv = GetCryptProv(TEST_PROV_DSS);
if (fProviders) { printf("Getting Enhanced RSA provider (1024 bit)\n"); hEnh1024CryptProv = GetCryptProv(PROV_RSA_FULL, MS_ENHANCED_PROV_A, ENH_1024_CONTAINER_NAME_A, 1024); if (hEnh1024CryptProv == 0) return -1;
printf("Getting Enhanced RSA provider (2048 bit)\n"); hEnh2048CryptProv = GetCryptProv(PROV_RSA_FULL, MS_ENHANCED_PROV_A, ENH_2048_CONTAINER_NAME_A, 2048); if (hEnh2048CryptProv == 0) return -1;
printf("Getting DSS provider (512 bit)\n"); hDSS512CryptProv = GetCryptProv(TEST_PROV_DSS, NULL, DSS_512_CONTAINER_NAME_A, 512); } else { // Disable all enhanced provider flags
for (i = 0; i < CERT_CNT; i++) CertPara[i].dwFlags &= ~(DSS_512_PARA_FLAG | ENH_1024_PARA_FLAG | ENH_2048_PARA_FLAG); }
// Attempt to open the store
hStore = OpenStore(pszStoreFilename); if (hStore == NULL) goto ErrorReturn;
// Encode certs and CRLs and add to the store.
for (i = 0; i < CERT_CNT; i++) { if (EncodeCert(i, &pbEncoded, &cbEncoded)) { rgpCertContext[i] = CertCreateCertificateContext( dwCertEncodingType, pbEncoded, cbEncoded); AddCert(hStore, i, pbEncoded, cbEncoded); TestFree(pbEncoded); pbEncoded = NULL; }
if (CertPara[i].dwFlags & CA_PARA_FLAG) { if (0 == strncmp(CertPara[i].pszName, "Rollover", 8)) { // No CRL for rollover certs
; } else if (CertPara[i].dwFlags & DUPLICATE_CRL_PARA_FLAG) { DWORD dwAki; for (dwAki = 0; dwAki < AKI2_CNT; dwAki++) { if (EncodeCrl(i, &pbEncoded, &cbEncoded, dwAki)) { if (AKI2_BAD_SERIAL_NUMBER == dwAki) // Modify the signature
pbEncoded[cbEncoded -1] ^= 0xFF;
AddCrl(hStore, i, AUX1_PARA_FLAG, pbEncoded, cbEncoded); AddCrl(hStore, i, AUX2_PARA_FLAG, pbEncoded, cbEncoded, TRUE); TestFree(pbEncoded); pbEncoded = NULL; } } } else { if (EncodeCrl(i, &pbEncoded, &cbEncoded)) { AddCrl(hStore, i, 0, pbEncoded, cbEncoded); TestFree(pbEncoded); pbEncoded = NULL; } } } }
// Test CertFindCRLInStore(CRL_FIND_ISSUED_BY)
for (i = 0; i < CERT_CNT; i++) { if ((CA_PARA_FLAG | DUPLICATE_CRL_PARA_FLAG) == ((CA_PARA_FLAG | DUPLICATE_CRL_PARA_FLAG) & CertPara[i].dwFlags)) { PCCERT_CONTEXT pIssuer = rgpCertContext[i]; DWORD dwCnt; PCCRL_CONTEXT pCrl;
printf("CertFindCRLInStore(CRL_FIND_ISSUED_BY) [%d]\n", i);
dwCnt = 0; pCrl = NULL; while (pCrl = CertFindCRLInStore( hStore, dwCertEncodingType, 0, // dwFindFlags
CRL_FIND_ISSUED_BY, (const void *) pIssuer, pCrl )) dwCnt++; if ((AKI2_CNT * 2) != dwCnt) printf("CRL_FIND_ISSUED_BY failed count => expected: %d actual: %d\n", AKI2_CNT * 2, dwCnt);
dwCnt = 0; pCrl = NULL; while (pCrl = CertFindCRLInStore( hStore, dwCertEncodingType, CRL_FIND_ISSUED_BY_AKI_FLAG, CRL_FIND_ISSUED_BY, (const void *) pIssuer, pCrl )) dwCnt++; if (((AKI2_CNT - AKI2_BAD_CNT) * 2) != dwCnt) printf("CRL_FIND_ISSUED_BY(AKI_FLAG) failed count => expected: %d actual: %d\n", (AKI2_CNT - AKI2_BAD_CNT) * 2, dwCnt);
dwCnt = 0; pCrl = NULL; while (pCrl = CertFindCRLInStore( hStore, dwCertEncodingType, CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, (const void *) pIssuer, pCrl )) dwCnt++; if (((AKI2_CNT - 1) * 2) != dwCnt) printf("CRL_FIND_ISSUED_BY(SIGNATURE_FLAG) failed count => expected: %d actual: %d\n", (AKI2_CNT - 1) * 2, dwCnt);
if (!fKeepCrls) { // Delete all but the last pair of duplicates
dwCnt = 0; pCrl = NULL; while (pCrl = CertFindCRLInStore( hStore, dwCertEncodingType, 0, // dwFindFlags
CRL_FIND_ISSUED_BY, (const void *) pIssuer, pCrl )) { PCCRL_CONTEXT pDeleteCrl = CertDuplicateCRLContext(pCrl); CertDeleteCRLFromStore(pDeleteCrl); if (((AKI2_CNT - 1) * 2) == ++dwCnt) { CertFreeCRLContext(pCrl); break; } }
dwCnt = 0; pCrl = NULL; while (pCrl = CertFindCRLInStore( hStore, dwCertEncodingType, CRL_FIND_ISSUED_BY_AKI_FLAG | CRL_FIND_ISSUED_BY_SIGNATURE_FLAG, CRL_FIND_ISSUED_BY, (const void *) pIssuer, pCrl )) dwCnt++; if (2 != dwCnt) printf("CRL_FIND_ISSUED_BY(After delete) failed count => expected: %d actual: %d\n", 2, dwCnt); } } }
// Encode CTLs and add to the store.
for (i = 0; i < CERT_CNT; i++) { if (CertPara[i].dwFlags & (CTL1_PARA_FLAG | CTL2_PARA_FLAG)) { if (EncodeCtl(i, 0, &pbEncoded, &cbEncoded)) { AddCtl(hStore, i, pbEncoded, cbEncoded); TestFree(pbEncoded); pbEncoded = NULL; } if (EncodeCtl( i, #ifdef CMS_PKCS7
CMSG_CMS_ENCAPSULATED_CTL_FLAG | #endif // CMS_PKCS7
CMSG_ENCODE_SORTED_CTL_FLAG | ((CertPara[i].dwFlags & CTL1_PARA_FLAG) ? 0 : CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG), &pbEncoded, &cbEncoded)) { AddCtl(hStore, i, pbEncoded, cbEncoded); TestFree(pbEncoded); pbEncoded = NULL; } } }
for (i = 0; i < BASE_DELTA_CRL_CNT; i++) { if (EncodeBaseOrDeltaCrl( BASE_OR_DELTA_CA_ISSUER, BaseDeltaCrlPara[i].iBase, BaseDeltaCrlPara[i].dwFlags, &pbEncoded, &cbEncoded)) { BOOL fResult;
fResult = CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_ALWAYS, NULL); if (!fResult) PrintLastError("CertAddEncodedCRLToStore"); TestFree(pbEncoded); pbEncoded = NULL; } }
for (i = 0; i < UPDATE_CTL_CNT; i++) { if (EncodeUpdateCtl( UpdateCtlPara[i].fTimeInvalid, UpdateCtlPara[i].pszUsageObjId, UpdateCtlPara[i].pszListIdentifier, UpdateCtlPara[i].pwszUrl, &pbEncoded, &cbEncoded)) { BOOL fResult;
fResult = CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded, cbEncoded, CERT_STORE_ADD_ALWAYS, NULL); if (!fResult) PrintLastError("CertAddEncodedCTLToStore"); TestFree(pbEncoded); pbEncoded = NULL; } }
for (i = 0; i < CERT_CNT; i++) CertFreeCertificateContext(rgpCertContext[i]);
SaveStore(hStore, pszStoreFilename);
ErrorReturn: if (pbEncoded) TestFree(pbEncoded);
if (hStore) { if (!CertCloseStore(hStore, 0)) PrintLastError("CertCloseStore"); }
if (hRSACryptProv) CryptReleaseContext(hRSACryptProv, 0); if (hEnh1024CryptProv) CryptReleaseContext(hEnh1024CryptProv, 0); if (hEnh2048CryptProv) CryptReleaseContext(hEnh2048CryptProv, 0); if (hDSSCryptProv) CryptReleaseContext(hDSSCryptProv, 0); if (hDSS512CryptProv) CryptReleaseContext(hDSS512CryptProv, 0);
if (pwszContainer) TestFree(pwszContainer);
printf("Done.\n");
return 0; }
static BOOL AllocAndSignToBeSigned( DWORD dwIssuer, BYTE *pbToBeSigned, DWORD cbToBeSigned, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, BYTE **ppbSignature, DWORD *pcbSignature) { BOOL fResult; BYTE *pbSignature = NULL; DWORD cbSignature; HCRYPTPROV hProv;
if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG) { if (CertPara[dwIssuer].dwFlags & DSS_512_PARA_FLAG) hProv = hDSS512CryptProv; else hProv = hDSSCryptProv; } else if (CertPara[dwIssuer].dwFlags & ENH_1024_PARA_FLAG) hProv = hEnh1024CryptProv; else if (CertPara[dwIssuer].dwFlags & ENH_2048_PARA_FLAG) hProv = hEnh2048CryptProv; else hProv = hRSACryptProv;
cbSignature = 0; CryptSignCertificate( hProv, AT_SIGNATURE, dwCertEncodingType, pbToBeSigned, cbToBeSigned, pSignatureAlgorithm, NULL, // pvHashAuxInfo
NULL, // pbSignature
&cbSignature ); if (cbSignature == 0) { PrintLastError("AllocAndSignToBeSigned::CryptSignCertificate(cb == 0)"); goto ErrorReturn; } pbSignature = (BYTE *) TestAlloc(cbSignature); if (pbSignature == NULL) goto ErrorReturn; if (!CryptSignCertificate( hProv, AT_SIGNATURE, dwCertEncodingType, pbToBeSigned, cbToBeSigned, pSignatureAlgorithm, NULL, // pvHashAuxInfo
pbSignature, &cbSignature )) { PrintLastError("AllocAndSignToBeSigned::CryptSignCertificate"); goto ErrorReturn; }
fResult = TRUE; goto CommonReturn;
ErrorReturn: fResult = FALSE; if (pbSignature) { TestFree(pbSignature); pbSignature = NULL; } cbSignature = 0; CommonReturn: *ppbSignature = pbSignature; *pcbSignature = cbSignature; return fResult; }
static BOOL EncodeSignedContent( DWORD dwIssuer, BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE **ppbEncoded, DWORD *pcbEncoded) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; BYTE *pbSignature = NULL; DWORD cbSignature; CERT_SIGNED_CONTENT_INFO CertEncoding;
CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm = { SIGNATURE_ALG_OBJID, 0, 0 };
if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG) SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID;
if (!AllocAndSignToBeSigned(dwIssuer, pbToBeSigned, cbToBeSigned, &SignatureAlgorithm, &pbSignature, &cbSignature)) goto ErrorReturn;
memset(&CertEncoding, 0, sizeof(CertEncoding)); CertEncoding.ToBeSigned.pbData = pbToBeSigned; CertEncoding.ToBeSigned.cbData = cbToBeSigned; CertEncoding.SignatureAlgorithm = SignatureAlgorithm; CertEncoding.Signature.pbData = pbSignature; CertEncoding.Signature.cbData = cbSignature;
if (!AllocAndEncodeObject( X509_CERT, &CertEncoding, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if (pbSignature) TestFree(pbSignature); *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL GetPublicKey( DWORD dwCert, PCERT_PUBLIC_KEY_INFO *ppPubKeyInfo) { BOOL fResult; PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL; DWORD cbPubKeyInfo; DWORD dwKeySpec; HCRYPTPROV hProv;
if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) dwKeySpec = AT_KEYEXCHANGE; else dwKeySpec = AT_SIGNATURE;
if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) { if (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG) hProv = hDSS512CryptProv; else hProv = hDSSCryptProv; } else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG) hProv = hEnh1024CryptProv; else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG) hProv = hEnh2048CryptProv; else hProv = hRSACryptProv;
cbPubKeyInfo = 0; CryptExportPublicKeyInfo( hProv, dwKeySpec, dwCertEncodingType, NULL, // pPubKeyInfo
&cbPubKeyInfo ); if (cbPubKeyInfo == 0) { PrintLastError("GetPublicKey::CryptExportPublicKeyInfo(cb == 0)"); goto ErrorReturn; } pPubKeyInfo = (PCERT_PUBLIC_KEY_INFO) TestAlloc(cbPubKeyInfo); if (pPubKeyInfo == NULL) goto ErrorReturn; if (!CryptExportPublicKeyInfo( hProv, dwKeySpec, dwCertEncodingType, pPubKeyInfo, &cbPubKeyInfo )) { PrintLastError("GetPublicKey::CryptExportPublicKeyInfo"); goto ErrorReturn; }
if (fInheritParameters) { DWORD dwIssuer = CertPara[dwCert].dwIssuer;
if (dwCert != dwIssuer && 0 == (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) && 0 == (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG) && 0 != (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) && 0 == (CertPara[dwIssuer].dwFlags & DSS_512_PARA_FLAG) && 0 != (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG)) { pPubKeyInfo->Algorithm.Parameters.cbData = 0; pPubKeyInfo->Algorithm.Parameters.pbData = NULL; } }
fResult = TRUE; goto CommonReturn;
ErrorReturn: fResult = FALSE; if (pPubKeyInfo) { TestFree(pPubKeyInfo); pPubKeyInfo = NULL; } CommonReturn: *ppPubKeyInfo = pPubKeyInfo; return fResult; }
#define SHA1_HASH_LEN 20
static BOOL Sha1HashPublicKey( DWORD dwCert, BYTE rgbHash[SHA1_HASH_LEN] ) { BOOL fResult; PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL; DWORD cbHash;
// Get Certificates's PUBLIC KEY. SHA1 hash the encoded public key.
if (!GetPublicKey(dwCert, &pPubKeyInfo)) goto ErrorReturn;
#if 1
cbHash = SHA1_HASH_LEN; if (!CryptHashPublicKeyInfo( 0, // hCryptProv
CALG_SHA1, 0, dwCertEncodingType, pPubKeyInfo, rgbHash, &cbHash)) { PrintLastError("Sha1HashPublicKey::CryptHashPublicKeyInfo"); goto ErrorReturn; } #else
cbHash = SHA1_HASH_LEN; if (!CryptHashCertificate( 0, // hCryptProv
CALG_SHA1, 0, // dwFlags
pPubKeyInfo->PublicKey.pbData, pPubKeyInfo->PublicKey.cbData, rgbHash, &cbHash)) { PrintLastError("Sha1HashPublicKey::CryptHashCertificate"); goto ErrorReturn; } #endif
fResult = TRUE; goto CommonReturn;
ErrorReturn: fResult = FALSE; memset(rgbHash, 0, SHA1_HASH_LEN); CommonReturn: if (pPubKeyInfo) TestFree(pPubKeyInfo); return fResult; }
static void CreateNameInfo( DWORD dwCert, PCERT_NAME_INFO pInfo, PCERT_RDN pRDN, CERT_RDN_ATTR rgAttr[] ) { LPSTR pszKey; LPSTR pszUser; DWORD i;
assert(RDN_CNT == ATTR_CNT); for (i = 0; i < RDN_CNT; i++) { pRDN[i].cRDNAttr = 1; pRDN[i].rgRDNAttr = &rgAttr[i]; }
if (CertPara[dwCert].dwFlags & NO_NAME_PARA_FLAG) { pInfo->cRDN = 0; pInfo->rgRDN = NULL; } else if (CertPara[dwCert].dwFlags & VALID_PARA_FLAG) { pInfo->cRDN = 1; pInfo->rgRDN = pRDN; } else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) { pInfo->cRDN = RDN_CNT - 1; pInfo->rgRDN = pRDN; } else { pInfo->cRDN = RDN_CNT; pInfo->rgRDN = pRDN; }
rgAttr[0].pszObjId = ATTR_0_OBJID; if (0 == strcmp("UTF8", CertPara[dwCert].pszName)) { rgAttr[0].dwValueType = CERT_RDN_UTF8_STRING; rgAttr[0].Value.pbData = (BYTE *) UTF8_NAME; rgAttr[0].Value.cbData = wcslen(UTF8_NAME) * sizeof(WCHAR); } else { rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = (BYTE *) CertPara[dwCert].pszName; rgAttr[0].Value.cbData = strlen(CertPara[dwCert].pszName); }
rgAttr[1].pszObjId = ATTR_1_OBJID; rgAttr[1].dwValueType = CERT_RDN_PRINTABLE_STRING; if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) pszKey = "xchg"; else pszKey = "sign"; rgAttr[1].Value.pbData = (BYTE *) pszKey; rgAttr[1].Value.cbData = strlen(pszKey);
rgAttr[2].pszObjId = ATTR_2_OBJID; rgAttr[2].dwValueType = CERT_RDN_PRINTABLE_STRING; if (pszContainer) pszUser = pszContainer; else pszUser = "default"; rgAttr[2].Value.pbData = (BYTE *) pszUser; rgAttr[2].Value.cbData = strlen(pszUser);
rgAttr[3].pszObjId = szOID_RSA_emailAddr; rgAttr[3].dwValueType = CERT_RDN_IA5_STRING; rgAttr[3].Value.pbData = (BYTE *) " [email protected] "; rgAttr[3].Value.cbData = strlen(" [email protected] ");
assert(ATTR_CNT == 3+1); }
static BOOL CreateAuthorityKeyId( DWORD dwIssuer, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; BYTE *pbNameEncoded = NULL; DWORD cbNameEncoded; CERT_AUTHORITY_KEY_ID_INFO KeyIdInfo;
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name; FILETIME SerialNumber;
memset(&KeyIdInfo, 0, sizeof(KeyIdInfo));
// Issuer's KeyId
KeyIdInfo.KeyId.pbData = (BYTE *) &dwIssuer; KeyIdInfo.KeyId.cbData = sizeof(dwIssuer);
// Issuer's Issuer
CreateNameInfo(CertPara[dwIssuer].dwIssuer, &Name, rgRDN, rgAttr);
if (!AllocAndEncodeObject( X509_NAME, &Name, &pbNameEncoded, &cbNameEncoded)) goto ErrorReturn;
KeyIdInfo.CertIssuer.pbData = pbNameEncoded; KeyIdInfo.CertIssuer.cbData = cbNameEncoded;
// Issuer's SerialNumber
{ SYSTEMTIME SystemTime = TestTime; SystemTime.wMilliseconds += (WORD) dwIssuer; MySystemTimeToFileTime(&SystemTime, &SerialNumber); } KeyIdInfo.CertSerialNumber.pbData = (BYTE *) &SerialNumber; KeyIdInfo.CertSerialNumber.cbData = sizeof(SerialNumber);
if (!AllocAndEncodeObject( X509_AUTHORITY_KEY_ID, &KeyIdInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if (pbNameEncoded) TestFree(pbNameEncoded);
*ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateAuthorityKeyId2( DWORD dwCert, DWORD dwIssuer, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded, IN DWORD dwAki = AKI2_KEYID ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; BYTE *pbNameEncoded = NULL; DWORD cbNameEncoded; CERT_AUTHORITY_KEY_ID2_INFO KeyId2Info; CERT_ALT_NAME_ENTRY AltNameEntry;
BYTE rgbPubKeyHash[SHA1_HASH_LEN];
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name; FILETIME SerialNumber;
memset(&KeyId2Info, 0, sizeof(KeyId2Info));
// Issuer's KeyId
if (AKI2_BAD_KEYID == dwAki) memset(rgbPubKeyHash, 0xba, sizeof(rgbPubKeyHash)); else Sha1HashPublicKey(dwIssuer, rgbPubKeyHash); KeyId2Info.KeyId.pbData = rgbPubKeyHash; KeyId2Info.KeyId.cbData = sizeof(rgbPubKeyHash);
if (AKI2_FULL == dwAki || AKI2_BAD_ISSUER == dwAki || AKI2_BAD_SERIAL_NUMBER == dwAki || (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG)) {
if (AKI2_BAD_ISSUER == dwAki) { Name.cRDN = 1; Name.rgRDN = rgRDN; rgRDN[0].cRDNAttr = 1; rgRDN[0].rgRDNAttr = rgAttr;
rgAttr[0].pszObjId = szOID_COMMON_NAME; rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = (BYTE *) "AKI2BadIssuer"; rgAttr[0].Value.cbData = strlen("AKI2BadIssuer"); } else // Issuer's Issuer
CreateNameInfo(CertPara[dwIssuer].dwIssuer, &Name, rgRDN, rgAttr);
if (!AllocAndEncodeObject( X509_NAME, &Name, &pbNameEncoded, &cbNameEncoded)) goto ErrorReturn;
AltNameEntry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; AltNameEntry.DirectoryName.pbData = pbNameEncoded; AltNameEntry.DirectoryName.cbData = cbNameEncoded; KeyId2Info.AuthorityCertIssuer.cAltEntry = 1; KeyId2Info.AuthorityCertIssuer.rgAltEntry = &AltNameEntry;
// Issuer's SerialNumber
{ SYSTEMTIME SystemTime = TestTime; if (AKI2_BAD_SERIAL_NUMBER == dwAki) SystemTime.wMilliseconds += CERT_CNT; else SystemTime.wMilliseconds += (WORD) dwIssuer; MySystemTimeToFileTime(&SystemTime, &SerialNumber); } KeyId2Info.AuthorityCertSerialNumber.pbData = (BYTE *) &SerialNumber; KeyId2Info.AuthorityCertSerialNumber.cbData = sizeof(SerialNumber); }
if (!AllocAndEncodeObject( X509_AUTHORITY_KEY_ID2, &KeyId2Info, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if (pbNameEncoded) TestFree(pbNameEncoded);
*ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateAuthorityInfoAccess( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; DWORD dwIssuer = CertPara[dwCert].dwIssuer; BYTE *pbEncoded = NULL; DWORD cbEncoded; BYTE *pbNameEncoded = NULL; DWORD cbNameEncoded; CERT_AUTHORITY_INFO_ACCESS AuthorityInfoAccess;
#define ACCESS_DESCR_COUNT 12
CERT_ACCESS_DESCRIPTION rgAccess[ACCESS_DESCR_COUNT];
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name;
// Issuer's Issuer
CreateNameInfo(CertPara[dwIssuer].dwIssuer, &Name, rgRDN, rgAttr);
if (!AllocAndEncodeObject( X509_NAME, &Name, &pbNameEncoded, &cbNameEncoded)) goto ErrorReturn;
rgAccess[0].pszAccessMethod = szOID_PKIX_OCSP; rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[0].AccessLocation.pwszURL = L"URL to the stars"; rgAccess[1].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[1].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgAccess[1].AccessLocation.DirectoryName.pbData = pbNameEncoded; rgAccess[1].AccessLocation.DirectoryName.cbData = cbNameEncoded; rgAccess[2].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[2].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgAccess[2].AccessLocation.pwszRfc822Name = L"[email protected]"; rgAccess[3].pszAccessMethod = szOID_PKIX_OCSP; rgAccess[3].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[3].AccessLocation.pwszURL = L"URL to the POLICY"; rgAccess[4].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[4].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[4].AccessLocation.pwszURL = L"http://URLToTheIssuerCertificate"; rgAccess[5].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[5].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[5].AccessLocation.pwszURL = L"ldap://ntdev.microsoft.com/c=us??sub"; rgAccess[6].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[6].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[6].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate"; rgAccess[7].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[7].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[7].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate"; rgAccess[8].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[8].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[8].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate"; rgAccess[9].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[9].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[9].AccessLocation.pwszURL = L"file://FileToTheIssuerCertificate"; rgAccess[10].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[10].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[10].AccessLocation.pwszURL = L"http://crl.verisign.com/class1.crl"; rgAccess[11].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[11].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[11].AccessLocation.pwszURL = L"http://crl.microsoft.com/pki/crl/products/CodeSignPCA.crl";
memset(&AuthorityInfoAccess, 0, sizeof(AuthorityInfoAccess)); if (0 == strcmp("TestAIAEnd", CertPara[dwCert].pszName)) { rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[0].AccessLocation.pwszURL = L"file://TestAIACA.p7b"; AuthorityInfoAccess.cAccDescr = 1; AuthorityInfoAccess.rgAccDescr = rgAccess; } else if (0 == strcmp("RolloverCA", CertPara[dwCert].pszName)) { rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[0].AccessLocation.pwszURL = L"file://RolloverAIARoot.p7b"; AuthorityInfoAccess.cAccDescr = 1; AuthorityInfoAccess.rgAccDescr = rgAccess; } else if (0 == strcmp("kevin", CertPara[dwCert].pszName)) { rgAccess[0].pszAccessMethod = szOID_PKIX_CA_ISSUERS; rgAccess[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL; rgAccess[0].AccessLocation.pwszURL = L"http://vbl03ca.ntdev.microsoft.com/CertEnroll/vbl03ca.ntdev.microsoft.com_Microsoft%20Windows%20VBL03CA.crt"; AuthorityInfoAccess.cAccDescr = 1; AuthorityInfoAccess.rgAccDescr = rgAccess; } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { AuthorityInfoAccess.cAccDescr = 11; AuthorityInfoAccess.rgAccDescr = &rgAccess[1]; } else { AuthorityInfoAccess.cAccDescr = 1; AuthorityInfoAccess.rgAccDescr = rgAccess; }
if (!AllocAndEncodeObject( X509_AUTHORITY_INFO_ACCESS, &AuthorityInfoAccess, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if (pbNameEncoded) TestFree(pbNameEncoded);
*ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BYTE CrlIPAddress[] = {1,2,3,4}; #define CRL_DNS_NAME L"CRL.DNS.NAME.COM"
#define CRL_EMAIL_NAME L"[email protected]"
#define CRL_URL_NAME1 L"file://crltest1.p7b"
#define CRL_URL_NAME2 L"file://crltest2.p7b"
#define CRL_REGISTERED_ID "1.2.3.4.5.6"
static BYTE rgbCrlOtherName[] = {0x02, 0x02, 0x11, 0x22}; static CERT_OTHER_NAME CrlOtherName = { "1.2.33.44.55.66", sizeof(rgbCrlOtherName), rgbCrlOtherName };
#define CRL_DIST_POINTS_DELTA_FLAG 0x1
#define CRL_DIST_POINTS_UNSUPPORTED_FLAG 0x2
static BOOL CreateCrlDistPoints( DWORD dwIssuer, BOOL dwFlags, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CRL_DIST_POINTS_INFO CrlDistPointsInfo;
BYTE bReasonFlags; CERT_ALT_NAME_ENTRY rgAltNameEntry[9]; CERT_ALT_NAME_ENTRY rgIssuerAltNameEntry[1]; CRL_DIST_POINT rgDistPoint[5];
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name; BYTE *pbIssuerNameEncoded = NULL; DWORD cbIssuerNameEncoded;
if (dwFlags & CRL_DIST_POINTS_DELTA_FLAG) { // ISSUER
CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr); if (!AllocAndEncodeObject( X509_NAME, &Name, &pbIssuerNameEncoded, &cbIssuerNameEncoded )) goto ErrorReturn;
rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgAltNameEntry[0].pwszDNSName = CRL_DNS_NAME; rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgAltNameEntry[1].pwszRfc822Name = CRL_EMAIL_NAME; rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgAltNameEntry[2].IPAddress.pbData = CrlIPAddress; rgAltNameEntry[2].IPAddress.cbData = sizeof(CrlIPAddress); rgAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID; rgAltNameEntry[3].pszRegisteredID = CRL_REGISTERED_ID; rgAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[4].pwszURL = CRL_URL_NAME2; rgAltNameEntry[5].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgAltNameEntry[5].pOtherName = &CrlOtherName; rgAltNameEntry[6].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[6].pwszURL = CRL_URL_NAME1; rgAltNameEntry[7].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgAltNameEntry[7].DirectoryName.pbData = pbIssuerNameEncoded; rgAltNameEntry[7].DirectoryName.cbData = cbIssuerNameEncoded; rgAltNameEntry[8].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[8].pwszURL = L"file://BadUnsupportedChoice.crl";
rgIssuerAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL; rgIssuerAltNameEntry[0].pwszURL = L"CRL Issuer URL";
memset(rgDistPoint, 0, sizeof(rgDistPoint));
// [0] has unsupported ReasonFlags
rgDistPoint[0].DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; rgDistPoint[0].DistPointName.FullName.cAltEntry = 1; rgDistPoint[0].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[8]; rgDistPoint[0].ReasonFlags.cbData = 1; rgDistPoint[0].ReasonFlags.pbData = &bReasonFlags; rgDistPoint[0].ReasonFlags.cUnusedBits = 1; bReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG | CRL_REASON_CA_COMPROMISE_FLAG; // [1] has unsupported CRLIssuer
rgDistPoint[1].DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; rgDistPoint[1].DistPointName.FullName.cAltEntry = 1; rgDistPoint[1].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[8]; rgDistPoint[1].CRLIssuer.cAltEntry = 1; rgDistPoint[1].CRLIssuer.rgAltEntry = rgIssuerAltNameEntry; // [2] is empty
rgDistPoint[3].DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; rgDistPoint[3].DistPointName.FullName.cAltEntry = 5; rgDistPoint[3].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0]; rgDistPoint[4].DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; rgDistPoint[4].DistPointName.FullName.cAltEntry = 3; rgDistPoint[4].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[5];
memset(&CrlDistPointsInfo, 0, sizeof(CrlDistPointsInfo)); CrlDistPointsInfo.rgDistPoint = &rgDistPoint[0]; if (dwFlags & CRL_DIST_POINTS_UNSUPPORTED_FLAG) CrlDistPointsInfo.cDistPoint = 1; else CrlDistPointsInfo.cDistPoint = 5; } else { rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[0].pwszURL = L"file://test1.crl";
memset(rgDistPoint, 0, sizeof(rgDistPoint)); rgDistPoint[0].DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; rgDistPoint[0].DistPointName.FullName.cAltEntry = 1; rgDistPoint[0].DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
memset(&CrlDistPointsInfo, 0, sizeof(CrlDistPointsInfo)); CrlDistPointsInfo.rgDistPoint = &rgDistPoint[0]; CrlDistPointsInfo.cDistPoint = 1; }
if (!AllocAndEncodeObject( X509_CRL_DIST_POINTS, &CrlDistPointsInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if(pbIssuerNameEncoded) TestFree(pbIssuerNameEncoded); *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateCertIssuingDistPoint( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CRL_ISSUING_DIST_POINT Info;
BYTE bOnlySomeReasonFlags; CERT_ALT_NAME_ENTRY rgAltNameEntry[2];
rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[0].pwszURL = L"file://test1.crl"; rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[1].pwszURL = L"file://test1.crl";
memset(&Info, 0, sizeof(Info)); Info.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; Info.DistPointName.FullName.cAltEntry = 2; Info.DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
Info.OnlySomeReasonFlags.cbData = 1; Info.OnlySomeReasonFlags.pbData = &bOnlySomeReasonFlags; Info.OnlySomeReasonFlags.cUnusedBits = 1; bOnlySomeReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG | CRL_REASON_CA_COMPROMISE_FLAG;
Info.fIndirectCRL = TRUE; Info.fOnlyContainsUserCerts = TRUE; Info.fOnlyContainsCACerts = TRUE;
if (!AllocAndEncodeObject( X509_ISSUING_DIST_POINT, &Info, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateCrlIssuingDistPoint( OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CRL_ISSUING_DIST_POINT Info;
CERT_ALT_NAME_ENTRY rgAltNameEntry[1];
rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[0].pwszURL = L"file://test1.crl";
memset(&Info, 0, sizeof(Info)); Info.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; Info.DistPointName.FullName.cAltEntry = 1; Info.DistPointName.FullName.rgAltEntry = &rgAltNameEntry[0];
if (!AllocAndEncodeObject( szOID_ISSUING_DIST_POINT, &Info, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateNameConstraints( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; PCERT_NAME_CONSTRAINTS_INFO pInfo;
CERT_NAME_CONSTRAINTS_INFO RootInfo; CERT_GENERAL_SUBTREE rgRootPermitted[15]; CERT_GENERAL_SUBTREE rgRootExcluded[15];
CERT_NAME_CONSTRAINTS_INFO CaInfo; CERT_GENERAL_SUBTREE rgCaPermitted[15];
CERT_NAME_CONSTRAINTS_INFO MissingInfo; CERT_GENERAL_SUBTREE rgMissingPermitted[15]; CERT_GENERAL_SUBTREE rgMissingExcluded[15];
BYTE rgbMissing[3] = {2, 1, 1}; // INTEGER
CERT_OTHER_NAME MissingOtherName = {"1.2.3.4.5.6", sizeof(rgbMissing), rgbMissing};
BYTE rgbEmpty[2] = {5, 0}; // NULL
CERT_OTHER_NAME AnyOctetOtherName = {OCTET_OTHER_NAME_OID, sizeof(rgbEmpty), rgbEmpty}; CERT_OTHER_NAME AnyStringOtherName = {STRING_OTHER_NAME_OID, sizeof(rgbEmpty), rgbEmpty};
CERT_NAME_VALUE NameValue; CERT_OTHER_NAME PermittedUPNOtherName; BYTE *pbPermittedUPNNameEncoded = NULL; DWORD cbPermittedUPNNameEncoded;
CERT_OTHER_NAME ExcludedUPNOtherName; BYTE *pbExcludedUPNNameEncoded = NULL; DWORD cbExcludedUPNNameEncoded;
CERT_OTHER_NAME AnyUPNOtherName; BYTE *pbAnyUPNNameEncoded = NULL; DWORD cbAnyUPNNameEncoded;
CERT_OTHER_NAME PermittedStringOtherName; BYTE *pbPermittedStringOtherNameEncoded = NULL; DWORD cbPermittedStringOtherNameEncoded;
CERT_OTHER_NAME ExcludedStringOtherName; BYTE *pbExcludedStringOtherNameEncoded = NULL; DWORD cbExcludedStringOtherNameEncoded;
BYTE rgbDefaultIPAddress[] = {1,1,0,0, 255,255,0,0}; BYTE rgbAllExtIPAddress[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0xF0}; BYTE rgbExcludedIPAddress[] = {2,2,2,2, 255,254,254,254};
CERT_RDN rgRDN[3]; CERT_RDN_ATTR rgAttr[3]; CERT_NAME_INFO NameInfo; BYTE *pbPermittedNameEncoded = NULL; DWORD cbPermittedNameEncoded; BYTE *pbExcludedNameEncoded = NULL; DWORD cbExcludedNameEncoded; BYTE *pbAnyOUNameEncoded = NULL; DWORD cbAnyOUNameEncoded; BYTE *pbAnyNameEncoded = NULL; DWORD cbAnyNameEncoded; LPSTR pszSign = "\n sign \r";
DWORD i;
NameValue.dwValueType = CERT_RDN_BMP_STRING; NameValue.Value.pbData = (BYTE *) L" @UPN.COM "; NameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &NameValue, &pbPermittedUPNNameEncoded, &cbPermittedUPNNameEncoded)) goto ErrorReturn;
PermittedUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME; PermittedUPNOtherName.Value.pbData = pbPermittedUPNNameEncoded; PermittedUPNOtherName.Value.cbData = cbPermittedUPNNameEncoded;
NameValue.dwValueType = CERT_RDN_UNIVERSAL_STRING; NameValue.Value.pbData = (BYTE *) L" [email protected] "; NameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &NameValue, &pbExcludedUPNNameEncoded, &cbExcludedUPNNameEncoded)) goto ErrorReturn;
ExcludedUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME; ExcludedUPNOtherName.Value.pbData = pbExcludedUPNNameEncoded; ExcludedUPNOtherName.Value.cbData = cbExcludedUPNNameEncoded;
NameValue.dwValueType = CERT_RDN_PRINTABLE_STRING; NameValue.Value.pbData = (BYTE *) L""; NameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &NameValue, &pbAnyUPNNameEncoded, &cbAnyUPNNameEncoded)) goto ErrorReturn;
AnyUPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME; AnyUPNOtherName.Value.pbData = pbAnyUPNNameEncoded; AnyUPNOtherName.Value.cbData = cbAnyUPNNameEncoded;
NameValue.dwValueType = CERT_RDN_VISIBLE_STRING; NameValue.Value.pbData = (BYTE *) L" String@OtherName "; NameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &NameValue, &pbPermittedStringOtherNameEncoded, &cbPermittedStringOtherNameEncoded)) goto ErrorReturn;
PermittedStringOtherName.pszObjId = STRING_OTHER_NAME_OID; PermittedStringOtherName.Value.pbData = pbPermittedStringOtherNameEncoded; PermittedStringOtherName.Value.cbData = cbPermittedStringOtherNameEncoded;
NameValue.dwValueType = CERT_RDN_GRAPHIC_STRING; NameValue.Value.pbData = (BYTE *) L" excludedString@OtherName "; NameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &NameValue, &pbExcludedStringOtherNameEncoded, &cbExcludedStringOtherNameEncoded)) goto ErrorReturn;
ExcludedStringOtherName.pszObjId = STRING_OTHER_NAME_OID; ExcludedStringOtherName.Value.pbData = pbExcludedStringOtherNameEncoded; ExcludedStringOtherName.Value.cbData = cbExcludedStringOtherNameEncoded;
for (i = 0; i < 3; i++) { rgRDN[i].cRDNAttr = 1; rgRDN[i].rgRDNAttr = &rgAttr[i]; }
// Any
rgAttr[0].pszObjId = ATTR_0_OBJID; rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = NULL; rgAttr[0].Value.cbData = 0;
rgAttr[1].pszObjId = ATTR_1_OBJID; rgAttr[1].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[1].Value.pbData = (BYTE *) pszSign; rgAttr[1].Value.cbData = strlen(pszSign);
rgAttr[2].pszObjId = ATTR_2_OBJID; rgAttr[2].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[2].Value.pbData = (BYTE *) "default"; rgAttr[2].Value.cbData = strlen("default");
NameInfo.cRDN = 3; NameInfo.rgRDN = rgRDN;
if (!AllocAndEncodeObject( X509_NAME, &NameInfo, &pbPermittedNameEncoded, &cbPermittedNameEncoded )) goto ErrorReturn;
rgAttr[0].pszObjId = ATTR_0_OBJID; rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = (BYTE *) "excluded"; rgAttr[0].Value.cbData = strlen("excluded"); NameInfo.cRDN = 1; NameInfo.rgRDN = rgRDN;
if (!AllocAndEncodeObject( X509_NAME, &NameInfo, &pbExcludedNameEncoded, &cbExcludedNameEncoded )) goto ErrorReturn;
rgAttr[0].pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME; rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = NULL; rgAttr[0].Value.cbData = 0; NameInfo.cRDN = 1; NameInfo.rgRDN = rgRDN;
if (!AllocAndEncodeObject( X509_NAME, &NameInfo, &pbAnyOUNameEncoded, &cbAnyOUNameEncoded )) goto ErrorReturn;
NameInfo.cRDN = 0; NameInfo.rgRDN = rgRDN;
if (!AllocAndEncodeObject( X509_NAME, &NameInfo, &pbAnyNameEncoded, &cbAnyNameEncoded )) goto ErrorReturn;
memset(&rgRootPermitted, 0, sizeof(rgRootPermitted)); rgRootPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgRootPermitted[0].Base.pwszDNSName = L"dns Name "; rgRootPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgRootPermitted[1].Base.pwszRfc822Name = L" eMail.COM"; rgRootPermitted[2].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgRootPermitted[2].Base.pwszDNSName = L" kevin "; rgRootPermitted[3].Base.dwAltNameChoice = CERT_ALT_NAME_URL; rgRootPermitted[3].Base.pwszURL = L".url.com"; rgRootPermitted[4].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgRootPermitted[4].Base.pOtherName = &PermittedUPNOtherName;
rgRootPermitted[5].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgRootPermitted[5].Base.IPAddress.pbData = rgbDefaultIPAddress; rgRootPermitted[5].Base.IPAddress.cbData = sizeof(rgbDefaultIPAddress); rgRootPermitted[6].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgRootPermitted[6].Base.IPAddress.pbData = rgbAllExtIPAddress; rgRootPermitted[6].Base.IPAddress.cbData = sizeof(rgbAllExtIPAddress);
rgRootPermitted[7].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgRootPermitted[7].Base.pwszRfc822Name = L" [email protected] ";
rgRootPermitted[8].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgRootPermitted[8].Base.DirectoryName.pbData = pbPermittedNameEncoded; rgRootPermitted[8].Base.DirectoryName.cbData = cbPermittedNameEncoded; rgRootPermitted[9].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgRootPermitted[9].Base.DirectoryName.pbData = pbAnyOUNameEncoded; rgRootPermitted[9].Base.DirectoryName.cbData = cbAnyOUNameEncoded;
rgRootPermitted[10].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgRootPermitted[10].Base.pOtherName = &PermittedStringOtherName; rgRootPermitted[11].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgRootPermitted[11].Base.pOtherName = &AnyOctetOtherName;
rgRootPermitted[12].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgRootPermitted[12].Base.pwszRfc822Name = L"[email protected]";
memset(&rgRootExcluded, 0, sizeof(rgRootExcluded)); rgRootExcluded[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgRootExcluded[0].Base.pwszDNSName = L"www.ExcLuDed.dns.com "; rgRootExcluded[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgRootExcluded[1].Base.pwszRfc822Name = L"[email protected]"; rgRootExcluded[2].Base.dwAltNameChoice = CERT_ALT_NAME_URL; rgRootExcluded[2].Base.pwszURL = L"excluded.url.com"; rgRootExcluded[3].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgRootExcluded[3].Base.pOtherName = &ExcludedUPNOtherName;
rgRootExcluded[4].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgRootExcluded[4].Base.IPAddress.pbData = rgbExcludedIPAddress; rgRootExcluded[4].Base.IPAddress.cbData = sizeof(rgbExcludedIPAddress);
rgRootExcluded[5].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgRootExcluded[5].Base.DirectoryName.pbData = pbExcludedNameEncoded; rgRootExcluded[5].Base.DirectoryName.cbData = cbExcludedNameEncoded;
rgRootExcluded[6].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgRootExcluded[6].Base.pOtherName = &ExcludedStringOtherName;
memset(&RootInfo, 0, sizeof(RootInfo)); RootInfo.cPermittedSubtree = 13; RootInfo.rgPermittedSubtree = rgRootPermitted; RootInfo.cExcludedSubtree = 7; RootInfo.rgExcludedSubtree = rgRootExcluded;
memset(&rgCaPermitted, 0, sizeof(rgCaPermitted)); rgCaPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgCaPermitted[0].Base.pwszDNSName = L""; rgCaPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgCaPermitted[1].Base.pwszRfc822Name = L""; rgCaPermitted[2].Base.dwAltNameChoice = CERT_ALT_NAME_URL; rgCaPermitted[2].Base.pwszURL = L""; rgCaPermitted[3].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgCaPermitted[3].Base.pOtherName = &AnyUPNOtherName; rgCaPermitted[4].Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgCaPermitted[4].Base.IPAddress.pbData = NULL; rgCaPermitted[4].Base.IPAddress.cbData = 0; rgCaPermitted[5].Base.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgCaPermitted[5].Base.DirectoryName.pbData = pbAnyNameEncoded; rgCaPermitted[5].Base.DirectoryName.cbData = cbAnyNameEncoded;
rgCaPermitted[6].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgCaPermitted[6].Base.pOtherName = &AnyOctetOtherName; rgCaPermitted[7].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgCaPermitted[7].Base.pOtherName = &AnyStringOtherName;
memset(&CaInfo, 0, sizeof(CaInfo)); CaInfo.cPermittedSubtree = 8; CaInfo.rgPermittedSubtree = rgCaPermitted; CaInfo.cExcludedSubtree = 0; CaInfo.rgExcludedSubtree = NULL;
memset(&rgMissingPermitted, 0, sizeof(rgMissingPermitted)); rgMissingPermitted[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgMissingPermitted[0].Base.pwszDNSName = L"a super dns Name "; rgMissingPermitted[0].dwMinimum = 1; rgMissingPermitted[1].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgMissingPermitted[1].Base.pOtherName = &MissingOtherName;
memset(&rgMissingExcluded, 0, sizeof(rgMissingExcluded)); rgMissingExcluded[0].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgMissingExcluded[0].Base.pwszDNSName = L"www.ReallyExcLuDed.dns.com "; rgMissingExcluded[1].Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgMissingExcluded[1].Base.pwszDNSName = L"www.ExcLuDed.dns.com "; rgMissingExcluded[1].fMaximum = TRUE; rgMissingExcluded[1].dwMaximum = 2; rgMissingExcluded[2].Base.dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgMissingExcluded[2].Base.pOtherName = &MissingOtherName;
memset(&MissingInfo, 0, sizeof(MissingInfo)); MissingInfo.cPermittedSubtree = 2; MissingInfo.rgPermittedSubtree = rgMissingPermitted; MissingInfo.cExcludedSubtree = 3; MissingInfo.rgExcludedSubtree = rgMissingExcluded;
if (dwCert == POLICY_ROOT) pInfo = &RootInfo; else if (dwCert == POLICY_CA) pInfo = &CaInfo; else if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCCA")) pInfo = &MissingInfo; else goto ErrorReturn;
if (!AllocAndEncodeObject( X509_NAME_CONSTRAINTS, pInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: TestFree(pbPermittedUPNNameEncoded); TestFree(pbExcludedUPNNameEncoded); TestFree(pbAnyUPNNameEncoded); TestFree(pbPermittedNameEncoded); TestFree(pbExcludedNameEncoded); TestFree(pbPermittedStringOtherNameEncoded); TestFree(pbExcludedStringOtherNameEncoded); TestFree(pbAnyOUNameEncoded); TestFree(pbAnyNameEncoded);
*ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreatePolicyMappings( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; PCERT_POLICY_MAPPINGS_INFO pInfo;
CERT_POLICY_MAPPING rgRootPolicyMapping[] = { "1.1.22", "1.2.22.1", "1.1.22", "1.2.22.2", // multiple subjects may map to same issuer
"1.1.4444", "1.2.4444", "1.1.4444", "1.1.4444", // multiple subjects for same issuer
"1.1.22.333", "1.2.22.1", // duplicate subject
"1.1.22", "1.2.22.3", "1.1.333", "1.2.333.1", "1.1.333", "1.2.333.2", "1.1.333", "1.2.333.3", "1.1.22", "1.2.22.3", // multiple subjects for same issuer
"1.1.22", "1.2.22.3", // duplicate subject
"1.1.22", "1.2.22.4", // multiple subjects for same issuer
}; CERT_POLICY_MAPPINGS_INFO RootInfo = { sizeof(rgRootPolicyMapping) / sizeof(rgRootPolicyMapping[0]), rgRootPolicyMapping };
CERT_POLICY_MAPPING rgCaPolicyMapping[] = { "1.1.1", "1.3.1.1", "1.1.1", "1.3.1.2", "1.2.22.2", "1.3.22.2.1", // -> 1.1.22
"1.2.22.2", "1.3.22.2.2", // -> 1.1.22
}; CERT_POLICY_MAPPINGS_INFO CaInfo = { sizeof(rgCaPolicyMapping) / sizeof(rgCaPolicyMapping[0]), rgCaPolicyMapping };
if (dwCert == POLICY_ROOT) pInfo = &RootInfo; else if (dwCert == POLICY_CA) pInfo = &CaInfo; else goto ErrorReturn;
if (!AllocAndEncodeObject( X509_POLICY_MAPPINGS, pInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreatePolicyConstraints( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; PCERT_POLICY_CONSTRAINTS_INFO pInfo;
CERT_POLICY_CONSTRAINTS_INFO RootInfo = { TRUE, // fRequireExplicitPolicy
1, // dwRequireExplicitPolicySkipCerts
TRUE, // fInhibitPolicyMapping
1 // dwInhibitPolicyMappingSkipCerts
};
CERT_POLICY_CONSTRAINTS_INFO CaInfo = { TRUE, // fRequireExplicitPolicy
0, // dwRequireExplicitPolicySkipCerts
TRUE, // fInhibitPolicyMapping
0 // dwInhibitPolicyMappingSkipCerts
};
if (dwCert == POLICY_ROOT) pInfo = &RootInfo; else if (dwCert == POLICY_CA) pInfo = &CaInfo; else if (dwCert == ROLLOVER_CROSS_CERT) { CaInfo.dwRequireExplicitPolicySkipCerts = 2; pInfo = &CaInfo; } else goto ErrorReturn; if (!AllocAndEncodeObject( X509_POLICY_CONSTRAINTS, pInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateCrossCertDistPoints( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CROSS_CERT_DIST_POINTS_INFO Info; CERT_ALT_NAME_INFO rgDistPoint[2]; CERT_ALT_NAME_ENTRY rgAltNameEntry[3];
rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[0].pwszURL = L"file://vsgood.cer"; rgAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[1].pwszURL = L"file://nt.store"; rgAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[2].pwszURL = L"file://win95.store";
rgDistPoint[0].cAltEntry = 1; rgDistPoint[0].rgAltEntry = &rgAltNameEntry[0]; rgDistPoint[1].cAltEntry = 2; rgDistPoint[1].rgAltEntry = &rgAltNameEntry[1];
memset(&Info, 0, sizeof(Info)); Info.dwSyncDeltaTime = 60 * 60 * 8; Info.cDistPoint = 2; Info.rgDistPoint = rgDistPoint;
if (!AllocAndEncodeObject( X509_CROSS_CERT_DIST_POINTS, &Info, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateKeyId( DWORD dwIssuer, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BYTE rgbPubKeyHash[SHA1_HASH_LEN]; CRYPT_DATA_BLOB KeyIdentifier;
Sha1HashPublicKey(dwIssuer, rgbPubKeyHash);
KeyIdentifier.pbData = rgbPubKeyHash; KeyIdentifier.cbData = sizeof(rgbPubKeyHash);
return AllocAndEncodeObject( X509_OCTET_STRING, &KeyIdentifier, ppbEncoded, pcbEncoded ); }
static BOOL CreateKeyAttributes( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CERT_KEY_ATTRIBUTES_INFO KeyAttrInfo; CERT_PRIVATE_KEY_VALIDITY KeyValidity;
BYTE bIntendedKeyUsage;
memset(&KeyAttrInfo, 0, sizeof(KeyAttrInfo));
if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) { // Issuer's KeyId
KeyAttrInfo.KeyId.pbData = (BYTE *) &dwCert; KeyAttrInfo.KeyId.cbData = sizeof(dwCert); }
if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) bIntendedKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE; else bIntendedKeyUsage = CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE; if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) bIntendedKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
KeyAttrInfo.IntendedKeyUsage.pbData = &bIntendedKeyUsage; KeyAttrInfo.IntendedKeyUsage.cbData = 1; KeyAttrInfo.IntendedKeyUsage.cUnusedBits = 1;
{ SYSTEMTIME SystemTime = TestTime;
SystemTime.wMilliseconds = 123; MySystemTimeToFileTime(&SystemTime, &KeyValidity.NotBefore); SystemTime.wYear += 2; SystemTime.wMilliseconds = 456;
MySystemTimeToFileTime(&SystemTime, &KeyValidity.NotAfter); } KeyAttrInfo.pPrivateKeyUsagePeriod = &KeyValidity;
if (!AllocAndEncodeObject( X509_KEY_ATTRIBUTES, &KeyAttrInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateKeyUsageRestriction( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CERT_KEY_USAGE_RESTRICTION_INFO KeyUsageInfo; BYTE bRestrictedKeyUsage;
LPSTR rgpszCertPolicyElementId[4] = { "1.2.333.1", "1.2.333.22", "1.2.333.333", "1.2.333.4444" }; CERT_POLICY_ID rgCertPolicyId[3] = { 0, NULL, 1, rgpszCertPolicyElementId, 4, rgpszCertPolicyElementId };
LPSTR rgpszSpcCertPolicyElementId[2] = { SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID, SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID }; CERT_POLICY_ID rgSpcCertPolicyId[2] = { 1, &rgpszSpcCertPolicyElementId[0], 1, &rgpszSpcCertPolicyElementId[1] };
memset(&KeyUsageInfo, 0, sizeof(KeyUsageInfo));
if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) bRestrictedKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE; else bRestrictedKeyUsage = CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE; if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) bRestrictedKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
KeyUsageInfo.RestrictedKeyUsage.pbData = &bRestrictedKeyUsage; KeyUsageInfo.RestrictedKeyUsage.cbData = 1; KeyUsageInfo.RestrictedKeyUsage.cUnusedBits = 1;
if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) { KeyUsageInfo.cCertPolicyId = 2; KeyUsageInfo.rgCertPolicyId = rgSpcCertPolicyId; } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) { KeyUsageInfo.cCertPolicyId = 1; KeyUsageInfo.rgCertPolicyId = &rgSpcCertPolicyId[1]; } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) { KeyUsageInfo.cCertPolicyId = 1; KeyUsageInfo.rgCertPolicyId = &rgSpcCertPolicyId[0]; } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { KeyUsageInfo.cCertPolicyId = 3; KeyUsageInfo.rgCertPolicyId = rgCertPolicyId; }
if (!AllocAndEncodeObject( X509_KEY_USAGE_RESTRICTION, &KeyUsageInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateBasicConstraints( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; BYTE *pbSubtreesEncoded = NULL; DWORD cbSubtreesEncoded; CERT_NAME_BLOB rgSubtreesConstraint[2];
CERT_BASIC_CONSTRAINTS_INFO BasicConstraintsInfo; BYTE bSubjectType;
memset(&BasicConstraintsInfo, 0, sizeof(BasicConstraintsInfo));
if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) { bSubjectType = CERT_CA_SUBJECT_FLAG; BasicConstraintsInfo.fPathLenConstraint = TRUE; BasicConstraintsInfo.dwPathLenConstraint = dwCert + 1; } else bSubjectType = CERT_END_ENTITY_SUBJECT_FLAG; BasicConstraintsInfo.SubjectType.pbData = &bSubjectType; BasicConstraintsInfo.SubjectType.cbData = 1; BasicConstraintsInfo.SubjectType.cUnusedBits = 6;
if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name;
CreateNameInfo(dwCert, &Name, rgRDN, rgAttr); cbSubtreesEncoded = 0;
if (!AllocAndEncodeObject( X509_NAME, &Name, &pbSubtreesEncoded, &cbSubtreesEncoded )) goto ErrorReturn;
BasicConstraintsInfo.cSubtreesConstraint = 2; BasicConstraintsInfo.rgSubtreesConstraint = rgSubtreesConstraint; rgSubtreesConstraint[0].pbData = pbSubtreesEncoded; rgSubtreesConstraint[0].cbData = cbSubtreesEncoded; rgSubtreesConstraint[1].pbData = pbSubtreesEncoded; rgSubtreesConstraint[1].cbData = cbSubtreesEncoded; }
if (!AllocAndEncodeObject( X509_BASIC_CONSTRAINTS, &BasicConstraintsInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: if (pbSubtreesEncoded) TestFree(pbSubtreesEncoded); *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateKeyUsage( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CRYPT_BIT_BLOB KeyUsageInfo; BYTE bKeyUsage;
memset(&KeyUsageInfo, 0, sizeof(KeyUsageInfo));
if (CertPara[dwCert].dwFlags & XCHG_PARA_FLAG) bKeyUsage = CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE; else bKeyUsage = CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_NON_REPUDIATION_KEY_USAGE; if (0 == strcmp(CertPara[dwCert].pszName, "InvalidKeyUsageCA")) // No cert signing usage for this cert
; else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) bKeyUsage |= CERT_KEY_CERT_SIGN_KEY_USAGE;
KeyUsageInfo.pbData = &bKeyUsage; KeyUsageInfo.cbData = 1; KeyUsageInfo.cUnusedBits = 1;
if (!AllocAndEncodeObject( X509_KEY_USAGE, &KeyUsageInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateBasicConstraints2( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
CERT_BASIC_CONSTRAINTS2_INFO BasicConstraints2Info;
memset(&BasicConstraints2Info, 0, sizeof(BasicConstraints2Info));
if (dwCert == POLICY_ROOT || dwCert == ROLLOVER_CROSS_CERT) { BasicConstraints2Info.fCA = TRUE; BasicConstraints2Info.fPathLenConstraint = TRUE; BasicConstraints2Info.dwPathLenConstraint = 1; } else if (dwCert == POLICY_CA) { BasicConstraints2Info.fCA = TRUE; BasicConstraints2Info.fPathLenConstraint = TRUE; BasicConstraints2Info.dwPathLenConstraint = 0; } else if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) { BasicConstraints2Info.fCA = TRUE; BasicConstraints2Info.fPathLenConstraint = TRUE; if (0 == strcmp(CertPara[dwCert].pszName, "TestRoot")) BasicConstraints2Info.dwPathLenConstraint = 2; else BasicConstraints2Info.dwPathLenConstraint = dwCert + 1; } else BasicConstraints2Info.fCA = FALSE;
if (!AllocAndEncodeObject( X509_BASIC_CONSTRAINTS2, &BasicConstraints2Info, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreatePolicies( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BYTE rgbQualifier2[] = {5, 0}; // NULL
BYTE rgbQualifier4[] = {4, 8, 1,2,3,4,5,6,7,8}; // Octet String
CERT_POLICY_QUALIFIER_INFO rgQualifierInfo[4] = { "1.2.1", 0, NULL, "1.2.2", sizeof(rgbQualifier2), rgbQualifier2, "1.2.3", 0, NULL, "1.2.4", sizeof(rgbQualifier4), rgbQualifier4 };
// Root has the following policies:
// 1.1.1
// 1.1.55555
// 1.1.22
// 1.1.333
// 1.1.4444
CERT_POLICY_INFO rgRootPolicyInfo[] = { "1.1.1", 0, NULL, "1.1.55555", 0, NULL, "1.1.22", 2, rgQualifierInfo, "1.1.333", 2, &rgQualifierInfo[2], "1.1.333", 0, NULL, // duplicate, should be removed
"1.1.4444", 1, rgQualifierInfo, "1.1.4444", 0, NULL, // duplicate
"1.1.1", 0, NULL, // duplicate
"1.1.1", 0, NULL, // duplicate
};
// After mapping, the CA has the following policies:
// 1.1.1
// 1.1.22
// 1.1.333
// 1.1.4444
CERT_POLICY_INFO rgCaPolicyInfo[] = { "1.2.22.1", 0, NULL, // 1.1.22
"1.2.22.2", 0, NULL, // 1.1.22
"1.2.22.3", 0, NULL, // 1.1.22
"1.2.333.1", 0, NULL, // 1.1.333
"1.2.333.2", 0, NULL, // 1.1.333
"1.2.4444", 0, NULL, // 1.1.4444
"1.1.4444", 0, NULL, // 1.1.4444
"1.1.1", 0, NULL, // 1.1.1
"1.2.333.3", 0, NULL, // 1.1.333
"1.2.55555", 0, NULL, // no mapping
};
// After mapping, the cert has the following policies:
// 1.1.1
// 1.1.22
CERT_POLICY_INFO rgPolicyInfo[] = { "1.1.55555", 0, NULL, // no mapping via ca
"1.3.22.2.1", 0, NULL, // 1.2.22.2 -> 1.1.22
"1.3.1.1", 0, NULL, // 1.1.1
"1.2.55555", 0, NULL, // no mapping via root
};
// After mapping, the cert has the following policies:
// 1.1.1
// 1.1.22
// 1.1.4444
CERT_POLICY_INFO rgAllExtPolicyInfo[] = { "1.3.1.2", 0, NULL, // 1.1.1
"1.3.22.2.2", 0, NULL, // 1.2.22.2 -> 1.1.22
"1.1.55555", 0, NULL, // no mapping via ca
"1.2.55555", 0, NULL, // not mapping via root
"1.1.4444", 0, NULL, // 1.1.4444
};
CERT_POLICY_INFO rgSpcPolicyInfo[2] = { SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID, 0, NULL, SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID, 0, NULL };
CERT_POLICY_INFO rgDssCAPolicyInfo[] = { szOID_ANY_CERT_POLICY, 0, NULL, };
CERT_POLICY_INFO rgDssEndPolicyInfo[] = { "1.1.4444", 0, NULL, "1.1.55555", 0, NULL, };
CERT_POLICIES_INFO PoliciesInfo; memset(&PoliciesInfo, 0, sizeof(PoliciesInfo));
if (0 == strcmp(CertPara[dwCert].pszName, "DssCA")) { PoliciesInfo.cPolicyInfo = sizeof(rgDssCAPolicyInfo) / sizeof(rgDssCAPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgDssCAPolicyInfo; } else if (0 == strcmp(CertPara[dwCert].pszName, "DssEnd")) { PoliciesInfo.cPolicyInfo = sizeof(rgDssEndPolicyInfo) / sizeof(rgDssEndPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgDssEndPolicyInfo; } else if (POLICY_ROOT == dwCert) { PoliciesInfo.cPolicyInfo = sizeof(rgRootPolicyInfo) / sizeof(rgRootPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgRootPolicyInfo; } else if (POLICY_CA == dwCert) { PoliciesInfo.cPolicyInfo = sizeof(rgCaPolicyInfo) / sizeof(rgCaPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgCaPolicyInfo; } else if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) { PoliciesInfo.cPolicyInfo = 2; PoliciesInfo.rgPolicyInfo = rgSpcPolicyInfo; } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) { PoliciesInfo.cPolicyInfo = 1; PoliciesInfo.rgPolicyInfo = &rgSpcPolicyInfo[1]; } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) { PoliciesInfo.cPolicyInfo = 1; PoliciesInfo.rgPolicyInfo = &rgSpcPolicyInfo[0]; } else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { PoliciesInfo.cPolicyInfo = sizeof(rgAllExtPolicyInfo) / sizeof(rgAllExtPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgAllExtPolicyInfo; } else { PoliciesInfo.cPolicyInfo = sizeof(rgPolicyInfo) / sizeof(rgPolicyInfo[0]); PoliciesInfo.rgPolicyInfo = rgPolicyInfo; }
return AllocAndEncodeObject( X509_CERT_POLICIES, &PoliciesInfo, ppbEncoded, pcbEncoded); }
static BOOL CreateSMIMECapabilities( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BYTE rgb128BitLen[] = {2, 2, 0, 128}; // Integer
BYTE rgb40BitLen[] = {2, 1, 40}; // Integer
CRYPT_SMIME_CAPABILITY rgCapability[4] = { szOID_RSA_DES_EDE3_CBC, 0, NULL, szOID_RSA_RC2CBC, sizeof(rgb128BitLen), rgb128BitLen, szOID_RSA_RC2CBC, sizeof(rgb40BitLen), rgb40BitLen, szOID_RSA_preferSignedData, 0, NULL };
CRYPT_SMIME_CAPABILITIES Capabilities = { sizeof(rgCapability)/sizeof(rgCapability[0]), rgCapability };
return AllocAndEncodeObject( PKCS_SMIME_CAPABILITIES, &Capabilities, ppbEncoded, pcbEncoded); }
static BOOL CreateAltName( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded; CERT_ALT_NAME_INFO AltNameInfo; #define ALT_NAME_ENTRY_CNT 15
CERT_ALT_NAME_ENTRY rgAltNameEntry[ALT_NAME_ENTRY_CNT]; DWORD i;
BYTE *pbNameEncoded = NULL; DWORD cbNameEncoded;
CERT_OTHER_NAME UPNOtherName; BYTE *pbUPNNameEncoded = NULL; DWORD cbUPNNameEncoded;
CERT_OTHER_NAME StringOtherName; BYTE *pbStringOtherNameEncoded = NULL; DWORD cbStringOtherNameEncoded; DWORD dwStringOtherNameValueType = CERT_RDN_UTF8_STRING;
LPWSTR pwszEmail = NULL; LPWSTR pwszUrl = NULL; LPWSTR pwszUPN = NULL; LPWSTR pwszStringOtherName = NULL; LPWSTR pwszDns = NULL;
BYTE rgbOctetOtherName[] = {0x04, 0x02, 0x11, 0x22}; CERT_OTHER_NAME OctetOtherName; PCERT_OTHER_NAME pOctetOtherName = NULL;
LPSTR pszRegisteredID = NULL;
BYTE rgbDefaultIPAddress[] = {1,1,0,0}; BYTE rgbAllExtIPAddress[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17}; BYTE rgbExcludedIPAddress[] = {2,2,3,3}; BYTE rgbNotPermittedIPAddress[] = {3,3,3,3}; BYTE *pbIPAddress = NULL; DWORD cbIPAddress = 0;
if (CertPara[dwCert].dwFlags & (NO_NAME_PARA_FLAG | ALT_DIR_NAME_PARA_FLAG)) { pwszEmail = L"[email protected]"; }
if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { pwszEmail = L" [email protected] "; pwszUrl = L" http://www.AllExt.url.com:388/more url stuff"; pwszDns = L"DNS name"; pwszUPN = L"[email protected]"; pwszStringOtherName = L"AllExtString@OtherName"; dwStringOtherNameValueType = CERT_RDN_TELETEX_STRING; pbIPAddress = rgbAllExtIPAddress; cbIPAddress = sizeof(rgbAllExtIPAddress); } else if (0 == strcmp(CertPara[dwCert].pszName, "Excluded")) { pwszEmail = L" [email protected] "; pwszUrl = L" http://Excluded.url.com/more url stuff"; pwszDns = L"www.excluded.dns.com"; pwszUPN = L"[email protected]"; pwszStringOtherName = L"ExcludedString@OtherName"; dwStringOtherNameValueType = CERT_RDN_IA5_STRING; pbIPAddress = rgbExcludedIPAddress; cbIPAddress = sizeof(rgbExcludedIPAddress); } else if (0 == strcmp(CertPara[dwCert].pszName, "NotPermitted")) { pwszEmail = L"[email protected]"; pwszUrl = L"http://www.url.not/more url stuff"; pwszDns = L"www.excluded.dns.not"; pwszUPN = L"[email protected]"; pwszStringOtherName = L"String@OtherNameNot"; dwStringOtherNameValueType = CERT_RDN_GENERAL_STRING; pbIPAddress = rgbNotPermittedIPAddress; cbIPAddress = sizeof(rgbNotPermittedIPAddress);
OctetOtherName.pszObjId = OCTET_OTHER_NAME_OID; OctetOtherName.Value.pbData = rgbOctetOtherName; OctetOtherName.Value.cbData = sizeof(rgbOctetOtherName); pOctetOtherName = &OctetOtherName;
pszRegisteredID = "1.2.3.4.5.6.7"; } else { pwszUPN = L" [email protected] "; pwszStringOtherName = L" DefaultString@OtherName "; dwStringOtherNameValueType = CERT_RDN_UTF8_STRING; pbIPAddress = rgbDefaultIPAddress; cbIPAddress = sizeof(rgbDefaultIPAddress); }
if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCEnd")) { OctetOtherName.pszObjId = OCTET_OTHER_NAME_OID; OctetOtherName.Value.pbData = rgbOctetOtherName; OctetOtherName.Value.cbData = sizeof(rgbOctetOtherName); pOctetOtherName = &OctetOtherName; }
i = 0; if (pwszEmail) { rgAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgAltNameEntry[0].pwszRfc822Name = pwszEmail; i++; }
if (pwszUPN) { CERT_NAME_VALUE UPNNameValue;
UPNNameValue.dwValueType = CERT_RDN_UTF8_STRING; UPNNameValue.Value.pbData = (BYTE *) pwszUPN; UPNNameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &UPNNameValue, &pbUPNNameEncoded, &cbUPNNameEncoded)) goto ErrorReturn;
UPNOtherName.pszObjId = szOID_NT_PRINCIPAL_NAME; UPNOtherName.Value.pbData = pbUPNNameEncoded; UPNOtherName.Value.cbData = cbUPNNameEncoded;
rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgAltNameEntry[i].pOtherName = &UPNOtherName; i++; }
if (pwszStringOtherName) { CERT_NAME_VALUE OtherNameValue;
OtherNameValue.dwValueType = dwStringOtherNameValueType; OtherNameValue.Value.pbData = (BYTE *) pwszStringOtherName; OtherNameValue.Value.cbData = 0; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &OtherNameValue, &pbStringOtherNameEncoded, &cbStringOtherNameEncoded)) goto ErrorReturn;
StringOtherName.pszObjId = STRING_OTHER_NAME_OID; StringOtherName.Value.pbData = pbStringOtherNameEncoded; StringOtherName.Value.cbData = cbStringOtherNameEncoded;
rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgAltNameEntry[i].pOtherName = &StringOtherName; i++; }
if (pwszUrl) { rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_URL; rgAltNameEntry[i].pwszURL = pwszUrl; i++; }
if (pwszDns) { rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgAltNameEntry[i].pwszDNSName = pwszDns; i++; }
if (pszRegisteredID) { rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID; rgAltNameEntry[i].pszRegisteredID = pszRegisteredID; i++; }
if (pbIPAddress && cbIPAddress) { rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgAltNameEntry[i].IPAddress.pbData = pbIPAddress; rgAltNameEntry[i].IPAddress.cbData = cbIPAddress; i++; }
if (pOctetOtherName) { rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgAltNameEntry[i].pOtherName = pOctetOtherName; i++; }
if (CertPara[dwCert].dwFlags & ALT_DIR_NAME_PARA_FLAG) { CERT_NAME_INFO NameInfo; CERT_RDN rgRDN[1]; CERT_RDN_ATTR rgAttr[1];
NameInfo.cRDN = 1; NameInfo.rgRDN = rgRDN;
rgRDN[0].cRDNAttr = 1; rgRDN[0].rgRDNAttr = rgAttr;
rgAttr[0].pszObjId = szOID_ORGANIZATIONAL_UNIT_NAME; rgAttr[0].dwValueType = CERT_RDN_PRINTABLE_STRING; rgAttr[0].Value.pbData = (BYTE *) CertPara[dwCert].pszName; rgAttr[0].Value.cbData = strlen(CertPara[dwCert].pszName);
if (!AllocAndEncodeObject( X509_NAME, &NameInfo, &pbNameEncoded, &cbNameEncoded)) goto ErrorReturn;
rgAltNameEntry[i].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgAltNameEntry[i].DirectoryName.pbData = pbNameEncoded; rgAltNameEntry[i].DirectoryName.cbData = cbNameEncoded; i++; }
AltNameInfo.cAltEntry = i; AltNameInfo.rgAltEntry = rgAltNameEntry;
if (!AllocAndEncodeObject( X509_ALTERNATE_NAME, &AltNameInfo, &pbEncoded, &cbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: TestFree(pbNameEncoded); TestFree(pbUPNNameEncoded); TestFree(pbStringOtherNameEncoded); *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSETAccountAlias( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
BOOL bInfo;
if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) bInfo = TRUE; else bInfo = FALSE;
if (!AllocAndEncodeObject( X509_SET_ACCOUNT_ALIAS, &bInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSETHashedRootKey( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
BYTE i; BYTE rgbInfo[SET_HASHED_ROOT_LEN];
for (i = 0; i < SET_HASHED_ROOT_LEN; i++) rgbInfo[i] = i;
if (!AllocAndEncodeObject( X509_SET_HASHED_ROOT_KEY, rgbInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSETCertificateType( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
CRYPT_BIT_BLOB Info; BYTE rgbType[2] = {0,0};
if (dwCert < 8) rgbType[0] = 1 << (dwCert % 8); else rgbType[1] = 0x40 << (dwCert % 2); Info.pbData = rgbType; Info.cbData = 2; Info.cUnusedBits = 6;
if (!AllocAndEncodeObject( X509_SET_CERTIFICATE_TYPE, &Info, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSETMerchantData( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
SET_MERCHANT_DATA_INFO Info;
memset(&Info, 0, sizeof(Info)); if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { Info.pszMerID = "ID"; Info.pszMerAcquirerBIN = "0123456"; Info.pszMerTermID = "TermID"; Info.pszMerName = "Name"; Info.pszMerCity = "City"; Info.pszMerStateProvince = "StateProvince"; Info.pszMerPostalCode = "PostalCode"; Info.pszMerCountry = "Country/Region"; Info.pszMerPhone = "Phone"; Info.fMerPhoneRelease = TRUE; Info.fMerAuthFlag = TRUE; } else { Info.pszMerID = ""; Info.pszMerAcquirerBIN = ""; Info.pszMerTermID = ""; Info.pszMerName = ""; Info.pszMerCity = ""; Info.pszMerStateProvince = ""; Info.pszMerPostalCode = ""; Info.pszMerCountry = ""; Info.pszMerPhone = ""; Info.fMerPhoneRelease = FALSE; Info.fMerAuthFlag = FALSE; }
if (!AllocAndEncodeObject( X509_SET_MERCHANT_DATA, &Info, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSpcSpAgency( DWORD dwCert, DWORD dwLevel, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
SPC_LINK UrlLink; SPC_LINK MonikerLink; #define MONIKER_DATA "Moniker Serialized Data"
SPC_LINK FileLink; SPC_IMAGE Image; SPC_SP_AGENCY_INFO AgencyInfo;
#define BIT_MAP "Bit Map"
#define META_FILE "Metafile"
#define ENHANCED_META_FILE "Enhanced Metafile"
#define GIF_FILE "Gif File"
int i;
UrlLink.dwLinkChoice = SPC_URL_LINK_CHOICE; UrlLink.pwszUrl = L"http://microsoft.com";
MonikerLink.dwLinkChoice = SPC_MONIKER_LINK_CHOICE; for (i = 0; i < sizeof(MonikerLink.Moniker.ClassId); i++) MonikerLink.Moniker.ClassId[i] = (BYTE) (i + 1); MonikerLink.Moniker.SerializedData.cbData = strlen(MONIKER_DATA); MonikerLink.Moniker.SerializedData.pbData = (BYTE *) MONIKER_DATA;
FileLink.dwLinkChoice = SPC_FILE_LINK_CHOICE; FileLink.pwszFile = L"Unicode File Link";
memset(&Image, 0, sizeof(Image)); memset(&AgencyInfo, 0, sizeof(AgencyInfo));
AgencyInfo.pLogoImage = &Image;
if (dwLevel >= 1) { AgencyInfo.pPolicyInformation = &UrlLink; AgencyInfo.pwszPolicyDisplayText = L"MICROSOFT PRODUCTS POLICY"; AgencyInfo.pLogoImage = NULL; }
if (dwLevel >= 2) { AgencyInfo.pPolicyInformation = &UrlLink; AgencyInfo.pwszPolicyDisplayText = L"Unicode String"; Image.Bitmap.cbData = strlen(BIT_MAP); Image.Bitmap.pbData = (BYTE *) BIT_MAP; }
if (dwLevel >= 3) { AgencyInfo.pwszPolicyDisplayText = L"Policy Display Unicode String"; AgencyInfo.pLogoLink = &MonikerLink; Image.pImageLink = &FileLink; Image.Metafile.cbData = strlen(META_FILE); Image.Metafile.pbData = (BYTE *) META_FILE; Image.EnhancedMetafile.cbData = strlen(ENHANCED_META_FILE); Image.EnhancedMetafile.pbData = (BYTE *) ENHANCED_META_FILE; Image.GifFile.cbData = strlen(GIF_FILE); Image.GifFile.pbData = (BYTE *) GIF_FILE; }
if (!AllocAndEncodeObject( SPC_SP_AGENCY_INFO_STRUCT, &AgencyInfo, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateSpcCommonName( DWORD dwCert, OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { BOOL fResult; BYTE *pbEncoded = NULL; DWORD cbEncoded;
#define SPC_AGENCY_NAME L"Microsoft Code Signing Agency"
#define SPC_COM_NAME "Microsoft Software Products"
CERT_NAME_VALUE NameValue;
if (CertPara[dwCert].dwFlags & SPC_AGENCY_PARA_FLAG) { NameValue.dwValueType = CERT_RDN_UNICODE_STRING; NameValue.Value.pbData = (BYTE *) SPC_AGENCY_NAME; NameValue.Value.cbData = wcslen(SPC_AGENCY_NAME) * sizeof(WCHAR); } else if (CertPara[dwCert].dwFlags & SPC_COM_PARA_FLAG) { NameValue.dwValueType = CERT_RDN_IA5_STRING; NameValue.Value.pbData = (BYTE *) SPC_COM_NAME; NameValue.Value.cbData = strlen(SPC_COM_NAME); } else { NameValue.dwValueType = CERT_RDN_PRINTABLE_STRING; NameValue.Value.pbData = (BYTE *) CertPara[dwCert].pszName; NameValue.Value.cbData = strlen(CertPara[dwCert].pszName); }
if (!AllocAndEncodeObject( X509_NAME_VALUE, &NameValue, &pbEncoded, &cbEncoded )) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbEncoded) { TestFree(pbEncoded); pbEncoded = NULL; } cbEncoded = 0; fResult = FALSE; CommonReturn: *ppbEncoded = pbEncoded; *pcbEncoded = cbEncoded; return fResult; }
static BOOL CreateCRLReason( OUT BYTE **ppbEncoded, IN OUT DWORD *pcbEncoded ) { static int iReason = -1;
iReason += 1;
iReason = iReason % CRL_REASON_CERTIFICATE_HOLD; return AllocAndEncodeObject( X509_ENUMERATED, (const void *) &iReason, ppbEncoded, pcbEncoded ); }
static BOOL EncodeCert(DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded) { BOOL fResult; BYTE *pbSubjectEncoded = NULL; DWORD cbSubjectEncoded; BYTE *pbIssuerEncoded = NULL; DWORD cbIssuerEncoded; PCERT_PUBLIC_KEY_INFO pPubKeyInfo = NULL; BYTE *pbCertEncoded = NULL; DWORD cbCertEncoded;
BYTE *pbKeyIdEncoded = NULL; DWORD cbKeyIdEncoded; BYTE *pbKeyId2Encoded = NULL; DWORD cbKeyId2Encoded; BYTE *pbSubjectKeyIdEncoded = NULL; DWORD cbSubjectKeyIdEncoded; BYTE *pbAuthorityInfoAccessEncoded = NULL; DWORD cbAuthorityInfoAccessEncoded; BYTE *pbCrlDistPointsEncoded = NULL; DWORD cbCrlDistPointsEncoded; BYTE *pbKeyAttrEncoded = NULL; DWORD cbKeyAttrEncoded; BYTE *pbAltNameEncoded = NULL; DWORD cbAltNameEncoded; BYTE *pbIssuerAltNameEncoded = NULL; DWORD cbIssuerAltNameEncoded; BYTE *pbKeyUsageRestrictionEncoded = NULL; DWORD cbKeyUsageRestrictionEncoded; BYTE *pbBasicConstraintsEncoded = NULL; DWORD cbBasicConstraintsEncoded; BYTE *pbKeyUsageEncoded = NULL; DWORD cbKeyUsageEncoded; BYTE *pbBasicConstraints2Encoded = NULL; DWORD cbBasicConstraints2Encoded; BYTE *pbPoliciesEncoded = NULL; DWORD cbPoliciesEncoded;
BYTE *pbSETAccountAliasEncoded = NULL; DWORD cbSETAccountAliasEncoded; BYTE *pbSETHashedRootKeyEncoded = NULL; DWORD cbSETHashedRootKeyEncoded; BYTE *pbSETCertificateTypeEncoded = NULL; DWORD cbSETCertificateTypeEncoded; BYTE *pbSETMerchantDataEncoded = NULL; DWORD cbSETMerchantDataEncoded;
BYTE *pbSpcSpAgencyEncoded0 = NULL; DWORD cbSpcSpAgencyEncoded0; BYTE *pbSpcSpAgencyEncoded1 = NULL; DWORD cbSpcSpAgencyEncoded1; BYTE *pbSpcSpAgencyEncoded2 = NULL; DWORD cbSpcSpAgencyEncoded2; BYTE *pbSpcCommonNameEncoded = NULL; DWORD cbSpcCommonNameEncoded;
BYTE *pbNetscapeCertType = NULL; DWORD cbNetscapeCertType; BYTE *pbNetscapeComment = NULL; DWORD cbNetscapeComment; BYTE *pbNetscapeBaseUrl = NULL; DWORD cbNetscapeBaseUrl; BYTE *pbNetscapeRevUrl = NULL; DWORD cbNetscapeRevUrl;
BYTE *pbEnhancedKeyUsageEncoded = NULL; DWORD cbEnhancedKeyUsageEncoded;
BYTE *pbSMIMECapabilitiesEncoded = NULL; DWORD cbSMIMECapabilitiesEncoded;
BYTE *pbIDPEncoded = NULL; DWORD cbIDPEncoded; BYTE *pbNameConstraintsEncoded = NULL; DWORD cbNameConstraintsEncoded;
BYTE *pbPolicyMappingsEncoded = NULL; DWORD cbPolicyMappingsEncoded; BYTE *pbPolicyConstraintsEncoded = NULL; DWORD cbPolicyConstraintsEncoded; BYTE *pbCrossCertDistPointsEncoded = NULL; DWORD cbCrossCertDistPointsEncoded;
FILETIME SerialNumber;
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name; CERT_INFO Cert;
DWORD dwIssuer = CertPara[dwCert].dwIssuer;
DWORD dwCrlDistFlags;
#define CERT_EXTENSION_CNT 30
CERT_EXTENSION rgExt[CERT_EXTENSION_CNT];
// SUBJECT
CreateNameInfo(dwCert, &Name, rgRDN, rgAttr); if (!AllocAndEncodeObject( X509_NAME, &Name, &pbSubjectEncoded, &cbSubjectEncoded )) goto ErrorReturn;
// ISSUER
CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr); if (!AllocAndEncodeObject( X509_NAME, &Name, &pbIssuerEncoded, &cbIssuerEncoded )) goto ErrorReturn;
// PUBLIC KEY
if (!GetPublicKey(dwCert, &pPubKeyInfo)) goto ErrorReturn;
// CERT
memset(&Cert, 0, sizeof(Cert)); Cert.dwVersion = CERT_V3; { SYSTEMTIME SystemTime = TestTime; if (CertPara[dwCert].dwFlags & DUPLICATE_PARA_FLAG) // Use same serial number as previous certificate
SystemTime.wMilliseconds += (WORD) (dwCert - 1); else SystemTime.wMilliseconds += (WORD) dwCert; MySystemTimeToFileTime(&SystemTime, &SerialNumber); } Cert.SerialNumber.pbData = (BYTE *) &SerialNumber; Cert.SerialNumber.cbData = sizeof(SerialNumber); if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG) Cert.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID; else Cert.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID; Cert.Issuer.pbData = pbIssuerEncoded; Cert.Issuer.cbData = cbIssuerEncoded;
{ SYSTEMTIME SystemTime = TestTime;
if (CertPara[dwCert].dwFlags & TIME_INVALID_PARA_FLAG) { MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter); SystemTime.wYear--; MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore); } else if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) { SystemTime.wYear = 1920; MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore); SystemTime.wYear = 2070;
if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) SystemTime.wHour = 1; else SystemTime.wHour = 0; SystemTime.wMinute = 59 - (WORD) dwCert; SystemTime.wSecond = 0; MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter); } else if (0 == strcmp("ZeroNotAfter", CertPara[dwCert].pszName)) { MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore); // NotAfter has already been zeroed
} else { MySystemTimeToFileTime(&SystemTime, &Cert.NotBefore); SystemTime.wYear++; if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) SystemTime.wHour = 1; else SystemTime.wHour = 0; if (dwCert < 60) { SystemTime.wMinute = 59 - (WORD) dwCert; SystemTime.wSecond = 0; } else { SystemTime.wMinute = 0; SystemTime.wSecond = 0; } MySystemTimeToFileTime(&SystemTime, &Cert.NotAfter); } }
Cert.Subject.pbData = pbSubjectEncoded; Cert.Subject.cbData = cbSubjectEncoded; Cert.SubjectPublicKeyInfo = *pPubKeyInfo;
// Cert Extensions
if (!CreateAuthorityKeyId( dwIssuer, &pbKeyIdEncoded, &cbKeyIdEncoded)) goto ErrorReturn; if (!CreateAuthorityKeyId2( dwCert, dwIssuer, &pbKeyId2Encoded, &cbKeyId2Encoded)) goto ErrorReturn; if (!CreateAuthorityInfoAccess( dwCert, &pbAuthorityInfoAccessEncoded, &cbAuthorityInfoAccessEncoded)) goto ErrorReturn;
dwCrlDistFlags = 0; if (CertPara[dwCert].dwFlags & DELTA_CRL_PARA_FLAG) dwCrlDistFlags |= CRL_DIST_POINTS_DELTA_FLAG; if (0 == strcmp(CertPara[dwCert].pszName, "UnsupportedCDP")) dwCrlDistFlags |= CRL_DIST_POINTS_UNSUPPORTED_FLAG; if (!CreateCrlDistPoints( CertPara[dwCert].dwIssuer, dwCrlDistFlags, &pbCrlDistPointsEncoded, &cbCrlDistPointsEncoded)) goto ErrorReturn;
if (!CreateKeyAttributes( dwCert, &pbKeyAttrEncoded, &cbKeyAttrEncoded)) goto ErrorReturn; if (!CreateAltName( dwCert, &pbAltNameEncoded, &cbAltNameEncoded)) goto ErrorReturn; if (!CreateKeyUsageRestriction( dwCert, &pbKeyUsageRestrictionEncoded, &cbKeyUsageRestrictionEncoded)) goto ErrorReturn; if (!CreateBasicConstraints( dwCert, &pbBasicConstraintsEncoded, &cbBasicConstraintsEncoded)) goto ErrorReturn; if (!CreateKeyUsage( dwCert, &pbKeyUsageEncoded, &cbKeyUsageEncoded)) goto ErrorReturn; if (!CreateBasicConstraints2( dwCert, &pbBasicConstraints2Encoded, &cbBasicConstraints2Encoded)) goto ErrorReturn; if (!CreatePolicies( dwCert, &pbPoliciesEncoded, &cbPoliciesEncoded)) goto ErrorReturn;
if (CertPara[dwCert].dwFlags & SPC_AGENCY_INFO_PARA_FLAG) { if (!CreateSpcSpAgency( dwCert, 0, // dwLevel
&pbSpcSpAgencyEncoded0, &cbSpcSpAgencyEncoded0)) goto ErrorReturn; if (!CreateSpcSpAgency( dwCert, 2, // dwLevel
&pbSpcSpAgencyEncoded1, &cbSpcSpAgencyEncoded1)) goto ErrorReturn; if (!CreateSpcSpAgency( dwCert, 3, // dwLevel
&pbSpcSpAgencyEncoded2, &cbSpcSpAgencyEncoded2)) goto ErrorReturn; } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) { if (!CreateSpcSpAgency( dwCert, 1, // dwLevel
&pbSpcSpAgencyEncoded0, &cbSpcSpAgencyEncoded0)) goto ErrorReturn; if (!CreateSpcCommonName( dwCert, &pbSpcCommonNameEncoded, &cbSpcCommonNameEncoded)) goto ErrorReturn; } else { if (!CreateSETAccountAlias( dwCert, &pbSETAccountAliasEncoded, &cbSETAccountAliasEncoded)) goto ErrorReturn; if (!CreateSETHashedRootKey( dwCert, &pbSETHashedRootKeyEncoded, &cbSETHashedRootKeyEncoded)) goto ErrorReturn; if (!CreateSETCertificateType( dwCert, &pbSETCertificateTypeEncoded, &cbSETCertificateTypeEncoded)) goto ErrorReturn; if (!CreateSETMerchantData( dwCert, &pbSETMerchantDataEncoded, &cbSETMerchantDataEncoded)) goto ErrorReturn; }
rgExt[0].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER; rgExt[0].fCritical = FALSE; rgExt[0].Value.pbData = pbKeyIdEncoded; rgExt[0].Value.cbData = cbKeyIdEncoded; rgExt[1].pszObjId = szOID_KEY_ATTRIBUTES; rgExt[1].fCritical = FALSE; rgExt[1].Value.pbData = pbKeyAttrEncoded; rgExt[1].Value.cbData = cbKeyAttrEncoded; rgExt[2].pszObjId = szOID_BASIC_CONSTRAINTS; rgExt[2].fCritical = FALSE; rgExt[2].Value.pbData = pbBasicConstraintsEncoded; rgExt[2].Value.cbData = cbBasicConstraintsEncoded; rgExt[3].pszObjId = szOID_KEY_USAGE_RESTRICTION; rgExt[3].fCritical = FALSE; rgExt[3].Value.pbData = pbKeyUsageRestrictionEncoded; rgExt[3].Value.cbData = cbKeyUsageRestrictionEncoded; rgExt[4].pszObjId = szOID_KEY_USAGE; rgExt[4].fCritical = FALSE; rgExt[4].Value.pbData = pbKeyUsageEncoded; rgExt[4].Value.cbData = cbKeyUsageEncoded; rgExt[5].pszObjId = szOID_BASIC_CONSTRAINTS2; rgExt[5].fCritical = FALSE; rgExt[5].Value.pbData = pbBasicConstraints2Encoded; rgExt[5].Value.cbData = cbBasicConstraints2Encoded; rgExt[6].pszObjId = szOID_CERT_POLICIES; rgExt[6].fCritical = FALSE; rgExt[6].Value.pbData = pbPoliciesEncoded; rgExt[6].Value.cbData = cbPoliciesEncoded;
rgExt[7].pszObjId = szOID_SUBJECT_ALT_NAME; rgExt[7].fCritical = FALSE; if (0 == strcmp(CertPara[dwCert].pszName, "InvalidNCEnd_AV")) { static BYTE rgbExt[] = {5,0};
rgExt[7].Value.pbData = rgbExt; rgExt[7].Value.cbData = 0; // sizeof(rgbExt);
} else { rgExt[7].Value.pbData = pbAltNameEncoded; rgExt[7].Value.cbData = cbAltNameEncoded; }
if (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG) Cert.cExtension = 0; else if (CertPara[dwCert].dwFlags & VALID_PARA_FLAG) Cert.cExtension = 6; else if (CertPara[dwCert].dwFlags & SPC_AGENCY_INFO_PARA_FLAG) { rgExt[8].pszObjId = SPC_SP_AGENCY_INFO_OBJID; rgExt[8].fCritical = TRUE; rgExt[8].Value.pbData = pbSpcSpAgencyEncoded2; rgExt[8].Value.cbData = cbSpcSpAgencyEncoded2; rgExt[9].pszObjId = SPC_SP_AGENCY_INFO_OBJID; rgExt[9].fCritical = FALSE; rgExt[9].Value.pbData = pbSpcSpAgencyEncoded0; rgExt[9].Value.cbData = cbSpcSpAgencyEncoded0; rgExt[10].pszObjId = SPC_SP_AGENCY_INFO_OBJID; rgExt[10].fCritical = FALSE; rgExt[10].Value.pbData = pbSpcSpAgencyEncoded1; rgExt[10].Value.cbData = cbSpcSpAgencyEncoded1; Cert.cExtension = 11; } else if (CertPara[dwCert].dwFlags & SPC_EXT_PARA_FLAG) { rgExt[8].pszObjId = SPC_SP_AGENCY_INFO_OBJID; rgExt[8].fCritical = FALSE; rgExt[8].Value.pbData = pbSpcSpAgencyEncoded0; rgExt[8].Value.cbData = cbSpcSpAgencyEncoded0; if (CertPara[dwCert].dwFlags & (SPC_AGENCY_PARA_FLAG | SPC_COM_PARA_FLAG)) { rgExt[9].pszObjId = SPC_COMMON_NAME_OBJID; rgExt[9].fCritical = FALSE; rgExt[9].Value.pbData = pbSpcCommonNameEncoded; rgExt[9].Value.cbData = cbSpcCommonNameEncoded; Cert.cExtension = 10; } else Cert.cExtension = 9; } else if (CertPara[dwCert].dwFlags & NETSCAPE_PARA_FLAG) { BYTE bCertType; CRYPT_BIT_BLOB BitBlob; CERT_NAME_VALUE Comment; CERT_NAME_VALUE RevUrl; CERT_NAME_VALUE BaseUrl;
BitBlob.pbData = &bCertType; BitBlob.cbData = 1; BitBlob.cUnusedBits = 2; if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) bCertType = NETSCAPE_SSL_CA_CERT_TYPE; else bCertType = NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
if (!AllocAndEncodeObject( X509_BITS, &BitBlob, &pbNetscapeCertType, &cbNetscapeCertType)) goto ErrorReturn; rgExt[8].pszObjId = szOID_NETSCAPE_CERT_TYPE; rgExt[8].fCritical = FALSE; rgExt[8].Value.pbData = pbNetscapeCertType; rgExt[8].Value.cbData = cbNetscapeCertType;
memset(&Comment, 0, sizeof(Comment)); Comment.dwValueType = CERT_RDN_IA5_STRING; Comment.Value.pbData = (BYTE *) L"This is an IA5 Netscape Comment"; if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &Comment, &pbNetscapeComment, &cbNetscapeComment)) goto ErrorReturn; rgExt[9].pszObjId = szOID_NETSCAPE_COMMENT; rgExt[9].fCritical = FALSE; rgExt[9].Value.pbData = pbNetscapeComment; rgExt[9].Value.cbData = cbNetscapeComment;
memset(&BaseUrl, 0, sizeof(BaseUrl)); BaseUrl.dwValueType = CERT_RDN_IA5_STRING; #if 0
BaseUrl.Value.pbData = (BYTE *) L"http://status.verisign.com/"; #else
BaseUrl.Value.pbData = (BYTE *) L"https://www.netscape.com/"; #endif
if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &BaseUrl, &pbNetscapeBaseUrl, &cbNetscapeBaseUrl)) goto ErrorReturn; rgExt[10].pszObjId = szOID_NETSCAPE_BASE_URL; rgExt[10].fCritical = FALSE; rgExt[10].Value.pbData = pbNetscapeBaseUrl; rgExt[10].Value.cbData = cbNetscapeBaseUrl;
memset(&RevUrl, 0, sizeof(RevUrl)); RevUrl.dwValueType = CERT_RDN_IA5_STRING; #if 0
RevUrl.Value.pbData = (BYTE *) L"status/check/ver/1/ID/"; #else
RevUrl.Value.pbData = (BYTE *) L"cgi-bin/check-rev.cgi?"; #endif
if (!AllocAndEncodeObject( X509_UNICODE_ANY_STRING, &RevUrl, &pbNetscapeRevUrl, &cbNetscapeRevUrl)) goto ErrorReturn; if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) rgExt[11].pszObjId = szOID_NETSCAPE_CA_REVOCATION_URL; else rgExt[11].pszObjId = szOID_NETSCAPE_REVOCATION_URL; rgExt[11].fCritical = FALSE; rgExt[11].Value.pbData = pbNetscapeRevUrl; rgExt[11].Value.cbData = cbNetscapeRevUrl;
Cert.cExtension = 12; } else if (CertPara[dwCert].dwFlags & SET_PARA_FLAG) { rgExt[8].pszObjId = szOID_SET_ACCOUNT_ALIAS; rgExt[8].fCritical = FALSE; rgExt[8].Value.pbData = pbSETAccountAliasEncoded; rgExt[8].Value.cbData = cbSETAccountAliasEncoded; rgExt[9].pszObjId = szOID_SET_HASHED_ROOT_KEY; rgExt[9].fCritical = FALSE; rgExt[9].Value.pbData = pbSETHashedRootKeyEncoded; rgExt[9].Value.cbData = cbSETHashedRootKeyEncoded; rgExt[10].pszObjId = szOID_SET_CERTIFICATE_TYPE; rgExt[10].fCritical = FALSE; rgExt[10].Value.pbData = pbSETCertificateTypeEncoded; rgExt[10].Value.cbData = cbSETCertificateTypeEncoded; rgExt[11].pszObjId = szOID_SET_MERCHANT_DATA; rgExt[11].fCritical = FALSE; rgExt[11].Value.pbData = pbSETMerchantDataEncoded; rgExt[11].Value.cbData = cbSETMerchantDataEncoded; Cert.cExtension = 12; } else { Cert.cExtension = 8; }
if ((CertPara[dwCert].dwFlags & DELTA_CRL_PARA_FLAG) || (0 == (CertPara[dwCert].dwFlags & (NO_EXT_PARA_FLAG | VALID_PARA_FLAG)))) { DWORD cExt = Cert.cExtension;
if (0 == (CertPara[CertPara[dwCert].dwIssuer].dwFlags & NO_CRL_EXT_PARA_FLAG)) { if (0 != strncmp(CertPara[dwCert].pszName, "NoCDP", 5)) { rgExt[cExt].pszObjId = szOID_CRL_DIST_POINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbCrlDistPointsEncoded; rgExt[cExt].Value.cbData = cbCrlDistPointsEncoded; cExt++; } }
if (0 == strcmp(CertPara[dwCert].pszName, "DeltaEndValid")) { rgExt[cExt].pszObjId = szOID_FRESHEST_CRL; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbCrlDistPointsEncoded; rgExt[cExt].Value.cbData = cbCrlDistPointsEncoded; cExt++; }
Cert.cExtension = cExt; }
if (0 == strcmp(CertPara[dwCert].pszName, "DssCA") || 0 == strcmp(CertPara[dwCert].pszName, "DssEnd")) { DWORD cExt = Cert.cExtension; PCTL_USAGE pCtlUsage;
rgExt[cExt].pszObjId = szOID_CERT_POLICIES; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbPoliciesEncoded; rgExt[cExt].Value.cbData = cbPoliciesEncoded; cExt++;
if (0 == strcmp(CertPara[dwCert].pszName, "DssCA")) pCtlUsage = &rgCtlUsage[0]; else pCtlUsage = &rgCtlUsage[2];
if (!AllocAndEncodeObject( X509_ENHANCED_KEY_USAGE, (const void *) pCtlUsage, &pbEnhancedKeyUsageEncoded, &cbEnhancedKeyUsageEncoded)) goto ErrorReturn;
rgExt[cExt].pszObjId = szOID_ENHANCED_KEY_USAGE; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbEnhancedKeyUsageEncoded; rgExt[cExt].Value.cbData = cbEnhancedKeyUsageEncoded; cExt++;
Cert.cExtension = cExt; } else if (0 == strcmp("TestAIAEnd", CertPara[dwCert].pszName)) { DWORD cExt = Cert.cExtension;
rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded; rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded; cExt++;
Cert.cExtension = cExt; } else if (0 == strcmp(CertPara[dwCert].pszName, "RolloverRoot") || 0 == (CertPara[dwCert].dwFlags & (NO_EXT_PARA_FLAG | VALID_PARA_FLAG))) { DWORD cExt = Cert.cExtension;
rgExt[cExt].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER2; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbKeyId2Encoded; rgExt[cExt].Value.cbData = cbKeyId2Encoded; cExt++;
if (0 != strcmp(CertPara[dwCert].pszName, "RolloverRoot")) { rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded; rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded; cExt++; }
#if 1
if (TRUE) { #else
if (CertPara[dwCert].dwFlags & CA_PARA_FLAG) { #endif
if (!CreateKeyId( dwCert, &pbSubjectKeyIdEncoded, &cbSubjectKeyIdEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_SUBJECT_KEY_IDENTIFIER; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbSubjectKeyIdEncoded; rgExt[cExt].Value.cbData = cbSubjectKeyIdEncoded; cExt++; }
if (CertPara[dwCert].dwFlags & (USE1_PARA_FLAG | USE2_PARA_FLAG)) { if (!CreateEnhancedKeyUsage( CertPara[dwCert].dwFlags, &pbEnhancedKeyUsageEncoded, &cbEnhancedKeyUsageEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_ENHANCED_KEY_USAGE; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbEnhancedKeyUsageEncoded; rgExt[cExt].Value.cbData = cbEnhancedKeyUsageEncoded; cExt++; }
Cert.cExtension = cExt; } else if (0 == strcmp(CertPara[dwCert].pszName, "RolloverCA")) { DWORD cExt = Cert.cExtension;
rgExt[cExt].pszObjId = szOID_AUTHORITY_INFO_ACCESS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbAuthorityInfoAccessEncoded; rgExt[cExt].Value.cbData = cbAuthorityInfoAccessEncoded; cExt++;
Cert.cExtension = cExt; }
if (dwCert == POLICY_ROOT || dwCert == POLICY_CA) { // 0 - Root
// 1 - CA
DWORD cExt = Cert.cExtension;
if (!CreatePolicyMappings( dwCert, &pbPolicyMappingsEncoded, &cbPolicyMappingsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_POLICY_MAPPINGS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbPolicyMappingsEncoded; rgExt[cExt].Value.cbData = cbPolicyMappingsEncoded; cExt++;
if (!CreatePolicyConstraints( dwCert, &pbPolicyConstraintsEncoded, &cbPolicyConstraintsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_POLICY_CONSTRAINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbPolicyConstraintsEncoded; rgExt[cExt].Value.cbData = cbPolicyConstraintsEncoded; cExt++;
if (!CreateNameConstraints( dwCert, &pbNameConstraintsEncoded, &cbNameConstraintsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbNameConstraintsEncoded; rgExt[cExt].Value.cbData = cbNameConstraintsEncoded; cExt++;
Cert.cExtension = cExt;
} else if (dwCert == ROLLOVER_CROSS_CERT) { DWORD cExt = Cert.cExtension;
if (!CreatePolicyConstraints( dwCert, &pbPolicyConstraintsEncoded, &cbPolicyConstraintsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_POLICY_CONSTRAINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbPolicyConstraintsEncoded; rgExt[cExt].Value.cbData = cbPolicyConstraintsEncoded; cExt++;
Cert.cExtension = cExt;
} else if (0 == strcmp(CertPara[dwCert].pszName, "MissingNCCA")) { DWORD cExt = Cert.cExtension;
if (!CreateNameConstraints( dwCert, &pbNameConstraintsEncoded, &cbNameConstraintsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbNameConstraintsEncoded; rgExt[cExt].Value.cbData = cbNameConstraintsEncoded; cExt++;
Cert.cExtension = cExt;
} else if (0 == strcmp(CertPara[dwCert].pszName, "InvalidNCCA_AV")) { DWORD cExt = Cert.cExtension; static BYTE rgbExt[] = {5,0};
rgExt[cExt].pszObjId = szOID_NAME_CONSTRAINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = rgbExt; rgExt[cExt].Value.cbData = 0; // sizeof(rgbExt);
cExt++;
Cert.cExtension = cExt;
} else if (CertPara[dwCert].dwFlags & ALL_EXT_PARA_FLAG) { DWORD cExt = Cert.cExtension;
if (!CreateSMIMECapabilities( dwCert, &pbSMIMECapabilitiesEncoded, &cbSMIMECapabilitiesEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_RSA_SMIMECapabilities; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbSMIMECapabilitiesEncoded; rgExt[cExt].Value.cbData = cbSMIMECapabilitiesEncoded; cExt++;
if (!CreateCertIssuingDistPoint( dwCert, &pbIDPEncoded, &cbIDPEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_ISSUING_DIST_POINT; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbIDPEncoded; rgExt[cExt].Value.cbData = cbIDPEncoded; cExt++;
if (!CreateCrossCertDistPoints( dwCert, &pbCrossCertDistPointsEncoded, &cbCrossCertDistPointsEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_CROSS_CERT_DIST_POINTS; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbCrossCertDistPointsEncoded; rgExt[cExt].Value.cbData = cbCrossCertDistPointsEncoded; cExt++;
Cert.cExtension = cExt; }
if (CertPara[dwCert].dwFlags & ALT_DIR_NAME_PARA_FLAG) { DWORD cExt = Cert.cExtension;
if (!CreateAltName( dwIssuer, &pbIssuerAltNameEncoded, &cbIssuerAltNameEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_ISSUER_ALT_NAME2; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbIssuerAltNameEncoded; rgExt[cExt].Value.cbData = cbIssuerAltNameEncoded; cExt++;
Cert.cExtension = cExt; }
if (CertPara[dwCert].pszManifold) { DWORD cExt = Cert.cExtension;
rgExt[cExt].pszObjId = szOID_CERT_MANIFOLD; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = (BYTE *) CertPara[dwCert].pszManifold; rgExt[cExt].Value.cbData = strlen(CertPara[dwCert].pszManifold); cExt++;
Cert.cExtension = cExt; }
if (0 == strcmp("V1", CertPara[dwCert].pszName)) { Cert.dwVersion = CERT_V1; Cert.cExtension = 0; } else if (0 == strcmp("V2", CertPara[dwCert].pszName)) { Cert.dwVersion = CERT_V2; Cert.cExtension = 0;
#define ISSUER_UNIQUE_ID "Issuer Unique Id"
#define SUBJECT_UNIQUE_ID "Subject Unique Id"
Cert.IssuerUniqueId.pbData = (BYTE *) ISSUER_UNIQUE_ID; Cert.IssuerUniqueId.cbData = strlen(ISSUER_UNIQUE_ID); Cert.IssuerUniqueId.cUnusedBits = 0;
Cert.SubjectUniqueId.pbData = (BYTE *) SUBJECT_UNIQUE_ID; Cert.SubjectUniqueId.cbData = strlen(SUBJECT_UNIQUE_ID); Cert.SubjectUniqueId.cUnusedBits = 0; }
Cert.rgExtension = rgExt;
if (!AllocAndEncodeObject( X509_CERT_TO_BE_SIGNED, &Cert, &pbCertEncoded, &cbCertEncoded)) goto ErrorReturn;
if (!EncodeSignedContent( dwIssuer, pbCertEncoded, cbCertEncoded, ppbEncoded, pcbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: *ppbEncoded = NULL; *pcbEncoded = 0; fResult = FALSE; CommonReturn: if (pbKeyIdEncoded) TestFree(pbKeyIdEncoded); if (pbKeyId2Encoded) TestFree(pbKeyId2Encoded); if (pbSubjectKeyIdEncoded) TestFree(pbSubjectKeyIdEncoded); if (pbAuthorityInfoAccessEncoded) TestFree(pbAuthorityInfoAccessEncoded); if (pbCrlDistPointsEncoded) TestFree(pbCrlDistPointsEncoded); if (pbKeyAttrEncoded) TestFree(pbKeyAttrEncoded); if (pbAltNameEncoded) TestFree(pbAltNameEncoded); if (pbIssuerAltNameEncoded) TestFree(pbIssuerAltNameEncoded); if (pbKeyUsageRestrictionEncoded) TestFree(pbKeyUsageRestrictionEncoded); if (pbBasicConstraintsEncoded) TestFree(pbBasicConstraintsEncoded); if (pbKeyUsageEncoded) TestFree(pbKeyUsageEncoded); if (pbBasicConstraints2Encoded) TestFree(pbBasicConstraints2Encoded); if (pbPoliciesEncoded) TestFree(pbPoliciesEncoded); if (pbSETAccountAliasEncoded) TestFree(pbSETAccountAliasEncoded); if (pbSETHashedRootKeyEncoded) TestFree(pbSETHashedRootKeyEncoded); if (pbSETCertificateTypeEncoded) TestFree(pbSETCertificateTypeEncoded); if (pbSETMerchantDataEncoded) TestFree(pbSETMerchantDataEncoded); if (pbSpcSpAgencyEncoded0) TestFree(pbSpcSpAgencyEncoded0); if (pbSpcSpAgencyEncoded1) TestFree(pbSpcSpAgencyEncoded1); if (pbSpcSpAgencyEncoded2) TestFree(pbSpcSpAgencyEncoded2); if (pbSpcCommonNameEncoded) TestFree(pbSpcCommonNameEncoded); if (pbNetscapeCertType) TestFree(pbNetscapeCertType); if (pbNetscapeComment) TestFree(pbNetscapeComment); if (pbNetscapeRevUrl) TestFree(pbNetscapeRevUrl); if (pbNetscapeBaseUrl) TestFree(pbNetscapeBaseUrl);
if (pbSubjectEncoded) TestFree(pbSubjectEncoded); if (pbIssuerEncoded) TestFree(pbIssuerEncoded); if (pPubKeyInfo) TestFree(pPubKeyInfo); if (pbCertEncoded) TestFree(pbCertEncoded); if (pbEnhancedKeyUsageEncoded) TestFree(pbEnhancedKeyUsageEncoded); if (pbSMIMECapabilitiesEncoded) TestFree(pbSMIMECapabilitiesEncoded); if (pbIDPEncoded) TestFree(pbIDPEncoded); if (pbNameConstraintsEncoded) TestFree(pbNameConstraintsEncoded); if (pbPolicyMappingsEncoded) TestFree(pbPolicyMappingsEncoded); if (pbPolicyConstraintsEncoded) TestFree(pbPolicyConstraintsEncoded); if (pbCrossCertDistPointsEncoded) TestFree(pbCrossCertDistPointsEncoded);
return fResult; }
static BOOL EncodeCrl( DWORD dwCert, BYTE **ppbEncoded, DWORD *pcbEncoded, DWORD dwAki ) { BOOL fResult; BYTE *pbIssuerEncoded = NULL; DWORD cbIssuerEncoded; BYTE *pbCrlEncoded = NULL; DWORD cbCrlEncoded; BYTE *pbKeyId2Encoded = NULL; DWORD cbKeyId2Encoded; BYTE *pbIDPEncoded = NULL; DWORD cbIDPEncoded; DWORD i;
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name;
CRL_ENTRY rgEntry[CERT_CNT]; CRL_INFO Crl;
FILETIME SerialNumber[CERT_CNT];
#define CRL_EXTENSION_CNT 2
CERT_EXTENSION rgExt[CRL_EXTENSION_CNT];
// Max of 1 extension per entry
CERT_EXTENSION rgEntryExt[CERT_CNT]; memset(rgEntryExt, 0, sizeof(rgEntryExt));
// ISSUER
CreateNameInfo(dwCert, &Name, rgRDN, rgAttr); if (!AllocAndEncodeObject( X509_NAME, &Name, &pbIssuerEncoded, &cbIssuerEncoded )) goto ErrorReturn;
// CRL
memset(&Crl, 0, sizeof(Crl)); Crl.dwVersion = CRL_V2; if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) Crl.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID; else Crl.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID; Crl.Issuer.pbData = pbIssuerEncoded; Crl.Issuer.cbData = cbIssuerEncoded;
{ SYSTEMTIME SystemTime = TestTime;
if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) { SystemTime.wYear = 1921; MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate); SystemTime.wYear = 2071; MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate); } else { MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate); if (0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) { SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate); } } }
Crl.cCRLEntry = 0; Crl.rgCRLEntry = rgEntry; for (i = 0; i < CERT_CNT; i++) { if (CertPara[i].dwIssuer == dwCert && (CertPara[i].dwFlags & REVOKED_PARA_FLAG)) { DWORD j;
SYSTEMTIME SystemTime = TestTime;
j = Crl.cCRLEntry++; memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
SystemTime.wMilliseconds += (WORD) i; MySystemTimeToFileTime(&SystemTime, &SerialNumber[j]);
rgEntry[j].SerialNumber.pbData = (BYTE *) &SerialNumber[j]; rgEntry[j].SerialNumber.cbData = sizeof(SerialNumber[j]); if (CertPara[dwCert].dwFlags & GENERALIZED_TIME_PARA_FLAG) { SystemTime.wYear = 1922; MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate); } else MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
if (0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) { if (!CreateCRLReason( &rgEntryExt[j].Value.pbData, &rgEntryExt[j].Value.cbData)) goto ErrorReturn; rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE; rgEntryExt[j].fCritical = FALSE; rgEntry[j].cExtension = 1; rgEntry[j].rgExtension = &rgEntryExt[j]; }
} }
if (AKI2_NONE != dwAki && 0 == (CertPara[dwCert].dwFlags & NO_CRL_EXT_PARA_FLAG)) { // Crl Extensions
if (!CreateAuthorityKeyId2( dwCert, dwCert, &pbKeyId2Encoded, &cbKeyId2Encoded, dwAki )) goto ErrorReturn;
rgExt[0].pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER2; rgExt[0].fCritical = FALSE; rgExt[0].Value.pbData = pbKeyId2Encoded; rgExt[0].Value.cbData = cbKeyId2Encoded;
if (!CreateCrlIssuingDistPoint( &pbIDPEncoded, &cbIDPEncoded )) goto ErrorReturn;
rgExt[1].pszObjId = szOID_ISSUING_DIST_POINT; rgExt[1].fCritical = FALSE; rgExt[1].Value.pbData = pbIDPEncoded; rgExt[1].Value.cbData = cbIDPEncoded;
Crl.cExtension = CRL_EXTENSION_CNT; Crl.rgExtension = rgExt; }
if (0 == strcmp("V1", CertPara[dwCert].pszName)) { Crl.dwVersion = CRL_V1; Crl.cExtension = 0; }
if (!AllocAndEncodeObject( X509_CERT_CRL_TO_BE_SIGNED, &Crl, &pbCrlEncoded, &cbCrlEncoded )) goto ErrorReturn;
if (!EncodeSignedContent( dwCert, pbCrlEncoded, cbCrlEncoded, ppbEncoded, pcbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: *ppbEncoded = NULL; *pcbEncoded = 0; fResult = FALSE; CommonReturn: if (pbKeyId2Encoded) TestFree(pbKeyId2Encoded); if (pbIDPEncoded) TestFree(pbIDPEncoded); if (pbIssuerEncoded) TestFree(pbIssuerEncoded); if (pbCrlEncoded) TestFree(pbCrlEncoded); for (i = 0; i < CERT_CNT; i++) { if (rgEntryExt[i].Value.pbData) TestFree(rgEntryExt[i].Value.pbData); }
return fResult; }
static BOOL EncodeBaseOrDeltaCrl( DWORD dwIssuer, int iBase, DWORD dwFlags, BYTE **ppbEncoded, DWORD *pcbEncoded ) { BOOL fResult; DWORD i; BYTE *pbIssuerNameEncoded = NULL; DWORD cbIssuerNameEncoded; BYTE *pbCDPEncoded = NULL; DWORD cbCDPEncoded; BYTE *pbBaseEncoded; DWORD cbBaseEncoded; BYTE *pbIDPEncoded = NULL; DWORD cbIDPEncoded; BYTE *pbCrlEncoded = NULL; DWORD cbCrlEncoded;
CERT_RDN rgRDN[RDN_CNT]; CERT_RDN_ATTR rgAttr[ATTR_CNT]; CERT_NAME_INFO Name; FILETIME SerialNumber[CERT_CNT]; CRL_ENTRY rgEntry[CERT_CNT]; CRL_INFO Crl; CERT_EXTENSION rgExt[10]; DWORD cExt = 0;
// Max of 1 extension per entry
CERT_EXTENSION rgEntryExt[CERT_CNT]; memset(rgEntryExt, 0, sizeof(rgEntryExt));
// ISSUER
CreateNameInfo(dwIssuer, &Name, rgRDN, rgAttr); if (!AllocAndEncodeObject( X509_NAME, &Name, &pbIssuerNameEncoded, &cbIssuerNameEncoded )) goto ErrorReturn;
// CRL
memset(&Crl, 0, sizeof(Crl)); Crl.dwVersion = CRL_V2; if (CertPara[dwIssuer].dwFlags & DSS_PARA_FLAG) Crl.SignatureAlgorithm.pszObjId = DSS_SIGNATURE_ALG_OBJID; else Crl.SignatureAlgorithm.pszObjId = SIGNATURE_ALG_OBJID; Crl.Issuer.pbData = pbIssuerNameEncoded; Crl.Issuer.cbData = cbIssuerNameEncoded;
{ SYSTEMTIME SystemTime = TestTime;
if (dwFlags & EXPIRED_CRL_FLAG) { SystemTime.wYear = 1997; MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate); SystemTime.wYear = 1998; MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate); } else if (CertPara[dwIssuer].dwFlags & GENERALIZED_TIME_PARA_FLAG) { SystemTime.wYear = 1921; MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate); SystemTime.wYear = 2071; MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate); } else { MySystemTimeToFileTime(&SystemTime, &Crl.ThisUpdate); if (0 == (CertPara[dwIssuer].dwFlags & NO_CRL_EXT_PARA_FLAG)) { SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Crl.NextUpdate); } } }
Crl.cCRLEntry = 0; Crl.rgCRLEntry = rgEntry; if (0 == (dwFlags & NO_ENTRIES_CRL_FLAG)) { for (i = 0; i < CERT_CNT; i++) { if (CertPara[i].dwIssuer == dwIssuer && (CertPara[i].dwFlags & REVOKED_PARA_FLAG)) { DWORD j;
SYSTEMTIME SystemTime = TestTime;
j = Crl.cCRLEntry++; memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
SystemTime.wMilliseconds += (WORD) i; MySystemTimeToFileTime(&SystemTime, &SerialNumber[j]);
rgEntry[j].SerialNumber.pbData = (BYTE *) &SerialNumber[j]; rgEntry[j].SerialNumber.cbData = sizeof(SerialNumber[j]); if (CertPara[dwIssuer].dwFlags & GENERALIZED_TIME_PARA_FLAG) { SystemTime.wYear = 1922; MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate); } else MySystemTimeToFileTime(&SystemTime, &rgEntry[j].RevocationDate);
if (dwFlags & REMOVE_FROM_CRL_FLAG) { int iReason = CRL_REASON_REMOVE_FROM_CRL; if (!AllocAndEncodeObject( X509_ENUMERATED, (const void *) &iReason, &rgEntryExt[j].Value.pbData, &rgEntryExt[j].Value.cbData)) goto ErrorReturn; rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE; rgEntryExt[j].fCritical = TRUE; rgEntry[j].cExtension = 1; rgEntry[j].rgExtension = &rgEntryExt[j]; } else if (0 == (CertPara[dwIssuer].dwFlags & NO_CRL_EXT_PARA_FLAG)) { if (dwFlags & HOLD_CRL_FLAG) { int iReason = CRL_REASON_CERTIFICATE_HOLD; if (!AllocAndEncodeObject( X509_ENUMERATED, (const void *) &iReason, &rgEntryExt[j].Value.pbData, &rgEntryExt[j].Value.cbData)) goto ErrorReturn; } else { if (!CreateCRLReason( &rgEntryExt[j].Value.pbData, &rgEntryExt[j].Value.cbData)) goto ErrorReturn; } rgEntryExt[j].pszObjId = szOID_CRL_REASON_CODE; rgEntryExt[j].fCritical = FALSE; rgEntry[j].cExtension = 1; rgEntry[j].rgExtension = &rgEntryExt[j]; }
} } }
// Extensions
memset(&rgExt, 0, sizeof(rgExt)); if (!AllocAndEncodeObject( X509_INTEGER, (const void *) &iBase, &pbBaseEncoded, &cbBaseEncoded)) goto ErrorReturn; if (dwFlags & FRESHEST_CRL_FLAG) { rgExt[0].pszObjId = szOID_DELTA_CRL_INDICATOR; rgExt[0].fCritical = TRUE; } else { rgExt[0].pszObjId = szOID_CRL_NUMBER; rgExt[0].fCritical = FALSE; } rgExt[0].Value.pbData = pbBaseEncoded; rgExt[0].Value.cbData = cbBaseEncoded; cExt = 1;
if (dwFlags & UNSUPPORTED_CRITICAL_EXT_CRL_FLAG) { rgExt[cExt].pszObjId = "1.2.3.4.1999.2000"; rgExt[cExt].fCritical = TRUE; rgExt[cExt].Value.pbData = pbBaseEncoded; rgExt[cExt].Value.cbData = cbBaseEncoded; cExt++; }
if (0 == (dwFlags & FRESHEST_CRL_FLAG) && 0 == (dwFlags & NO_FRESHEST_CDP_CRL_FLAG)) { if (!CreateCrlDistPoints( dwIssuer, CRL_DIST_POINTS_DELTA_FLAG, &pbCDPEncoded, &cbCDPEncoded)) goto ErrorReturn; rgExt[cExt].pszObjId = szOID_FRESHEST_CRL; rgExt[cExt].fCritical = FALSE; rgExt[cExt].Value.pbData = pbCDPEncoded; rgExt[cExt].Value.cbData = cbCDPEncoded; cExt++; }
if (0 == (dwFlags & NO_IDP_CRL_FLAG)) { CRL_ISSUING_DIST_POINT IDP; PCERT_ALT_NAME_INFO pIDPAltNameInfo; CERT_ALT_NAME_ENTRY rgIDPAltNameEntry[8]; BYTE bOnlySomeReasonFlags;
memset(&IDP, 0, sizeof(IDP)); if (dwFlags & UNSUPPORTED_IDP_OPTIONS_CRL_FLAG) { IDP.OnlySomeReasonFlags.cbData = 1; IDP.OnlySomeReasonFlags.pbData = &bOnlySomeReasonFlags; IDP.OnlySomeReasonFlags.cUnusedBits = 1; bOnlySomeReasonFlags = CRL_REASON_KEY_COMPROMISE_FLAG | CRL_REASON_CA_COMPROMISE_FLAG;
IDP.fIndirectCRL = TRUE; }
if (dwFlags & ONLY_USERS_CRL_FLAG) IDP.fOnlyContainsUserCerts = TRUE; if (dwFlags & ONLY_CAS_CRL_FLAG) IDP.fOnlyContainsCACerts = TRUE;
IDP.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
rgIDPAltNameEntry[0].dwAltNameChoice = CERT_ALT_NAME_OTHER_NAME; rgIDPAltNameEntry[0].pOtherName = &CrlOtherName; rgIDPAltNameEntry[1].dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME; rgIDPAltNameEntry[1].DirectoryName.pbData = pbIssuerNameEncoded; rgIDPAltNameEntry[1].DirectoryName.cbData = cbIssuerNameEncoded; rgIDPAltNameEntry[2].dwAltNameChoice = CERT_ALT_NAME_DNS_NAME; rgIDPAltNameEntry[2].pwszDNSName = CRL_DNS_NAME; rgIDPAltNameEntry[3].dwAltNameChoice = CERT_ALT_NAME_RFC822_NAME; rgIDPAltNameEntry[3].pwszRfc822Name = CRL_EMAIL_NAME; rgIDPAltNameEntry[4].dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID; rgIDPAltNameEntry[4].pszRegisteredID = CRL_REGISTERED_ID; rgIDPAltNameEntry[5].dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS; rgIDPAltNameEntry[5].IPAddress.pbData = CrlIPAddress; rgIDPAltNameEntry[5].IPAddress.cbData = sizeof(CrlIPAddress); rgIDPAltNameEntry[6].dwAltNameChoice = CERT_ALT_NAME_URL; rgIDPAltNameEntry[6].pwszURL = CRL_URL_NAME2; rgIDPAltNameEntry[7].dwAltNameChoice = CERT_ALT_NAME_URL; rgIDPAltNameEntry[7].pwszURL = CRL_URL_NAME1;
pIDPAltNameInfo = &IDP.DistPointName.FullName; switch (iBase) { case 1: pIDPAltNameInfo->cAltEntry = 1; pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[0]; break; case 2: pIDPAltNameInfo->cAltEntry = 1; pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[1]; break; case 3: pIDPAltNameInfo->cAltEntry = 2; pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[2]; break; case 4: pIDPAltNameInfo->cAltEntry = 2; pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[4]; break; default: pIDPAltNameInfo->cAltEntry = 2; pIDPAltNameInfo->rgAltEntry = &rgIDPAltNameEntry[6]; break; }
if (!AllocAndEncodeObject( szOID_ISSUING_DIST_POINT, &IDP, &pbIDPEncoded, &cbIDPEncoded)) goto ErrorReturn;
rgExt[cExt].pszObjId = szOID_ISSUING_DIST_POINT; rgExt[cExt].fCritical = TRUE; rgExt[cExt].Value.pbData = pbIDPEncoded; rgExt[cExt].Value.cbData = cbIDPEncoded; cExt++; }
Crl.cExtension = cExt; Crl.rgExtension = rgExt;
if (!AllocAndEncodeObject( X509_CERT_CRL_TO_BE_SIGNED, &Crl, &pbCrlEncoded, &cbCrlEncoded )) goto ErrorReturn;
if (!EncodeSignedContent( dwIssuer, pbCrlEncoded, cbCrlEncoded, ppbEncoded, pcbEncoded)) goto ErrorReturn;
fResult = TRUE; goto CommonReturn;
ErrorReturn: *ppbEncoded = NULL; *pcbEncoded = 0; fResult = FALSE; CommonReturn: if (pbIssuerNameEncoded) TestFree(pbIssuerNameEncoded); if (pbBaseEncoded) TestFree(pbBaseEncoded); if (pbCDPEncoded) TestFree(pbCDPEncoded); if (pbIDPEncoded) TestFree(pbIDPEncoded); if (pbCrlEncoded) TestFree(pbCrlEncoded); for (i = 0; i < CERT_CNT; i++) { if (rgEntryExt[i].Value.pbData) TestFree(rgEntryExt[i].Value.pbData); }
return fResult; }
static BOOL EncodeCtl(DWORD dwCert, DWORD dwEncodeFlags, BYTE **ppbEncoded, DWORD *pcbEncoded) { BOOL fResult;
BYTE *pbNextUpdateLoc = NULL; DWORD cbNextUpdateLoc; BYTE *pbCtlEncoded = NULL; DWORD cbCtlEncoded;
DWORD dwFlags; DWORD dwCtlFlags; DWORD dwUseFlag; DWORD i;
struct { FILETIME ft; DWORD dwCert; } SequenceNumber;
PCTL_USAGE pCtlUsage; // not allocated
BYTE rgbHash[CERT_CNT][MAX_HASH_LEN]; BYTE rgbZero[1] = {0};
BYTE NullDer[] = {0x05, 0x00}; BYTE IntegerDer[] = {0x02, 0x01, 0x35}; CRYPT_ATTR_BLOB rgAttrBlob[2] = { 2, (BYTE *) NullDer, 3, (BYTE *) IntegerDer }; CRYPT_ATTRIBUTE rgAttr[] = { "1.2.3.4.5.0", 1, rgAttrBlob, "1.2.1.1.1.1.1.1", 2, rgAttrBlob };
CMSG_SIGNER_ENCODE_INFO SignerInfo; CMSG_SIGNED_ENCODE_INFO SignInfo; CRYPT_ATTRIBUTE SignerAttr; CRYPT_ATTR_BLOB SignerAttrBlob; CERT_BLOB CertBlob;
CTL_ENTRY rgEntry[CERT_CNT]; #define CTL_EXTENSION_CNT 1
CERT_EXTENSION rgExt[CTL_EXTENSION_CNT]; CTL_INFO Ctl;
if (NULL == rgpCertContext[dwCert]) goto ErrorReturn;
dwFlags = CertPara[dwCert].dwFlags;
// CTL
memset(&Ctl, 0, sizeof(Ctl)); Ctl.dwVersion = CTL_V1;
dwCtlFlags = dwFlags & (CTL1_PARA_FLAG | CTL2_PARA_FLAG); dwUseFlag = 0; switch (dwCtlFlags) { case CTL1_PARA_FLAG: if (dwFlags & NO_EXT_PARA_FLAG) pCtlUsage = &rgCtlUsage[0]; else { pCtlUsage = &rgCtlUsage[1]; dwUseFlag = USE1_PARA_FLAG; } break; case CTL2_PARA_FLAG: pCtlUsage = &rgCtlUsage[2]; dwUseFlag = USE2_PARA_FLAG; break; case CTL1_PARA_FLAG | CTL2_PARA_FLAG: default: pCtlUsage = &rgCtlUsage[3]; break; } Ctl.SubjectUsage = *pCtlUsage;
if (dwFlags & CTL2_PARA_FLAG) { DWORD dwIdx; if (dwFlags & TIME_INVALID_PARA_FLAG) { assert(dwFlags & DUPLICATE_PARA_FLAG); dwIdx = dwCert - 1; } else dwIdx = dwCert; Ctl.ListIdentifier.pbData = (BYTE *) CertPara[dwIdx].pszName; Ctl.ListIdentifier.cbData = strlen(CertPara[dwIdx].pszName);
MySystemTimeToFileTime(&TestTime, &SequenceNumber.ft); SequenceNumber.dwCert = dwCert; Ctl.SequenceNumber.pbData = (BYTE *) &SequenceNumber; Ctl.SequenceNumber.cbData = sizeof(SequenceNumber); }
{ SYSTEMTIME SystemTime = TestTime;
if (dwFlags & TIME_INVALID_PARA_FLAG) { SystemTime.wYear -=2; MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate); SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate); } else { MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate); if (dwUseFlag) { SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate); } } }
Ctl.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
Ctl.cCTLEntry = 0; Ctl.rgCTLEntry = rgEntry;
for (i = 0; i < CERT_CNT; i++) { if (CertPara[i].dwFlags & dwUseFlag) { DWORD j; DWORD cbHash;
if (NULL == rgpCertContext[i]) continue;
j = Ctl.cCTLEntry++; memset(&rgEntry[j], 0, sizeof(rgEntry[j]));
cbHash = MAX_HASH_LEN; if (CertGetCertificateContextProperty( rgpCertContext[i], CERT_SHA1_HASH_PROP_ID, rgbHash[j], &cbHash)) { rgEntry[j].SubjectIdentifier.pbData = rgbHash[j]; rgEntry[j].SubjectIdentifier.cbData = cbHash; } else { PrintLastError( "CertGetCertificateContextProperty(SHA1_HASH)"); rgEntry[j].SubjectIdentifier.pbData = rgbZero; rgEntry[j].SubjectIdentifier.cbData = sizeof(rgbZero); }
if (CertPara[i].dwFlags & ALL_EXT_PARA_FLAG) { rgEntry[j].cAttribute = sizeof(rgAttr) / sizeof(rgAttr[0]); rgEntry[j].rgAttribute = rgAttr; } }
}
if (!CreateNextUpdateLocation( dwCert, FALSE, // fProp
&pbNextUpdateLoc, &cbNextUpdateLoc)) goto ErrorReturn;
// Ctl Extensions
rgExt[0].pszObjId = szOID_NEXT_UPDATE_LOCATION; rgExt[0].fCritical = FALSE; rgExt[0].Value.pbData = pbNextUpdateLoc; rgExt[0].Value.cbData = cbNextUpdateLoc;
if (0 == (CertPara[dwCert].dwFlags & NO_EXT_PARA_FLAG)) { Ctl.cExtension = 1; Ctl.rgExtension = rgExt; }
memset(&SignerInfo, 0, sizeof(SignerInfo)); SignerInfo.cbSize = sizeof(SignerInfo); SignerInfo.pCertInfo = rgpCertContext[dwCert]->pCertInfo; if (CertPara[dwCert].dwFlags & DSS_PARA_FLAG) { if (CertPara[dwCert].dwFlags & DSS_512_PARA_FLAG) SignerInfo.hCryptProv = hDSS512CryptProv; else SignerInfo.hCryptProv = hDSSCryptProv; } else if (CertPara[dwCert].dwFlags & ENH_1024_PARA_FLAG) SignerInfo.hCryptProv = hEnh1024CryptProv; else if (CertPara[dwCert].dwFlags & ENH_2048_PARA_FLAG) SignerInfo.hCryptProv = hEnh2048CryptProv; else SignerInfo.hCryptProv = hRSACryptProv; SignerInfo.dwKeySpec = AT_SIGNATURE; SignerInfo.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
if (dwFlags & CTL2_PARA_FLAG) { // Signer Attributes
memset(&SignerAttr, 0, sizeof(SignerAttr)); SignerAttr.pszObjId = szOID_NEXT_UPDATE_LOCATION; SignerAttr.cValue = 1; SignerAttr.rgValue = &SignerAttrBlob; SignerAttrBlob.pbData = pbNextUpdateLoc; SignerAttrBlob.cbData = cbNextUpdateLoc;
SignerInfo.cAuthAttr = 1; SignerInfo.rgAuthAttr = &SignerAttr; SignerInfo.cUnauthAttr = 1; SignerInfo.rgUnauthAttr = &SignerAttr; }
memset(&SignInfo, 0, sizeof(SignInfo)); SignInfo.cbSize = sizeof(SignInfo); if (dwUseFlag) { SignInfo.cSigners = 1; SignInfo.rgSigners = &SignerInfo; SignInfo.cCertEncoded = 1; CertBlob.pbData = rgpCertContext[dwCert]->pbCertEncoded; CertBlob.cbData = rgpCertContext[dwCert]->cbCertEncoded; SignInfo.rgCertEncoded = &CertBlob; }
cbCtlEncoded = 0; if (!CryptMsgEncodeAndSignCTL( dwMsgEncodingType, &Ctl, &SignInfo, dwEncodeFlags, NULL, // pbEncoded
&cbCtlEncoded ) || 0 == cbCtlEncoded) { PrintLastError("EncodeCtl::CryptMsgEncodeAndSignCTL(cbEncoded == 0)"); goto ErrorReturn; } pbCtlEncoded = (BYTE *) TestAlloc(cbCtlEncoded); if (pbCtlEncoded == NULL) goto ErrorReturn; if (!CryptMsgEncodeAndSignCTL( dwMsgEncodingType, &Ctl, &SignInfo, dwEncodeFlags, pbCtlEncoded, &cbCtlEncoded )) { PrintLastError("EncodeCtl::CryptMsgEncodeAndSignCTL"); goto ErrorReturn; }
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbCtlEncoded) TestFree(pbCtlEncoded); pbCtlEncoded = NULL; cbCtlEncoded = 0; fResult = FALSE; CommonReturn: if (pbNextUpdateLoc) TestFree(pbNextUpdateLoc); *ppbEncoded = pbCtlEncoded; *pcbEncoded = cbCtlEncoded;
return fResult; }
static BOOL EncodeUpdateCtl( BOOL fTimeInvalid, LPSTR pszUsageObjId, LPSTR pszListIdentifier, LPWSTR pwszUrl, BYTE **ppbEncoded, DWORD *pcbEncoded ) { BOOL fResult;
BYTE *pbNextUpdateLoc = NULL; DWORD cbNextUpdateLoc; BYTE *pbCtlEncoded = NULL; DWORD cbCtlEncoded;
CERT_BLOB CertBlob; CMSG_SIGNER_ENCODE_INFO SignerInfo; CMSG_SIGNED_ENCODE_INFO SignInfo; CERT_EXTENSION rgExt[1]; CTL_INFO Ctl;
if (NULL == rgpCertContext[UPDATE_CTL_SIGNER]) goto ErrorReturn;
// CTL
memset(&Ctl, 0, sizeof(Ctl)); Ctl.dwVersion = CTL_V1; Ctl.SubjectUsage.cUsageIdentifier = 1; Ctl.SubjectUsage.rgpszUsageIdentifier = &pszUsageObjId;
Ctl.ListIdentifier.pbData = (BYTE *) pszListIdentifier; Ctl.ListIdentifier.cbData = strlen(pszListIdentifier);
{ SYSTEMTIME SystemTime = TestTime;
if (fTimeInvalid) { SystemTime.wYear -=2; MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate); SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate); } else { MySystemTimeToFileTime(&SystemTime, &Ctl.ThisUpdate); SystemTime.wYear++; MySystemTimeToFileTime(&SystemTime, &Ctl.NextUpdate); } }
Ctl.SubjectAlgorithm.pszObjId = szOID_OIWSEC_sha1;
if (!CreateNextUpdateLocation( UPDATE_CTL_SIGNER, // dwCert
FALSE, // fProp
&pbNextUpdateLoc, &cbNextUpdateLoc, pwszUrl)) goto ErrorReturn;
// Ctl Extensions
rgExt[0].pszObjId = szOID_NEXT_UPDATE_LOCATION; rgExt[0].fCritical = FALSE; rgExt[0].Value.pbData = pbNextUpdateLoc; rgExt[0].Value.cbData = cbNextUpdateLoc;
Ctl.cExtension = 1; Ctl.rgExtension = rgExt;
memset(&SignerInfo, 0, sizeof(SignerInfo)); SignerInfo.cbSize = sizeof(SignerInfo); SignerInfo.pCertInfo = rgpCertContext[UPDATE_CTL_SIGNER]->pCertInfo; SignerInfo.hCryptProv = hRSACryptProv; SignerInfo.dwKeySpec = AT_SIGNATURE; SignerInfo.HashAlgorithm.pszObjId = szOID_OIWSEC_sha1;
memset(&SignInfo, 0, sizeof(SignInfo)); SignInfo.cbSize = sizeof(SignInfo); SignInfo.cSigners = 1; SignInfo.rgSigners = &SignerInfo; SignInfo.cCertEncoded = 1; CertBlob.pbData = rgpCertContext[UPDATE_CTL_SIGNER]->pbCertEncoded; CertBlob.cbData = rgpCertContext[UPDATE_CTL_SIGNER]->cbCertEncoded; SignInfo.rgCertEncoded = &CertBlob;
cbCtlEncoded = 0; if (!CryptMsgEncodeAndSignCTL( dwMsgEncodingType, &Ctl, &SignInfo, 0, // dwEncodeFlags
NULL, // pbEncoded
&cbCtlEncoded ) || 0 == cbCtlEncoded) { PrintLastError("EncodeUpdateCtl::CryptMsgEncodeAndSignCTL(cbEncoded == 0)"); goto ErrorReturn; } pbCtlEncoded = (BYTE *) TestAlloc(cbCtlEncoded); if (pbCtlEncoded == NULL) goto ErrorReturn; if (!CryptMsgEncodeAndSignCTL( dwMsgEncodingType, &Ctl, &SignInfo, 0, // dwEncodeFlags
pbCtlEncoded, &cbCtlEncoded )) { PrintLastError("EncodeUpdateCtl::CryptMsgEncodeAndSignCTL"); goto ErrorReturn; }
fResult = TRUE; goto CommonReturn;
ErrorReturn: if (pbCtlEncoded) TestFree(pbCtlEncoded); pbCtlEncoded = NULL; cbCtlEncoded = 0; fResult = FALSE; CommonReturn: if (pbNextUpdateLoc) TestFree(pbNextUpdateLoc); *ppbEncoded = pbCtlEncoded; *pcbEncoded = cbCtlEncoded;
return fResult; }
|