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

7298 lines
177 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: CertMgr
//
// Contents: Certificate store management tools
//
// See Usage() for list of options.
//
//
// Functions: wmain
//
// History: July 21st xiaohs created
//
//--------------------------------------------------------------------------
#include "certmgr.h"
//--------------------------------------------------------------------------
//
// Global Flags
//
//----------------------------------------------------------------------------
#define ITEM_VERBOSE 0x00010000
#define ITEM_CERT 0x00000001
#define ITEM_CTL 0x00000002
#define ITEM_CRL 0x00000004
#define ACTION_DISPLAY 0x01
#define ACTION_ADD 0x02
#define ACTION_DELETE 0x04
#define ACTION_PUT 0x08
#define OPTION_SWITCH_SIZE 10
#define SHA1_LENGTH 20
#define MAX_HASH_LEN 20
#define MAX_STRING_RSC_SIZE 512
//--------------------------------------------------------------------------
//
// Global Variable
//
//----------------------------------------------------------------------------
HMODULE hModule=NULL;
//varibles for installable formatting routines
HCRYPTOIDFUNCSET hFormatFuncSet;
const CRYPT_OID_FUNC_ENTRY g_FormatTable[] = {
szOID_BASIC_CONSTRAINTS2, FormatBasicConstraints2};
DWORD g_dwFormatCount=sizeof(g_FormatTable)/sizeof(g_FormatTable[0]);
typedef BOOL (WINAPI *PFN_FORMAT_FUNC)(
IN DWORD dwCertEncodingType,
IN DWORD dwFormatType,
IN DWORD dwFormatStrType,
IN void *pFormatStruct,
IN LPCSTR lpszStructType,
IN const BYTE *pbEncoded,
IN DWORD cbEncoded,
OUT void *pbFormat,
IN OUT DWORD *pcbFormat
);
//variables for installing OID information
typedef struct _CERTMGR_OID_INFO
{
LPCSTR pszOID;
int idsOIDName;
}CERTMGR_OID_INFO;
CERTMGR_OID_INFO g_rgOIDInfo[]={
SPC_SP_AGENCY_INFO_OBJID, IDS_SPC_SP_NAME,
SPC_FINANCIAL_CRITERIA_OBJID, IDS_SPC_FIN_NAME,
SPC_MINIMAL_CRITERIA_OBJID, IDS_SPC_MIN_NAME,
szOID_NETSCAPE_CERT_TYPE, IDS_NTSP_CERT_NAME,
szOID_NETSCAPE_BASE_URL, IDS_NTSP_BASE_NAME,
szOID_NETSCAPE_REVOCATION_URL, IDS_NTSP_REV_NAME,
szOID_NETSCAPE_CA_REVOCATION_URL, IDS_NTSP_CA_REV_NAME,
szOID_NETSCAPE_CERT_RENEWAL_URL, IDS_NTSP_RENEW_NAME,
szOID_NETSCAPE_CA_POLICY_URL, IDS_NTSP_POL_NAME,
szOID_NETSCAPE_SSL_SERVER_NAME, IDS_NTSP_SSL_SERVER_NAME,
szOID_NETSCAPE_COMMENT, IDS_NTSP_COMMENT};
DWORD g_dwOIDInfo=sizeof(g_rgOIDInfo)/sizeof(g_rgOIDInfo[0]);
//varibles for string manipulations
WCHAR g_wszBuffer[MAX_STRING_RSC_SIZE];
DWORD g_dwBufferSize=sizeof(g_wszBuffer)/sizeof(g_wszBuffer[0]);
//varibles for options
DWORD g_dwAction=0;
DWORD g_dwItem=0;
LPWSTR g_wszCertEncodingType=NULL;
DWORD g_dwCertEncodingType = X509_ASN_ENCODING;
DWORD g_dwMsgEncodingType = PKCS_7_ASN_ENCODING;
DWORD g_dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
BOOL g_fSaveAs7 = FALSE;
LPWSTR g_wszCertCN = NULL;
LPWSTR g_wszSha1Hash = NULL;
BYTE *g_pbHash=NULL;
DWORD g_cbHash=0;
BOOL g_fAll=FALSE;
HCRYPTMSG g_hMsg=NULL;
LPWSTR g_wszEKU=NULL;
LPWSTR g_wszName=NULL;
BOOL g_fMulti=FALSE;
BOOL g_fUndocumented=FALSE;
BOOL g_fSrcSystemStore = FALSE;
LPWSTR g_wszSrcStoreLocation=NULL;
DWORD g_dwSrcStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
LPWSTR g_wszSrcStoreName=NULL;
BOOL g_fSameSrcDes=FALSE;
BOOL g_fDesSystemStore = FALSE;
LPWSTR g_wszDesStoreLocation=NULL;
DWORD g_dwDesStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
LPWSTR g_wszDesStoreName=NULL;
LPWSTR g_wszSrcStoreProvider = NULL;
LPSTR g_szSrcStoreProvider = NULL;
LPWSTR g_wszSrcStoreOpenFlag = NULL;
DWORD g_dwSrcStoreOpenFlag = 0;
LPWSTR g_wszDesStoreProvider = NULL;
LPSTR g_szDesStoreProvider = NULL;
LPWSTR g_wszDesStoreOpenFlag = NULL;
DWORD g_dwDesStoreOpenFlag = 0;
CHAR g_szNULL[OPTION_SWITCH_SIZE];
WCHAR g_wszSHA1[OPTION_SWITCH_SIZE];
WCHAR g_wszMD5[OPTION_SWITCH_SIZE];
WCHAR g_wszUnKnown[OPTION_SWITCH_SIZE*2];
//---------------------------------------------------------------------------
// wmain
//
//---------------------------------------------------------------------------
extern "C" int __cdecl wmain(int argc, WCHAR *wargv[])
{
int ReturnStatus=-1;
//variables for parse the options
WCHAR *pwChar;
WCHAR wszSwitch1[OPTION_SWITCH_SIZE];
WCHAR wszSwitch2[OPTION_SWITCH_SIZE];
HCERTSTORE hCertStore=NULL;
CRYPTUI_CERT_MGR_STRUCT CertMgrStruct;
//get the module handler
if(!InitModule())
goto ErrorReturn;
//load the strings necessary for parsing the parameters
if( !LoadStringU(hModule, IDS_SWITCH1, wszSwitch1, OPTION_SWITCH_SIZE)
||!LoadStringU(hModule, IDS_SWITCH2, wszSwitch2, OPTION_SWITCH_SIZE)
//<NULL>
||!LoadStringA(hModule, IDS_NULL, g_szNULL, OPTION_SWITCH_SIZE)
||!LoadStringU(hModule, IDS_SHA1, g_wszSHA1, OPTION_SWITCH_SIZE)
||!LoadStringU(hModule, IDS_MD5, g_wszMD5, OPTION_SWITCH_SIZE)
//<UNKNOWN OID>
||!LoadStringU(hModule, IDS_UNKNOWN, g_wszUnKnown, OPTION_SWITCH_SIZE*2))
goto ErrorReturn;
//call the UI versino of certmgr if no parameter is passed
//memset
if(1== argc)
{
memset(&CertMgrStruct, 0, sizeof(CRYPTUI_CERT_MGR_STRUCT));
CertMgrStruct.dwSize=sizeof(CRYPTUI_CERT_MGR_STRUCT);
CryptUIDlgCertMgr(&CertMgrStruct);
ReturnStatus = 0;
IDSwprintf(hModule, IDS_SUCCEEDED);
goto CommonReturn;
}
//parse the parameters
while (--argc)
{
pwChar = *++wargv;
if (*pwChar == *wszSwitch1 || *pwChar == *wszSwitch2)
{
//parse the options
if(!ParseSwitch (&argc, &wargv))
{
if(TRUE==g_fUndocumented)
goto UndocReturn;
else
goto UsageReturn;
}
}
else
{
//set the source file name
if(NULL==g_wszSrcStoreName)
g_wszSrcStoreName=pwChar;
else
{
//set the destination file name
if(!SetParam(&g_wszDesStoreName, pwChar))
goto UsageReturn;
}
}
}
//check the parameters. Make sure that they are valid and make sense
if(!CheckParameter())
goto UsageReturn;
//open the destination store, which includes all the CERTS, CRTs, and CTLs
if(!OpenGenericStore(g_wszSrcStoreName,
g_fSrcSystemStore,
g_dwSrcStoreFlag,
g_szSrcStoreProvider,
g_dwSrcStoreOpenFlag,
TRUE,
&hCertStore))
{
IDSwprintf(hModule,IDS_ERR_OPEN_SOURCE_STORE);
goto ErrorReturn;
}
//error if we opened a signed file and there is a delete option with on destination
if(g_hMsg)
{
if(g_dwAction & ACTION_DELETE)
{
if(g_fSameSrcDes)
{
IDSwprintf(hModule, IDS_ERR_DELETE_SIGNED_FILE);
goto ErrorReturn;
}
}
}
//Display
if(g_dwAction & ACTION_DISPLAY)
{
//if the msg is signed, disply the signer info
if(g_hMsg)
{
if(!DisplaySignerInfo(g_hMsg, g_dwItem))
goto ErrorReturn;
}
if(!DisplayCertStore(hCertStore))
goto ErrorReturn;
IDSwprintf(hModule, IDS_SEPERATOR);
}
//Delete
if(g_dwAction & ACTION_DELETE)
{
if(!DeleteCertStore(hCertStore))
goto ErrorReturn;
}
//Add
if(g_dwAction & ACTION_ADD)
{
if(!AddCertStore(hCertStore))
goto ErrorReturn;
}
if(g_dwAction & ACTION_PUT)
{
if(!PutCertStore(hCertStore))
goto ErrorReturn;
}
//mark succeed
ReturnStatus = 0;
IDSwprintf(hModule, IDS_SUCCEEDED);
goto CommonReturn;
UndocReturn:
//print out the undocuemted Usage
UndocumentedUsage();
goto CommonReturn;
//print out the Usage.
UsageReturn:
Usage();
goto CommonReturn;
ErrorReturn:
//print out an error msg
IDSwprintf(hModule, IDS_FAILED);
goto CommonReturn;
CommonReturn:
//clean up memory. Return the status
if(g_szSrcStoreProvider)
ToolUtlFree(g_szSrcStoreProvider);
if(g_szDesStoreProvider)
ToolUtlFree(g_szDesStoreProvider);
if(g_pbHash)
ToolUtlFree(g_pbHash);
if(g_hMsg)
CryptMsgClose(g_hMsg);
if(hCertStore)
CertCloseStore(hCertStore, 0);
return ReturnStatus;
}
//---------------------------------------------------------------------------
// The private version of wcscat
//----------------------------------------------------------------------------
wchar_t *IDSwcscat(HMODULE hModule, WCHAR *pwsz, int idsString)
{
//load the string
if(!LoadStringU(hModule, idsString, g_wszBuffer, g_dwBufferSize))
return pwsz;
return wcscat(pwsz, g_wszBuffer);
}
//---------------------------------------------------------------------------
// Get the hModule hanlder and init two DLLMain.
//
//---------------------------------------------------------------------------
BOOL InitModule()
{
WCHAR wszOIDName[MAX_STRING_RSC_SIZE];
DWORD dwIndex=0;
CRYPT_OID_INFO OIDInfo;
if(!(hModule=GetModuleHandle(NULL)))
return FALSE;
//We do not need to do the following any more.
//the oid information are now in the OID database
//now, we are installing the format the extensions :
//BASICCONTRAINTS2
if (NULL == (hFormatFuncSet = CryptInitOIDFunctionSet(
CRYPT_OID_FORMAT_OBJECT_FUNC,
0))) // dwFlags
{
IDSwprintf(hModule, IDS_ERR_INIT_OID_SET);
return FALSE;
}
//install the default formatting routine
if (!CryptInstallOIDFunctionAddress(
NULL, // hModule
g_dwCertEncodingType,
CRYPT_OID_FORMAT_OBJECT_FUNC,
g_dwFormatCount,
g_FormatTable,
0)) // dwFlags
{
IDSwprintf(hModule, IDS_ERR_INSTALL_OID);
return FALSE;
}
//secondly, we install the OID information
//init OIDInfo
/* memset(&OIDInfo, 0, sizeof(CRYPT_OID_INFO));
OIDInfo.cbSize=sizeof(CRYPT_OID_INFO);
OIDInfo.dwGroupId=CRYPT_EXT_OR_ATTR_OID_GROUP_ID;
for(dwIndex=0; dwIndex < g_dwOIDInfo; dwIndex++)
{
if(!LoadStringU(hModule, g_rgOIDInfo[dwIndex].idsOIDName,
wszOIDName, MAX_STRING_RSC_SIZE))
return FALSE;
OIDInfo.pszOID=g_rgOIDInfo[dwIndex].pszOID;
OIDInfo.pwszName=wszOIDName;
CryptRegisterOIDInfo(&OIDInfo,0);
} */
return TRUE;
}
//---------------------------------------------------------------------------
// Usage
//
//---------------------------------------------------------------------------
void Usage(void)
{
IDSwprintf(hModule,IDS_SYNTAX);
IDSwprintf(hModule,IDS_SYNTAX1);
IDSwprintf(hModule,IDS_OPTIONS);
IDSwprintf(hModule,IDS_OPTION_ADD_DESC);
IDSwprintf(hModule,IDS_OPTION_DEL_DESC);
IDSwprintf(hModule,IDS_OPTION_DEL_DESC1);
IDSwprintf(hModule,IDS_OPTION_PUT_DESC);
IDSwprintf(hModule,IDS_OPTION_PUT_DESC1);
IDSwprintf(hModule,IDS_OPTION_PUT_DESC2);
IDSwprintf(hModule,IDS_OPTION_S_DESC);
IDSwprintf(hModule,IDS_OPTION_R_DESC);
IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE,IDS_R_CU,IDS_R_LM,IDS_R_CU);
IDSwprintf(hModule,IDS_OPTION_C_DESC);
IDSwprintf(hModule,IDS_OPTION_CRL_DESC);
IDSwprintf(hModule,IDS_OPTION_CTL_DESC);
IDSwprintf(hModule,IDS_OPTION_V_DESC);
IDSwprintf(hModule,IDS_OPTION_ALL_DESC);
IDSwprintf(hModule,IDS_OPTION_N_DESC);
IDSwprintf(hModule,IDS_OPTION_SHA1_DESC);
IDSwprintf(hModule,IDS_OPTION_7_DESC);
IDSwprintf(hModule,IDS_OPTION_E_DESC);
IDSwprintf(hModule,IDS_OPTION_E_DESC1);
IDSwprintf(hModule,IDS_OPTION_F_DESC);
IDSwprintf(hModule,IDS_OPTION_Y_DESC);
}
//---------------------------------------------------------------------------
//
// Usage
//
//---------------------------------------------------------------------------
void UndocumentedUsage()
{
IDSwprintf(hModule, IDS_SYNTAX);
IDSwprintf(hModule, IDS_OPTIONS);
IDSwprintf(hModule, IDS_OPTION_EKU_DESC);
IDSwprintf(hModule, IDS_OPTION_NAME_DESC);
IDSwprintf(hModule, IDS_OPTION_MULTI_DESC);
}
//--------------------------------------------------------------------------------
// Parse arguements
//--------------------------------------------------------------------------------
BOOL
ParseSwitch (int *pArgc,
WCHAR **pArgv[])
{
WCHAR* param = **pArgv;
//move pass '/' or '-'
param++;
if (IDSwcsicmp(hModule, param, IDS_OPTION_ADD)==0) {
g_dwAction |= ACTION_ADD;
return TRUE;
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_DEL)==0) {
g_dwAction |= ACTION_DELETE;
return TRUE;
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_PUT)==0) {
g_dwAction |= ACTION_PUT;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_S)==0) {
if(NULL==g_wszSrcStoreName)
g_fSrcSystemStore=TRUE;
else
g_fDesSystemStore=TRUE;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_R)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
if(NULL==g_wszSrcStoreName)
return SetParam(&g_wszSrcStoreLocation, **pArgv);
else
return SetParam(&g_wszDesStoreLocation, **pArgv);
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_C)==0) {
g_dwItem |= ITEM_CERT;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_CRL)==0) {
g_dwItem |= ITEM_CRL;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_CTL)==0) {
g_dwItem |= ITEM_CTL;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_V)==0) {
g_dwItem |= ITEM_VERBOSE;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_ALL)==0) {
g_fAll=TRUE;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_N)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
return SetParam(&g_wszCertCN, **pArgv);
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_SHA1)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
return SetParam(&g_wszSha1Hash, **pArgv);
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_7)==0) {
g_fSaveAs7=TRUE;
return TRUE;
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_E)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
return SetParam(&g_wszCertEncodingType, **pArgv);
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_Y)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
if(NULL==g_wszSrcStoreName)
return SetParam(&g_wszSrcStoreProvider, **pArgv);
else
return SetParam(&g_wszDesStoreProvider, **pArgv);
}
else if(IDSwcsicmp(hModule,param, IDS_OPTION_F)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
if(NULL==g_wszSrcStoreName)
return SetParam(&g_wszSrcStoreOpenFlag, **pArgv);
else
return SetParam(&g_wszDesStoreOpenFlag, **pArgv);
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_EKU)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
return SetParam(&g_wszEKU, **pArgv);
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_NAME)==0) {
if (!--(*pArgc))
return FALSE;
(*pArgv)++;
return SetParam(&g_wszName, **pArgv);
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_MULTI)==0) {
g_fMulti=TRUE;
return TRUE;
}
else if(IDSwcsicmp(hModule, param, IDS_OPTION_TEST)==0) {
g_fUndocumented=TRUE;
return FALSE;
}
return FALSE;
}
//-----------------------------------------------------------------------------
// Check the parameters
//
//-----------------------------------------------------------------------------
BOOL CheckParameter()
{
DWORD dwItemCount=0;
//check actions
if((g_dwAction & ACTION_ADD) && (g_dwAction & ACTION_DELETE))
{
IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
return FALSE;
}
if((g_dwAction & ACTION_ADD) && (g_dwAction & ACTION_PUT))
{
IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
return FALSE;
}
if((g_dwAction & ACTION_PUT) && (g_dwAction & ACTION_DELETE))
{
IDSwprintf(hModule, IDS_ERR_SINGLE_ACTION);
return FALSE;
}
if(0==g_dwAction)
g_dwAction |= ACTION_DISPLAY;
//-7 and -CTL can not be set at the same time for add or put
if(TRUE==g_fSaveAs7)
{
if(g_dwItem & ITEM_CTL)
{
if((g_dwAction & ACTION_ADD) || (g_dwAction & ACTION_PUT))
{
IDSwprintf(hModule, IDS_ERR_7_CTL);
IDSwprintf(hModule, IDS_ERR_7_CTL1);
return FALSE;
}
}
}
//-n and -sha1 can not be set at the same time
if(g_wszCertCN && g_wszSha1Hash)
{
IDSwprintf(hModule, IDS_ERR_N_SHA1);
return FALSE;
}
//-all can not be set with -n and -sha1 option
if(TRUE==g_fAll)
{
if(g_wszCertCN || g_wszSha1Hash)
{
IDSwprintf(hModule, IDS_ERR_ALL_N_SHA1);
return FALSE;
}
}
//-y, -f can not be set with -s and -r for source
if(g_wszSrcStoreProvider || g_wszSrcStoreOpenFlag)
{
if((TRUE==g_fSrcSystemStore)||(g_wszSrcStoreLocation))
{
IDSwprintf(hModule, IDS_ERR_PROVIDER_SYSTEM);
return FALSE;
}
}
//-y, -f can not be set with -s and -r for desitnation
if(g_wszDesStoreProvider || g_wszDesStoreOpenFlag)
{
if((TRUE==g_fDesSystemStore)||(g_wszDesStoreLocation))
{
IDSwprintf(hModule, IDS_ERR_PROVIDER_SYSTEM);
return FALSE;
}
}
//source store has to be set
if(NULL==g_wszSrcStoreName)
{
IDSwprintf(hModule, IDS_ERR_SOURCE_STORE);
return FALSE;
}
//get the source store Provider
if(g_wszSrcStoreProvider)
{
if(S_OK != WSZtoSZ(g_wszSrcStoreProvider, &g_szSrcStoreProvider))
{
IDSwprintf(hModule, IDS_ERR_STORE_PROVIDER);
return FALSE;
}
}
//get the source store open flag
if(g_wszSrcStoreOpenFlag)
{
g_dwSrcStoreOpenFlag = _wtol(g_wszSrcStoreOpenFlag);
}
//get the destination store Provider
if(g_wszDesStoreProvider)
{
if(S_OK != WSZtoSZ(g_wszDesStoreProvider, &g_szDesStoreProvider))
{
IDSwprintf(hModule, IDS_ERR_STORE_PROVIDER);
return FALSE;
}
}
//get the destination store open flag
if(g_wszDesStoreOpenFlag)
{
g_dwDesStoreOpenFlag = _wtol(g_wszDesStoreOpenFlag);
}
//get the encoding type
if(g_wszCertEncodingType)
{
g_dwCertEncodingType = _wtol(g_wszCertEncodingType);
}
g_dwMsgAndCertEncodingType |= g_dwCertEncodingType;
//get the source store location
if(g_wszSrcStoreLocation)
{
if(IDSwcsicmp(hModule,g_wszSrcStoreLocation, IDS_R_CU) == 0)
g_dwSrcStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
else
{
if(IDSwcsicmp(hModule,g_wszSrcStoreLocation, IDS_R_LM) == 0)
g_dwSrcStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
else
{
IDSwprintf(hModule,IDS_ERR_NO_REG);
return FALSE;
}
}
}
//get the destincation store location
if(g_wszDesStoreLocation)
{
if(IDSwcsicmp(hModule,g_wszDesStoreLocation, IDS_R_CU) == 0)
g_dwDesStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
else
{
if(IDSwcsicmp(hModule,g_wszDesStoreLocation, IDS_R_LM) == 0)
g_dwDesStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
else
{
IDSwprintf(hModule,IDS_ERR_NO_REG);
return FALSE;
}
}
}
//get the hash
if(g_wszSha1Hash)
{
if(S_OK != WSZtoBLOB(g_wszSha1Hash, &g_pbHash, &g_cbHash))
{
//sha1 hash is invalid
IDSwprintf(hModule, IDS_ERR_SHA1_HASH);
return FALSE;
}
}
//check the item
if(g_dwAction & ACTION_DISPLAY)
{
if(0==g_dwItem || ITEM_VERBOSE==g_dwItem)
g_dwItem = g_dwItem | ITEM_CERT | ITEM_CTL | ITEM_CRL;
//can not set destination source
if((g_wszDesStoreLocation) || (g_fDesSystemStore==TRUE) ||
(g_wszCertCN) || (g_wszSha1Hash) || (g_fSaveAs7==TRUE) ||
(g_wszDesStoreName) ||(g_wszDesStoreProvider) ||(g_wszDesStoreOpenFlag))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY_TOO_MANY);
return FALSE;
}
}
//-eku can not be set for DISPLAY or PUT
if((g_dwAction & ACTION_DISPLAY) || (g_dwAction & ACTION_PUT))
{
//can not set -eku option
if(g_wszEKU || g_wszName)
{
IDSwprintf(hModule, IDS_ERR_DISPLAY_EKU);
return FALSE;
}
}
if(g_dwAction & ACTION_PUT)
{
//g_fAll can not be set,
if(TRUE==g_fAll)
{
IDSwprintf(hModule, IDS_ERR_ALL_PUT);
return FALSE;
}
//only one item can not set
dwItemCount=0;
if(g_dwItem & ITEM_CERT)
dwItemCount++;
if(g_dwItem & ITEM_CTL)
dwItemCount++;
if(g_dwItem & ITEM_CRL)
dwItemCount++;
if(1!=dwItemCount)
{
IDSwprintf(hModule, IDS_ERR_PUT_ITEM);
return FALSE;
}
//check the destination store
if(NULL == g_wszDesStoreName)
{
IDSwprintf(hModule,IDS_ERR_DES_STORE);
return FALSE;
}
//can not set -s, -y, -f, or -r for the destination store
if((g_fDesSystemStore==TRUE) || (g_wszDesStoreLocation) ||
(g_wszDesStoreProvider) || (g_wszDesStoreOpenFlag))
{
IDSwprintf(hModule,IDS_TOO_MANY_DES_STORE);
return FALSE;
}
}
if((g_dwAction & ACTION_ADD) ||
(g_dwAction & ACTION_DELETE))
{
//if g_fAll is set, OK
if(TRUE==g_fAll)
{
if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem )
g_dwItem = g_dwItem | ITEM_CERT | ITEM_CTL | ITEM_CRL;
}
//check the destination store
if(NULL == g_wszDesStoreName)
{
if(g_dwAction & ACTION_ADD)
{
IDSwprintf(hModule,IDS_ERR_DES_STORE);
return FALSE;
}
g_fSameSrcDes=TRUE;
//can not have set -s, -y, -f or -r if the store name is not set
if((g_fDesSystemStore==TRUE) || (g_wszDesStoreLocation) ||
(g_wszDesStoreProvider) || (g_wszDesStoreOpenFlag))
{
IDSwprintf(hModule,IDS_ERR_DES_STORE);
return FALSE;
}
g_wszDesStoreName=g_wszSrcStoreName;
g_dwDesStoreFlag=g_dwSrcStoreFlag;
g_fDesSystemStore=g_fSrcSystemStore;
g_szDesStoreProvider=g_szSrcStoreProvider;
g_dwDesStoreOpenFlag=g_dwSrcStoreOpenFlag;
}
//if -7 is set, can not save to a system store
if(TRUE==g_fSaveAs7)
{
if(TRUE==g_fDesSystemStore)
{
IDSwprintf(hModule,IDS_ERR_SOURCE_SYSTEM_7);
return FALSE;
}
}
}
return TRUE;
}
//------------------------------------------------------------------------------------
//
// Open a store. The order of trying is following:
//
// Using predefined store provider
// SystemStore
// CTL
// CRL
// Serialized Store, PKCS#7, Encoded Cert
// PKCS7 via sip
// Base64 encoded, then go throught the whole thing again
//
//
//------------------------------------------------------------------------------------
BOOL OpenGenericStore(LPWSTR wszStoreName,
BOOL fSystemStore,
DWORD dwStoreFlag,
LPSTR szStoreProvider,
DWORD dwStoreOpenFlag,
BOOL fCheckExist,
HCERTSTORE *phCertStore)
{
HCERTSTORE hStore=NULL;
BYTE *pbByte=NULL;
DWORD cbByte=0;
CRYPT_DATA_BLOB Blob;
if(!wszStoreName || !phCertStore)
return FALSE;
//open the store using supplied store provider
if(szStoreProvider)
{
hStore=CertOpenStore(szStoreProvider,
g_dwMsgAndCertEncodingType,
NULL,
dwStoreOpenFlag,
wszStoreName);
//one shot and we are done
goto CLEANUP;
}
//open the system store
if(fSystemStore)
{
if(TRUE==fCheckExist)
{
//open Read Only stores
hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwStoreFlag |CERT_STORE_READONLY_FLAG,
wszStoreName);
//we need to open the store as non-readonly if the store exists
//and we the source store is the same as destination store
if(NULL!=hStore)
{
if(TRUE==g_fSameSrcDes)
{
CertCloseStore(hStore, 0);
hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwStoreFlag,
wszStoreName);
}
}
}
else
{
hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwStoreFlag,
wszStoreName);
}
//one shot and we are done
goto CLEANUP;
}
//open an encoded CTL
hStore=OpenEncodedCTL(wszStoreName);
if(hStore)
{
//mark this is a CTL
if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
g_dwItem |= ITEM_CTL;
goto CLEANUP;
}
//open an encoded CRL
hStore=OpenEncodedCRL(wszStoreName);
if(hStore)
{
//mark this is a CRL
if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
g_dwItem |= ITEM_CRL;
goto CLEANUP;
}
//open an encoded Cert
hStore=OpenEncodedCert(wszStoreName);
if(hStore)
{
//mark this is a CERT
if((0==g_dwItem) || (ITEM_VERBOSE==g_dwItem))
g_dwItem |= ITEM_CERT;
goto CLEANUP;
}
//Serialized Store, PKCS#7, Encoded Cert
hStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
g_dwMsgAndCertEncodingType,
NULL,
0,
wszStoreName);
if(hStore)
goto CLEANUP;
//PKCS7 via SIP
hStore=OpenSipStore(wszStoreName);
if(hStore)
goto CLEANUP;
//base64 encoded
if(!GetBase64Decoded(wszStoreName, &pbByte,&cbByte))
goto CLEANUP;
Blob.cbData=cbByte;
Blob.pbData=pbByte;
//open a temporary memory store
hStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
g_dwMsgAndCertEncodingType,
NULL,
0,
NULL);
if(!hStore)
goto CLEANUP;
//try as encodedCTL
if(CertAddEncodedCTLToStore(hStore,
g_dwMsgAndCertEncodingType,
pbByte,
cbByte,
CERT_STORE_ADD_ALWAYS,
NULL))
goto CLEANUP;
//try as encodedCRL
if(CertAddEncodedCRLToStore(hStore,
g_dwMsgAndCertEncodingType,
pbByte,
cbByte,
CERT_STORE_ADD_ALWAYS,
NULL))
goto CLEANUP;
//try as encodedCert
if(CertAddEncodedCertificateToStore(hStore,
g_dwMsgAndCertEncodingType,
pbByte,
cbByte,
CERT_STORE_ADD_ALWAYS,
NULL))
goto CLEANUP;
//close the temporary store
CertCloseStore(hStore, 0);
hStore=NULL;
//try as an 7
hStore=CertOpenStore(CERT_STORE_PROV_PKCS7,
g_dwMsgAndCertEncodingType,
NULL,
0,
&Blob);
if(hStore)
goto CLEANUP;
//try as a serialized store
hStore=CertOpenStore(CERT_STORE_PROV_SERIALIZED,
g_dwMsgAndCertEncodingType,
NULL,
0,
&Blob);
//now we give up
CLEANUP:
//free memory
if(pbByte)
ToolUtlFree(pbByte);
if(hStore)
{
*phCertStore=hStore;
return TRUE;
}
return FALSE;
}
//-------------------------------------------------------------------------
//
// Add certs/CTLs/CRLs from the source store to the destination store
//
//-------------------------------------------------------------------------
BOOL AddCertStore(HCERTSTORE hCertStore)
{
BOOL fResult=FALSE;
HCERTSTORE hAddStore=NULL;
int idsErr=0;
CRYPT_HASH_BLOB Blob;
DWORD dwIndex=0;
PCCERT_CONTEXT pCertContext=NULL;
DWORD dwCertCount=0;
PCCERT_CONTEXT *rgpCertContext=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
DWORD dwCRLCount=0;
PCCRL_CONTEXT *rgpCRLContext=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
DWORD dwCTLCount=0;
PCCTL_CONTEXT *rgpCTLContext=NULL;
//User has to specify the item to delete
if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
{
IDSwprintf(hModule,IDS_ERR_C_CTL_CTL_ALL);
return FALSE;
}
//create a temporaray memory store
hAddStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
g_dwMsgAndCertEncodingType,
NULL,
0,
NULL);
if(!hAddStore)
{
idsErr=IDS_ERR_TMP_STORE;
goto CLEANUP;
}
//add certs
if(g_dwItem & ITEM_CERT)
{
//add all
if(g_fAll)
{
if(!MoveItem(hCertStore, hAddStore,ITEM_CERT))
{
idsErr=IDS_ERR_ADD_CERT_ALL;
goto CLEANUP;
}
}
else
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
//search for the certificate
pCertContext=CertFindCertificateInStore(
hCertStore,
g_dwCertEncodingType,
0,
CERT_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCertContext)
{
idsErr=IDS_ERR_NO_CERT_HASH;
goto CLEANUP;
}
//add certificate to the hash
if(!CertAddCertificateContextToStore(hAddStore,
pCertContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CERT;
goto CLEANUP;
}
//free the pCertContext
CertFreeCertificateContext(pCertContext);
pCertContext=NULL;
}
else
{
if(g_wszCertCN)
{
//search for the certificate
if(!BuildCertList(hCertStore, g_wszCertCN,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
}
else
{
//search for the certificate
if(!BuildCertList(hCertStore, NULL,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
}
//check if there is no certs
if(0==dwCertCount && g_wszCertCN)
{
idsErr=IDS_ERR_ADD_NO_CERT;
goto CLEANUP;
}
//check if there is only one cert
if(1==dwCertCount)
{
//add certificate
if(!CertAddCertificateContextToStore(hAddStore,
rgpCertContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CERT;
goto CLEANUP;
}
}
else
{
if(dwCertCount>1)
{
//promt user for the index number to add
if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
{
idsErr=IDS_ERR_ADD_CERT;
goto CLEANUP;
}
//add certificate
if(!CertAddCertificateContextToStore(hAddStore,
rgpCertContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CERT;
goto CLEANUP;
}
}
}
}
}
}
//add CRLs
if(g_dwItem & ITEM_CRL)
{
//add all
if(g_fAll)
{
if(!MoveItem(hCertStore, hAddStore,ITEM_CRL))
{
idsErr=IDS_ERR_ADD_CRL_ALL;
goto CLEANUP;
}
}
else
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCRLContext=FindCRLInStore(
hCertStore,
&Blob);
if(!pCRLContext)
{
idsErr=IDS_ERR_NO_CRL_HASH;
goto CLEANUP;
}
//add CRL to the hash
if(!CertAddCRLContextToStore(hAddStore,
pCRLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CRL;
goto CLEANUP;
}
//free the pCRLContext
CertFreeCRLContext(pCRLContext);
pCRLContext=NULL;
}
else
{
//search for the CRL
if(!BuildCRLList(hCertStore, &rgpCRLContext, &dwCRLCount))
{
idsErr=IDS_ERR_CRL_FIND;
goto CLEANUP;
}
//check if there is only one CRL
if(1==dwCRLCount)
{
//add CRL
if(!CertAddCRLContextToStore(hAddStore,
rgpCRLContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CRL;
goto CLEANUP;
}
}
else
{
if(dwCRLCount>1)
{
//promt user for the index number to add
if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
{
idsErr=IDS_ERR_ADD_CRL;
goto CLEANUP;
}
//add certificate
if(!CertAddCRLContextToStore(hAddStore,
rgpCRLContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CRL;
goto CLEANUP;
}
}
}
}
}
}
//add CTLs
if(g_dwItem & ITEM_CTL)
{
//add all
if(g_fAll)
{
if(!MoveItem(hCertStore, hAddStore,ITEM_CTL))
{
idsErr=IDS_ERR_ADD_CTL_ALL;
goto CLEANUP;
}
}
else
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCTLContext=CertFindCTLInStore(
hCertStore,
g_dwMsgAndCertEncodingType,
0,
CTL_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCTLContext)
{
idsErr=IDS_ERR_NO_CTL_HASH;
goto CLEANUP;
}
//add CTL to the hash
if(!CertAddCTLContextToStore(hAddStore,
pCTLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CTL;
goto CLEANUP;
}
//free the pCRLContext
CertFreeCTLContext(pCTLContext);
pCTLContext=NULL;
}
else
{
//search for the certificate
if(!BuildCTLList(hCertStore,&rgpCTLContext, &dwCTLCount))
{
idsErr=IDS_ERR_CTL_FIND;
goto CLEANUP;
}
//check if there is only one item
if(1==dwCTLCount)
{
//add CRL
if(!CertAddCTLContextToStore(hAddStore,
rgpCTLContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CTL;
goto CLEANUP;
}
}
else
{
if(dwCTLCount>1)
{
//promt user for the index number to add
if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
{
idsErr=IDS_ERR_ADD_CTL;
goto CLEANUP;
}
//add certificate
if(!CertAddCTLContextToStore(hAddStore,
rgpCTLContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_ADD_CTL;
goto CLEANUP;
}
}
}
}
}
}
//save the properties to the certificates in the store
if(g_wszEKU)
{
if(!SetEKUProperty(hAddStore))
{
idsErr=IDS_ERR_SET_EKU;
goto CLEANUP;
}
}
//save the properties to the certificates in the store
if(g_wszName)
{
if(!SetNameProperty(hAddStore))
{
idsErr=IDS_ERR_SET_NAME;
goto CLEANUP;
}
}
//save the hAddStore to the destination store
if(!SaveStore(hAddStore))
goto CLEANUP;
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(rgpCertContext)
{
for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
CertFreeCertificateContext(rgpCertContext[dwIndex]);
free(rgpCertContext);
}
if(rgpCRLContext)
{
for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
CertFreeCRLContext(rgpCRLContext[dwIndex]);
free(rgpCRLContext);
}
if(rgpCTLContext)
{
for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
CertFreeCTLContext(rgpCTLContext[dwIndex]);
free(rgpCTLContext);
}
if(hAddStore)
CertCloseStore(hAddStore, 0);
if(FALSE==fResult)
{
//output the error message
IDSwprintf(hModule,idsErr);
}
return fResult;
}
//-------------------------------------------------------------------------
//
// Put certs/CTLs/CRLs from the source store to the destination store
//
//-------------------------------------------------------------------------
BOOL PutCertStore(HCERTSTORE hCertStore)
{
BOOL fResult=FALSE;
HCERTSTORE hPutStore=NULL;
int idsErr=0;
CRYPT_HASH_BLOB Blob;
DWORD dwIndex=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPut=NULL;
DWORD dwCertCount=0;
PCCERT_CONTEXT *rgpCertContext=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPut=NULL;
DWORD dwCRLCount=0;
PCCRL_CONTEXT *rgpCRLContext=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPut=NULL;
DWORD dwCTLCount=0;
PCCTL_CONTEXT *rgpCTLContext=NULL;
BYTE *pByte=NULL;
DWORD cbByte=0;
DWORD dwCRLFlag=0;
//User has to specify the item to delete
if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
{
IDSwprintf(hModule,IDS_ERR_PUT_ITEM);
return FALSE;
}
//create a temporaray memory store
hPutStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
g_dwMsgAndCertEncodingType,
NULL,
0,
NULL);
if(!hPutStore)
{
idsErr=IDS_ERR_TMP_STORE;
goto CLEANUP;
}
//put certs
if(g_dwItem & ITEM_CERT)
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
//search for the certificate
pCertContext=CertFindCertificateInStore(
hCertStore,
g_dwCertEncodingType,
0,
CERT_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCertContext)
{
idsErr=IDS_ERR_NO_CERT_HASH;
goto CLEANUP;
}
//add certificate to the hash
if(!CertAddCertificateContextToStore(hPutStore,
pCertContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CERT;
goto CLEANUP;
}
//free the pCertContext
CertFreeCertificateContext(pCertContext);
pCertContext=NULL;
}
else
{
if(g_wszCertCN)
{
//search for the certificate
if(!BuildCertList(hCertStore, g_wszCertCN,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
}
else
{
//search for the certificate
if(!BuildCertList(hCertStore, NULL,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_PUT_NO_CERT;
goto CLEANUP;
}
}
//check if there is no certs
if(0==dwCertCount)
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
//check if there is only one cert
if(1==dwCertCount)
{
//add certificate
if(!CertAddCertificateContextToStore(hPutStore,
rgpCertContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CERT;
goto CLEANUP;
}
}
else
{
if(dwCertCount>1)
{
//promt user for the index number to add
if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
{
idsErr=IDS_ERR_PUT_CERT;
goto CLEANUP;
}
//add certificate
if(!CertAddCertificateContextToStore(hPutStore,
rgpCertContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CERT;
goto CLEANUP;
}
}
}
}
}
//add CRLs
if(g_dwItem & ITEM_CRL)
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCRLContext=FindCRLInStore(
hCertStore,
&Blob);
if(!pCRLContext)
{
idsErr=IDS_ERR_NO_CRL_HASH;
goto CLEANUP;
}
//add CRL to the hash
if(!CertAddCRLContextToStore(hPutStore,
pCRLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CRL;
goto CLEANUP;
}
//free the pCRLContext
CertFreeCRLContext(pCRLContext);
pCRLContext=NULL;
}
else
{
//search for the CRL
if(!BuildCRLList(hCertStore, &rgpCRLContext, &dwCRLCount))
{
idsErr=IDS_ERR_PUT_CRL_FIND;
goto CLEANUP;
}
//check if there is no certs
if(0==dwCRLCount)
{
idsErr=IDS_ERR_PUT_CRL_FIND;
goto CLEANUP;
}
//check if there is only one CRL
if(1==dwCRLCount)
{
//add CRL
if(!CertAddCRLContextToStore(hPutStore,
rgpCRLContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CRL;
goto CLEANUP;
}
}
else
{
if(dwCRLCount>1)
{
//promt user for the index number to add
if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
{
idsErr=IDS_ERR_PUT_CRL;
goto CLEANUP;
}
//add certificate
if(!CertAddCRLContextToStore(hPutStore,
rgpCRLContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CRL;
goto CLEANUP;
}
}
}
}
}
//add CTLs
if(g_dwItem & ITEM_CTL)
{
//add based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCTLContext=CertFindCTLInStore(
hCertStore,
g_dwMsgAndCertEncodingType,
0,
CTL_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCTLContext)
{
idsErr=IDS_ERR_NO_CTL_HASH;
goto CLEANUP;
}
//add CTL to the hash
if(!CertAddCTLContextToStore(hPutStore,
pCTLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CTL;
goto CLEANUP;
}
//free the pCRLContext
CertFreeCTLContext(pCTLContext);
pCTLContext=NULL;
}
else
{
//search for the certificate
if(!BuildCTLList(hCertStore,&rgpCTLContext, &dwCTLCount))
{
idsErr=IDS_ERR_PUT_CTL_FIND;
goto CLEANUP;
}
//check if there is no certs
if(0==dwCTLCount)
{
idsErr=IDS_ERR_PUT_CTL_FIND;
goto CLEANUP;
}
//check if there is only one item
if(1==dwCTLCount)
{
//add CRL
if(!CertAddCTLContextToStore(hPutStore,
rgpCTLContext[0],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CTL;
goto CLEANUP;
}
}
else
{
if(dwCTLCount>1)
{
//promt user for the index number to add
if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
{
idsErr=IDS_ERR_PUT_CTL;
goto CLEANUP;
}
//add certificate
if(!CertAddCTLContextToStore(hPutStore,
rgpCTLContext[dwIndex],
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
{
idsErr=IDS_ERR_PUT_CTL;
goto CLEANUP;
}
}
}
}
}
//save the hPutStore to the destination store
//save as 7 is required
if(g_fSaveAs7==TRUE)
{
if(!CertSaveStore(hPutStore,
g_dwMsgAndCertEncodingType,
CERT_STORE_SAVE_AS_PKCS7,
CERT_STORE_SAVE_TO_FILENAME_W,
g_wszDesStoreName,
0))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
}
else
{
//get the BLOB to save to a file in X509 format
if(g_dwItem & ITEM_CERT)
{
if(NULL==(pCertPut=CertEnumCertificatesInStore(hPutStore, NULL)))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
pByte=pCertPut->pbCertEncoded;
cbByte=pCertPut->cbCertEncoded;
}
if(g_dwItem & ITEM_CRL)
{
if(NULL==(pCRLPut=CertGetCRLFromStore(hPutStore,
NULL,
NULL,
&dwCRLFlag)))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
pByte=pCRLPut->pbCrlEncoded;
cbByte=pCRLPut->cbCrlEncoded;
}
if(g_dwItem & ITEM_CTL)
{
if(NULL==(pCTLPut=CertEnumCTLsInStore(hPutStore, NULL)))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
pByte=pCTLPut->pbCtlEncoded;
cbByte=pCTLPut->cbCtlEncoded;
}
if(S_OK !=OpenAndWriteToFile(g_wszDesStoreName,pByte, cbByte))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCertPut)
CertFreeCertificateContext(pCertPut);
if(pCRLPut)
CertFreeCRLContext(pCRLPut);
if(pCTLPut)
CertFreeCTLContext(pCTLPut);
if(rgpCertContext)
{
for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
CertFreeCertificateContext(rgpCertContext[dwIndex]);
free(rgpCertContext);
}
if(rgpCRLContext)
{
for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
CertFreeCRLContext(rgpCRLContext[dwIndex]);
free(rgpCRLContext);
}
if(rgpCTLContext)
{
for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
CertFreeCTLContext(rgpCTLContext[dwIndex]);
free(rgpCTLContext);
}
if(hPutStore)
CertCloseStore(hPutStore, 0);
if(FALSE==fResult)
{
//output the error message
IDSwprintf(hModule,idsErr);
}
return fResult;
}
//-------------------------------------------------------------------------
//
// Delete certs/CTLs/CRLs from the source store to the destination store
//
//-------------------------------------------------------------------------
BOOL DeleteCertStore(HCERTSTORE hCertStore)
{
BOOL fResult=FALSE;
HCERTSTORE hDeleteStore=NULL;
BOOL fDuplicated=FALSE;
int idsErr=0;
CRYPT_HASH_BLOB Blob;
DWORD dwIndex=0;
PCCERT_CONTEXT pCertContext=NULL;
DWORD dwCertCount=0;
PCCERT_CONTEXT *rgpCertContext=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
DWORD dwCRLCount=0;
PCCRL_CONTEXT *rgpCRLContext=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
DWORD dwCTLCount=0;
PCCTL_CONTEXT *rgpCTLContext=NULL;
//User has to specify the item to delete
if(g_dwItem==0 || ITEM_VERBOSE==g_dwItem)
{
IDSwprintf(hModule,IDS_ERR_C_CTL_CTL_ALL);
return FALSE;
}
//first of all, create a certificate from which the certs will be deleted
//if the source store is a fileStore, or a system store saved to its self,
//we do not need to duplicate the source store since the deletion is not persistent;
//otherwise, we need to duplicate the source store so that the deletion
//will not show up at the source store
if( ((NULL != g_szSrcStoreProvider) &&(FALSE==g_fSameSrcDes) ) ||
((FALSE==g_fSameSrcDes) &&(TRUE==g_fSrcSystemStore)))
{
//open a temporary store
hDeleteStore=CertOpenStore(CERT_STORE_PROV_MEMORY,
g_dwMsgAndCertEncodingType,
NULL,
0,
NULL);
if(!hDeleteStore)
{
idsErr=IDS_ERR_TMP_STORE;
goto CLEANUP;
}
fDuplicated=TRUE;
//need to copy from the source to the delete store
if(!MoveItem(hCertStore, hDeleteStore, ITEM_CERT | ITEM_CTL | ITEM_CRL))
{
idsErr=IDS_ERR_COPY_FROM_SRC;
goto CLEANUP;
}
}
else
hDeleteStore=hCertStore;
//now, we delete CERTs, CTLs, and CRLs
//delete certs
if(g_dwItem & ITEM_CERT)
{
//delete all
if(g_fAll)
{
if(!DeleteItem(hDeleteStore,ITEM_CERT))
{
idsErr=IDS_ERR_DELETE_CERT_ALL;
goto CLEANUP;
}
}
else
{
//delete based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
//search for the certificate
pCertContext=CertFindCertificateInStore(
hDeleteStore,
g_dwCertEncodingType,
0,
CERT_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCertContext)
{
idsErr=IDS_ERR_NO_CERT_HASH;
goto CLEANUP;
}
//delete certificate to the hash
if(!CertDeleteCertificateFromStore(pCertContext))
{
idsErr=IDS_ERR_DELETE_CERT;
goto CLEANUP;
}
//free the pCertContext
//CertFreeCertificateContext(pCertContext);
pCertContext=NULL;
}
else
{
if(g_wszCertCN)
{
//search for the certificate
if(!BuildCertList(hDeleteStore, g_wszCertCN,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
}
else
{
//search for the certificate
if(!BuildCertList(hDeleteStore, NULL,
&rgpCertContext, &dwCertCount))
{
idsErr=IDS_ERR_CERT_FIND;
goto CLEANUP;
}
}
//check if there is no certs
if(0==dwCertCount && g_wszCertCN)
{
idsErr=IDS_ERR_DELETE_NO_CERT;
goto CLEANUP;
}
//check if there is only one cert
if(1==dwCertCount)
{
//delete certificate
CertDuplicateCertificateContext(rgpCertContext[0]);
if(!CertDeleteCertificateFromStore(rgpCertContext[0]))
{
idsErr=IDS_ERR_DELETE_CERT;
goto CLEANUP;
}
}
else
{
if(dwCertCount>1)
{
//promt user for the index number to delete
if(!DisplayCertAndPrompt(rgpCertContext, dwCertCount, &dwIndex))
{
idsErr=IDS_ERR_DELETE_CERT;
goto CLEANUP;
}
//delete certificate
CertDuplicateCertificateContext(rgpCertContext[dwIndex]);
if(!CertDeleteCertificateFromStore(rgpCertContext[dwIndex]))
{
idsErr=IDS_ERR_DELETE_CERT;
goto CLEANUP;
}
}
}
}
}
}
//delete CRLs
if(g_dwItem & ITEM_CRL)
{
//delete all
if(g_fAll)
{
if(!DeleteItem(hDeleteStore, ITEM_CRL))
{
idsErr=IDS_ERR_DELETE_CRL_ALL;
goto CLEANUP;
}
}
else
{
//delete based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCRLContext=FindCRLInStore(
hDeleteStore,
&Blob);
if(!pCRLContext)
{
idsErr=IDS_ERR_NO_CRL_HASH;
goto CLEANUP;
}
//delete CRL to the hash
if(!CertDeleteCRLFromStore(pCRLContext))
{
idsErr=IDS_ERR_DELETE_CRL;
goto CLEANUP;
}
//free the pCRLContext
//CertFreeCRLContext(pCRLContext);
pCRLContext=NULL;
}
else
{
//search for the CRL
if(!BuildCRLList(hDeleteStore, &rgpCRLContext, &dwCRLCount))
{
idsErr=IDS_ERR_CRL_FIND;
goto CLEANUP;
}
//check if there is only one CRL
if(1==dwCRLCount)
{
//delete CRL
CertDuplicateCRLContext(rgpCRLContext[0]);
if(!CertDeleteCRLFromStore(rgpCRLContext[0]))
{
idsErr=IDS_ERR_DELETE_CRL;
goto CLEANUP;
}
}
else
{
if(dwCRLCount>1)
{
//promt user for the index number to delete
if(!DisplayCRLAndPrompt(rgpCRLContext, dwCRLCount, &dwIndex))
{
idsErr=IDS_ERR_DELETE_CRL;
goto CLEANUP;
}
//delete certificate
CertDuplicateCRLContext(rgpCRLContext[dwIndex]);
if(!CertDeleteCRLFromStore(rgpCRLContext[dwIndex]))
{
idsErr=IDS_ERR_DELETE_CRL;
goto CLEANUP;
}
}
}
}
}
}
//delete CTLs
if(g_dwItem & ITEM_CTL)
{
//delete all
if(g_fAll)
{
if(!DeleteItem(hDeleteStore, ITEM_CTL))
{
idsErr=IDS_ERR_DELETE_CTL_ALL;
goto CLEANUP;
}
}
else
{
//delete based on Hash
if(g_pbHash)
{
Blob.cbData=g_cbHash;
Blob.pbData=g_pbHash;
pCTLContext=CertFindCTLInStore(
hDeleteStore,
g_dwMsgAndCertEncodingType,
0,
CTL_FIND_SHA1_HASH,
&Blob,
NULL);
if(!pCTLContext)
{
idsErr=IDS_ERR_NO_CTL_HASH;
goto CLEANUP;
}
//delete CTL to the hash
if(!CertDeleteCTLFromStore(pCTLContext))
{
idsErr=IDS_ERR_DELETE_CTL;
goto CLEANUP;
}
//free the pCRLContext
//CertFreeCTLContext(pCTLContext);
pCTLContext=NULL;
}
else
{
//search for the CTLs
if(!BuildCTLList(hDeleteStore,&rgpCTLContext, &dwCTLCount))
{
idsErr=IDS_ERR_CTL_FIND;
goto CLEANUP;
}
//check if there is only one item
if(1==dwCTLCount)
{
//delete CRL
CertDuplicateCTLContext(rgpCTLContext[0]);
if(!CertDeleteCTLFromStore(rgpCTLContext[0]))
{
idsErr=IDS_ERR_DELETE_CTL;
goto CLEANUP;
}
}
else
{
if(dwCTLCount>1)
{
//promt user for the index number to delete
if(!DisplayCTLAndPrompt(rgpCTLContext, dwCTLCount, &dwIndex))
{
idsErr=IDS_ERR_DELETE_CTL;
goto CLEANUP;
}
//delete CTL
CertDuplicateCTLContext(rgpCTLContext[dwIndex]);
if(!CertDeleteCTLFromStore(rgpCTLContext[dwIndex]))
{
idsErr=IDS_ERR_DELETE_CTL;
goto CLEANUP;
}
}
}
}
}
}
//save the properties to the certificates in the store
if(g_wszEKU)
{
if(!SetEKUProperty(hDeleteStore))
{
idsErr=IDS_ERR_SET_EKU;
goto CLEANUP;
}
}
//save the properties to the certificates in the store
if(g_wszName)
{
if(!SetNameProperty(hDeleteStore))
{
idsErr=IDS_ERR_SET_NAME;
goto CLEANUP;
}
}
//at last, we save the content for hDeleteStore to the desination store
//we do not need to do any thing if the source is a system store and
//it is saved to its self
if(((TRUE==g_fSameSrcDes) && (TRUE==g_fDesSystemStore))||
((TRUE==g_fSameSrcDes)&& (NULL!=g_szDesStoreProvider)))
{
fResult=TRUE;
goto CLEANUP;
}
if(!SaveStore(hDeleteStore))
goto CLEANUP;
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(rgpCertContext)
{
for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
CertFreeCertificateContext(rgpCertContext[dwIndex]);
free(rgpCertContext);
}
if(rgpCRLContext)
{
for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
CertFreeCRLContext(rgpCRLContext[dwIndex]);
free(rgpCRLContext);
}
if(rgpCTLContext)
{
for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
CertFreeCTLContext(rgpCTLContext[dwIndex]);
free(rgpCTLContext);
}
if((hDeleteStore) &&(TRUE==fDuplicated) )
CertCloseStore(hDeleteStore, 0);
if(FALSE==fResult)
//output the error message
IDSwprintf(hModule,idsErr);
return fResult;
}
//---------------------------------------------------------------------------
//
// Save the store to the destination
//--------------------------------------------------------------------------
BOOL SaveStore(HCERTSTORE hSrcStore)
{
BOOL fResult=FALSE;
HCERTSTORE hDesStore=NULL;
DWORD dwSaveAs=0;
if(!hSrcStore)
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
return FALSE;
}
//now, we need to distinguish between save to a file, or to a system store
if(g_fDesSystemStore || g_szDesStoreProvider)
{
if(NULL==g_szDesStoreProvider)
{
hDesStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
g_dwDesStoreFlag,
g_wszDesStoreName);
}
else
{
hDesStore=CertOpenStore(g_szDesStoreProvider,
g_dwMsgAndCertEncodingType,
NULL,
g_dwDesStoreOpenFlag,
g_wszDesStoreName);
}
if(!hDesStore)
{
IDSwprintf(hModule,IDS_ERR_OPEN_DES_STORE);
goto CLEANUP;
}
if(!MoveItem(hSrcStore, hDesStore,ITEM_CERT | ITEM_CRL |ITEM_CTL))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
}
else
{
//now, try to open the desitnation store so that the content of the destination
//store will not be overwritten
//we should try to do so, except when we are doing deleting,
//and the file is saved to its self
if(!((g_dwAction & ACTION_DELETE) && (g_fSameSrcDes==TRUE) &&
(FALSE==g_fDesSystemStore)))
{
if(OpenGenericStore(g_wszDesStoreName,
g_fDesSystemStore,
g_dwDesStoreFlag,
g_szDesStoreProvider,
g_dwDesStoreOpenFlag,
FALSE,
&hDesStore))
{
//if open succeeded, just move the items
if(!MoveItem(hSrcStore, hDesStore,ITEM_CERT | ITEM_CRL |ITEM_CTL))
{
IDSwprintf(hModule,IDS_ERR_OPEN_DES_STORE);
goto CLEANUP;
}
//now the items are moved, we need to persist them to a file. Go on.
}
//if we can not open the generic store, then the desination store
//does not exist. Go on
}
//now, we have the right store to save from
if(g_fSaveAs7==TRUE)
dwSaveAs=CERT_STORE_SAVE_AS_PKCS7;
else
dwSaveAs=CERT_STORE_SAVE_AS_STORE;
if(!CertSaveStore(hDesStore ? hDesStore : hSrcStore,
g_dwMsgAndCertEncodingType,
dwSaveAs,
CERT_STORE_SAVE_TO_FILENAME_W,
g_wszDesStoreName,
0))
{
IDSwprintf(hModule,IDS_ERR_SAVE_DES_STORE);
goto CLEANUP;
}
}
fResult=TRUE;
CLEANUP:
if(hDesStore)
CertCloseStore(hDesStore, 0);
return fResult;
}
//-------------------------------------------------------------------------
//
// Set EKU property to all the certificate in the store
//
//-------------------------------------------------------------------------
BOOL SetEKUProperty( HCERTSTORE hSrcStore)
{
BOOL fResult=FALSE;
BYTE *pbEncoded =NULL;
DWORD cbEncoded =0;
DWORD cCount;
LPSTR psz=NULL;
LPSTR pszTok=NULL;
DWORD cTok = 0;
PCERT_ENHKEY_USAGE pUsage =NULL;
CRYPT_DATA_BLOB Blob;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
if(S_OK != WSZtoSZ(g_wszEKU, &psz))
return FALSE;
// Count the number of OIDs as well as converting from comma delimited
// to NULL character delimited
pszTok = strtok(psz, ",");
while ( pszTok != NULL )
{
cTok++;
pszTok = strtok(NULL, ",");
}
//if cTok is 0, make sure user has passed in the correct format
if(0==cTok)
{
if(0!=strcmp(psz, ","))
goto CLEANUP;
}
// Allocate a cert enhanced key usage structure and fill it in with
// the string tokens
if(0!=cTok)
{
pUsage = (PCERT_ENHKEY_USAGE)ToolUtlAlloc(sizeof(CERT_ENHKEY_USAGE));
if(NULL==pUsage)
goto CLEANUP;
pUsage->cUsageIdentifier = cTok;
pUsage->rgpszUsageIdentifier = (LPSTR *)ToolUtlAlloc(sizeof(LPSTR)*cTok);
if(NULL==pUsage->rgpszUsageIdentifier)
goto CLEANUP;
//set up the OID array
pszTok = psz;
for ( cCount = 0; cCount < cTok; cCount++ )
{
pUsage->rgpszUsageIdentifier[cCount] = pszTok;
pszTok = pszTok+strlen(pszTok)+1;
}
// Encode the usage
if(!CryptEncodeObject(
X509_ASN_ENCODING,
szOID_ENHANCED_KEY_USAGE,
pUsage,
NULL,
&cbEncoded
))
goto CLEANUP;
pbEncoded = (BYTE *)ToolUtlAlloc(cbEncoded);
if ( NULL == pbEncoded)
goto CLEANUP;
if(!CryptEncodeObject(X509_ASN_ENCODING,
szOID_ENHANCED_KEY_USAGE,
pUsage,
pbEncoded,
&cbEncoded
))
goto CLEANUP;
}
//now, set the EKU for each certificate in the store
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
//1st, delete the original property
if(!CertSetCertificateContextProperty(pCertContext,
CERT_ENHKEY_USAGE_PROP_ID,
0,
NULL))
goto CLEANUP;
//2nd, set the new property if required
if(0!=cTok)
{
Blob.cbData=cbEncoded;
Blob.pbData=pbEncoded;
if(!CertSetCertificateContextProperty(pCertContext,
CERT_ENHKEY_USAGE_PROP_ID,
0,
&Blob))
goto CLEANUP;
}
pCertPre=pCertContext;
}
fResult=TRUE;
CLEANUP:
if(psz)
ToolUtlFree(psz);
if(pUsage)
{
if(pUsage->rgpszUsageIdentifier)
ToolUtlFree(pUsage->rgpszUsageIdentifier);
ToolUtlFree(pUsage);
}
if(pbEncoded)
ToolUtlFree(pbEncoded);
if(pCertContext)
CertFreeCertificateContext(pCertContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Set name property to all the certificate in the store
//
//-------------------------------------------------------------------------
BOOL SetNameProperty( HCERTSTORE hSrcStore)
{
BOOL fResult=FALSE;
CRYPT_DATA_BLOB Blob;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
//init the name property
Blob.cbData=(wcslen(g_wszName)+1)*sizeof(WCHAR);
Blob.pbData=(BYTE*)g_wszName;
//now, set the NAME for each certificate in the store
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
//1st, delete the original property
if(!CertSetCertificateContextProperty(pCertContext,
CERT_FRIENDLY_NAME_PROP_ID,
0,
NULL))
goto CLEANUP;
//2nd, set the new property if required
if(!CertSetCertificateContextProperty(pCertContext,
CERT_FRIENDLY_NAME_PROP_ID,
0,
&Blob))
goto CLEANUP;
pCertPre=pCertContext;
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Find a CRL based on SHA1 hash
//
//-------------------------------------------------------------------------
PCCRL_CONTEXT FindCRLInStore(HCERTSTORE hCertStore,
CRYPT_HASH_BLOB *pBlob)
{
BYTE *pbData=NULL;
DWORD cbData=0;
BOOL fResult=FALSE;
DWORD dwCRLFlag=0;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
if(!pBlob)
return NULL;
if(!(pBlob->pbData))
return NULL;
//enum the CRLS
while(pCRLContext=CertGetCRLFromStore(hCertStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
//get the hash
if(!CertGetCRLContextProperty(pCRLContext,
CERT_SHA1_HASH_PROP_ID,
NULL,
&cbData))
goto CLEANUP;
pbData=(BYTE *)ToolUtlAlloc(cbData);
if(!pbData)
goto CLEANUP;
if(!CertGetCRLContextProperty(pCRLContext,
CERT_SHA1_HASH_PROP_ID,
pbData,
&cbData))
goto CLEANUP;
//Compare
if(cbData==pBlob->cbData)
{
if(memcmp(pbData, pBlob->pbData, cbData)==0)
{
fResult=TRUE;
break;
}
}
pCRLPre=pCRLContext;
}
CLEANUP:
if(pbData)
ToolUtlFree(pbData);
if(FALSE==fResult)
{
if(pCRLContext)
{
CertFreeCRLContext(pCRLContext);
pCRLContext=NULL;
}
}
return pCRLContext;
}
//-------------------------------------------------------------------------
//
// Move Certs/CRls/CTLs from the source store to the destination
//
//-------------------------------------------------------------------------
BOOL MoveItem(HCERTSTORE hSrcStore,
HCERTSTORE hDesStore,
DWORD dwItem)
{
BOOL fResult=FALSE;
DWORD dwCRLFlag=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPre=NULL;
//add the certs
if(dwItem & ITEM_CERT)
{
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
if(!CertAddCertificateContextToStore(hDesStore,
pCertContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
goto CLEANUP;
pCertPre=pCertContext;
}
}
//add the CTLs
if(dwItem & ITEM_CTL)
{
while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
{
if(!CertAddCTLContextToStore(hDesStore,
pCTLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
goto CLEANUP;
pCTLPre=pCTLContext;
}
}
//add the CRLs
if(dwItem & ITEM_CRL)
{
while(pCRLContext=CertGetCRLFromStore(hSrcStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
if(!CertAddCRLContextToStore(hDesStore,
pCRLContext,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL))
goto CLEANUP;
pCRLPre=pCRLContext;
}
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Delete Certs/CRls/CTLs from the source store
//
//-------------------------------------------------------------------------
BOOL DeleteItem(HCERTSTORE hSrcStore,
DWORD dwItem)
{
BOOL fResult=FALSE;
DWORD dwCRLFlag=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPre=NULL;
//add the certs
if(dwItem & ITEM_CERT)
{
while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre))
{
pCertPre=pCertContext;
if(!CertDeleteCertificateFromStore(CertDuplicateCertificateContext(pCertContext)))
goto CLEANUP;
}
}
//add the CTLs
if(dwItem & ITEM_CTL)
{
while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre))
{
pCTLPre=pCTLContext;
if(!CertDeleteCTLFromStore(CertDuplicateCTLContext(pCTLContext)))
goto CLEANUP;
}
}
//add the CRLs
if(dwItem & ITEM_CRL)
{
while(pCRLContext=CertGetCRLFromStore(hSrcStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
pCRLPre=pCRLContext;
if(!CertDeleteCRLFromStore(CertDuplicateCRLContext(pCRLContext)))
goto CLEANUP;
}
}
fResult=TRUE;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Display all the certificates and prompt user for the index
//
//-------------------------------------------------------------------------
BOOL DisplayCertAndPrompt(PCCERT_CONTEXT *rgpCertContext,
DWORD dwCertCount,
DWORD *pdwIndex)
{
DWORD dwIndex=0;
if(!pdwIndex)
return FALSE;
//the count has to be more than 1
if(dwCertCount<2)
return FALSE;
//Display all the certs
for(dwIndex=0; dwIndex<dwCertCount; dwIndex++)
{
IDSwprintf(hModule,IDS_CERT_INDEX, dwIndex+1);
if(!DisplayCert(rgpCertContext[dwIndex], 0))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
return FALSE;
}
}
//promot user for an index
//tell them starting from 1
if(g_dwAction & ACTION_ADD)
IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CERT);
else
{
if(g_dwAction & ACTION_DELETE)
IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CERT);
else
{
IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CERT);
}
}
if (0 == scanf("%d",pdwIndex))
{
return FALSE;
}
if((*pdwIndex>=1) && (*pdwIndex<=dwCertCount))
{
//return the index
*pdwIndex=*pdwIndex-1;
return TRUE;
}
IDSwprintf(hModule, IDS_ERR_INVALID_INDEX);
return FALSE;
}
//-------------------------------------------------------------------------
//
// Display all the CRLs and prompt user for the index
//
//-------------------------------------------------------------------------
BOOL DisplayCRLAndPrompt(PCCRL_CONTEXT *rgpCRLContext,
DWORD dwCRLCount,
DWORD *pdwIndex)
{
DWORD dwIndex=0;
if(!pdwIndex)
return FALSE;
//the count has to be more than 1
if(dwCRLCount<2)
return FALSE;
//Display all the CRLs
for(dwIndex=0; dwIndex<dwCRLCount; dwIndex++)
{
IDSwprintf(hModule,IDS_CRL_INDEX, dwIndex+1);
if(!DisplayCRL(rgpCRLContext[dwIndex], 0))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
return FALSE;
}
}
//promot user for an index
//tell them starting from 1
if(g_dwAction & ACTION_ADD)
IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CRL);
else
{
if(g_dwAction & ACTION_DELETE)
IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CRL);
else
{
IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CRL);
}
}
if (0 == scanf("%d",pdwIndex))
{
return FALSE;
}
if((*pdwIndex>=1) && (*pdwIndex<=dwCRLCount))
{
//return the index
*pdwIndex=*pdwIndex-1;
return TRUE;
}
IDSwprintf(hModule,IDS_ERR_INVALID_INDEX);
return FALSE;
}
//-------------------------------------------------------------------------
//
// Display all the CTLs and prompt user for the index
//
//-------------------------------------------------------------------------
BOOL DisplayCTLAndPrompt(PCCTL_CONTEXT *rgpCTLContext,
DWORD dwCTLCount,
DWORD *pdwIndex)
{
DWORD dwIndex=0;
if(!pdwIndex)
return FALSE;
//the count has to be more than 1
if(dwCTLCount<2)
return FALSE;
//Display all the CTLs
for(dwIndex=0; dwIndex<dwCTLCount; dwIndex++)
{
IDSwprintf(hModule,IDS_CTL_INDEX, dwIndex+1);
if(!DisplayCTL(rgpCTLContext[dwIndex], 0))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
return FALSE;
}
}
//promot user for an index
//tell them starting from 1
if(g_dwAction & ACTION_ADD)
IDSwprintf(hModule,IDS_ENTER_ADD_INDEX_CTL);
else
{
if(g_dwAction & ACTION_DELETE)
IDSwprintf(hModule, IDS_ENTER_DELETE_INDEX_CTL);
else
{
IDSwprintf(hModule, IDS_ENTER_PUT_INDEX_CTL);
}
}
if (0 == scanf("%d",pdwIndex))
{
return FALSE;
}
if((*pdwIndex>=1) && (*pdwIndex<=dwCTLCount))
{
//return the index
*pdwIndex=*pdwIndex-1;
return TRUE;
}
IDSwprintf(hModule,IDS_ERR_INVALID_INDEX);
return FALSE;
}
//-------------------------------------------------------------------------
//
// Build a list of certificates for people to choose from
//
//-------------------------------------------------------------------------
BOOL BuildCertList(HCERTSTORE hCertStore,
LPWSTR wszCertCN,
PCCERT_CONTEXT **prgpCertContext,
DWORD *pdwCertCount)
{
BOOL fResult=FALSE;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCERT_CONTEXT * rgpCertContext=NULL;
DWORD dwIndex=0;
DWORD dwCount=0;
if(!prgpCertContext || !pdwCertCount)
return FALSE;
//init
*prgpCertContext=NULL;
*pdwCertCount=0;
//if wszCertCN is NULL, include every certs in the list
if(NULL==wszCertCN)
{
while(pCertContext=CertEnumCertificatesInStore(hCertStore, pCertPre))
{
dwCount++;
//allocation enough memory
rgpCertContext=(PCCERT_CONTEXT *)realloc((*prgpCertContext),
dwCount * sizeof(PCCERT_CONTEXT));
if(!rgpCertContext)
goto CLEANUP;
*prgpCertContext=rgpCertContext;
//duplicate the certificate context
(*prgpCertContext)[dwCount-1]=CertDuplicateCertificateContext(pCertContext);
if(!((*prgpCertContext)[dwCount-1]))
goto CLEANUP;
pCertPre=pCertContext;
}
}
else
{
//we search for the certificate based on the common name
while(pCertContext=CertFindCertificateInStore(hCertStore,
g_dwCertEncodingType,
0,
CERT_FIND_SUBJECT_STR_W,
wszCertCN,
pCertPre))
{
dwCount++;
//allocation enough memory
rgpCertContext=(PCCERT_CONTEXT *)realloc((*prgpCertContext),
dwCount * sizeof(PCCERT_CONTEXT));
if(!rgpCertContext)
goto CLEANUP;
*prgpCertContext=rgpCertContext;
//duplicate the certificate context
(*prgpCertContext)[dwCount-1]=CertDuplicateCertificateContext(pCertContext);
if(!((*prgpCertContext)[dwCount-1]))
goto CLEANUP;
pCertPre=pCertContext;
}
}
fResult=TRUE;
CLEANUP:
if(FALSE==fResult)
{
if(*prgpCertContext)
{
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
{
if(((*prgpCertContext)[dwIndex]))
CertFreeCertificateContext(((*prgpCertContext)[dwIndex]));
}
free(*prgpCertContext);
}
*prgpCertContext=NULL;
*pdwCertCount=0;
}
else
{
*pdwCertCount=dwCount;
}
if(pCertContext)
CertFreeCertificateContext(pCertContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Build a list of CRLs for people to choose from
//
//-------------------------------------------------------------------------
BOOL BuildCRLList( HCERTSTORE hCertStore,
PCCRL_CONTEXT **prgpCRLContext,
DWORD *pdwCRLCount)
{
BOOL fResult=FALSE;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
PCCRL_CONTEXT * rgpCRLContext=NULL;
DWORD dwCRLFlag=0;
DWORD dwIndex=0;
DWORD dwCount=0;
if(!prgpCRLContext || !pdwCRLCount)
return FALSE;
//init
*prgpCRLContext=NULL;
*pdwCRLCount=0;
while(pCRLContext=CertGetCRLFromStore(hCertStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
dwCount++;
//allocation enough memory
rgpCRLContext=(PCCRL_CONTEXT *)realloc((*prgpCRLContext),
dwCount * sizeof(PCCRL_CONTEXT));
if(!rgpCRLContext)
goto CLEANUP;
*prgpCRLContext=rgpCRLContext;
//duplicate the CRL context
(*prgpCRLContext)[dwCount-1]=CertDuplicateCRLContext(pCRLContext);
if(!((*prgpCRLContext)[dwCount-1]))
goto CLEANUP;
pCRLPre=pCRLContext;
}
fResult=TRUE;
CLEANUP:
if(FALSE==fResult)
{
if(*prgpCRLContext)
{
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
{
if(((*prgpCRLContext)[dwIndex]))
CertFreeCRLContext(((*prgpCRLContext)[dwIndex]));
}
free(*prgpCRLContext);
}
*prgpCRLContext=NULL;
*pdwCRLCount=0;
}
else
{
*pdwCRLCount=dwCount;
}
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Build a list of CTLs for people to choose from
//
//-------------------------------------------------------------------------
BOOL BuildCTLList( HCERTSTORE hCertStore,
PCCTL_CONTEXT **prgpCTLContext,
DWORD *pdwCTLCount)
{
BOOL fResult=FALSE;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPre=NULL;
PCCTL_CONTEXT * rgpCTLContext=NULL;
DWORD dwIndex=0;
DWORD dwCount=0;
if(!prgpCTLContext || !pdwCTLCount)
return FALSE;
//init
*prgpCTLContext=NULL;
*pdwCTLCount=0;
while(pCTLContext=CertEnumCTLsInStore(hCertStore,pCTLPre))
{
dwCount++;
//allocation enough memory
rgpCTLContext=(PCCTL_CONTEXT *)realloc((*prgpCTLContext),
dwCount * sizeof(PCCTL_CONTEXT));
if(!rgpCTLContext)
goto CLEANUP;
*prgpCTLContext=rgpCTLContext;
//duplicate the CTL context
(*prgpCTLContext)[dwCount-1]=CertDuplicateCTLContext(pCTLContext);
if(!((*prgpCTLContext)[dwCount-1]))
goto CLEANUP;
pCTLPre=pCTLContext;
}
fResult=TRUE;
CLEANUP:
if(FALSE==fResult)
{
if(*prgpCTLContext)
{
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
{
if(((*prgpCTLContext)[dwIndex]))
CertFreeCTLContext(((*prgpCTLContext)[dwIndex]));
}
free(*prgpCTLContext);
}
*prgpCTLContext=NULL;
*pdwCTLCount=0;
}
else
{
*pdwCTLCount=dwCount;
}
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
return fResult;
}
//-------------------------------------------------------------------------
//
// Display everthing in a store
//
//-------------------------------------------------------------------------
BOOL DisplayCertStore(HCERTSTORE hCertStore)
{
BOOL fResult=FALSE;
DWORD dwCount=0;
DWORD dwCRLFlag=0;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
PCCRL_CONTEXT pCRLContext=NULL;
PCCRL_CONTEXT pCRLPre=NULL;
PCCTL_CONTEXT pCTLContext=NULL;
PCCTL_CONTEXT pCTLPre=NULL;
//Display the certs
if(g_dwItem & ITEM_CERT)
{
while(pCertContext=CertEnumCertificatesInStore(hCertStore, pCertPre))
{
dwCount++;
IDSwprintf(hModule,IDS_CERT_INDEX, dwCount);
if(!DisplayCert(pCertContext, g_dwItem))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
}
pCertPre=pCertContext;
}
if(0==dwCount)
IDSwprintf(hModule,IDS_NO_CERT);
}
dwCount=0;
//Display the CTLs
if(g_dwItem & ITEM_CTL)
{
while(pCTLContext=CertEnumCTLsInStore(hCertStore, pCTLPre))
{
dwCount++;
IDSwprintf(hModule,IDS_CTL_INDEX, dwCount);
if(!DisplayCTL(pCTLContext, g_dwItem))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
}
pCTLPre=pCTLContext;
}
if(0==dwCount)
IDSwprintf(hModule,IDS_NO_CTL);
}
dwCount=0;
//Display the CRLs
if(g_dwItem & ITEM_CRL)
{
while(pCRLContext=CertGetCRLFromStore(hCertStore,
NULL,
pCRLPre,
&dwCRLFlag))
{
dwCount++;
IDSwprintf(hModule,IDS_CRL_INDEX, dwCount);
if(!DisplayCRL(pCRLContext, g_dwItem))
{
IDSwprintf(hModule,IDS_ERR_DISPLAY);
}
pCRLPre=pCRLContext;
}
if(0==dwCount)
IDSwprintf(hModule,IDS_NO_CRL);
}
fResult=TRUE;
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(pCTLContext)
CertFreeCTLContext(pCTLContext);
if(pCRLContext)
CertFreeCRLContext(pCRLContext);
return fResult;
}
//+-------------------------------------------------------------------------
// DisplaySMIMECapabilitiesExtension
//--------------------------------------------------------------------------
void DisplayTimeStamp(BYTE *pbEncoded,DWORD cbEncoded,DWORD dwDisplayFlags)
{
CMSG_SIGNER_INFO *pSignerInfo=NULL;
if (NULL == (pSignerInfo = (CMSG_SIGNER_INFO *) TestNoCopyDecodeObject(
PKCS7_SIGNER_INFO,
pbEncoded,
cbEncoded
))) goto CommonReturn;
//display the timestamper's information
//" Timestamp Version:: %d\n"
IDSwprintf(hModule, IDS_TS_VERSION, pSignerInfo->dwVersion);
//"Timestamp server's certificate issuer::\n");
IDSwprintf(hModule, IDS_TS_ISSUER);
DecodeName(pSignerInfo->Issuer.pbData,
pSignerInfo->Issuer.cbData, dwDisplayFlags);
//"Timestamp server's certificate SerialNumber::\n"
IDSwprintf(hModule, IDS_TS_SERIAL_NUMBER);
DisplaySerialNumber(&pSignerInfo->SerialNumber);
printf("\n");
//"Timestamp's authenticated attributes::\n"
IDSwprintf(hModule, IDS_TS_AUTHATTR);
PrintAttributes(pSignerInfo->AuthAttrs.cAttr, pSignerInfo->AuthAttrs.rgAttr,
dwDisplayFlags);
//"Timestamp's unauthenticated attributes::\n"
if(pSignerInfo->UnauthAttrs.cAttr)
{
IDSwprintf(hModule, IDS_TS_UNAUTHATTR);
PrintAttributes(pSignerInfo->UnauthAttrs.cAttr,
pSignerInfo->UnauthAttrs.rgAttr,
dwDisplayFlags);
}
CommonReturn:
if(pSignerInfo)
ToolUtlFree(pSignerInfo);
return;
}
//-------------------------------------------------------------------------
//
// Display a certificate
//
//-------------------------------------------------------------------------
BOOL DisplayCert(PCCERT_CONTEXT pCert, DWORD dwDisplayFlags)
{
BOOL fResult=FALSE;
BYTE rgbHash[MAX_HASH_LEN];
DWORD cbHash = MAX_HASH_LEN;
HCRYPTPROV hProv = 0;
//"Subject::\n");
IDSwprintf(hModule, IDS_SUBJECT);
DecodeName(pCert->pCertInfo->Subject.pbData,
pCert->pCertInfo->Subject.cbData, dwDisplayFlags);
//"Issuer::\n"
IDSwprintf(hModule, IDS_ISSUER);
DecodeName(pCert->pCertInfo->Issuer.pbData,
pCert->pCertInfo->Issuer.cbData, dwDisplayFlags);
//"SerialNumber::"
IDSwprintf(hModule, IDS_SERIAL_NUMBER);
DisplaySerialNumber(&pCert->pCertInfo->SerialNumber);
printf("\n");
CertGetCertificateContextProperty(
pCert,
CERT_SHA1_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
cbHash = MAX_HASH_LEN;
CertGetCertificateContextProperty(
pCert,
CERT_MD5_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
CryptAcquireContext(
&hProv,
NULL,
NULL, // pszProvider
PROV_RSA_FULL,
0 // dwFlags
);
if (hProv)
{
cbHash = MAX_HASH_LEN;
CryptHashPublicKeyInfo(
hProv,
CALG_MD5,
0, // dwFlags
g_dwCertEncodingType,
&pCert->pCertInfo->SubjectPublicKeyInfo,
rgbHash,
&cbHash
);
//"Key "
IDSwprintf(hModule, IDS_KEY);
DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
CryptReleaseContext(hProv, 0);
}
//print the Key_Prov_Info_Prop_ID
{
PCRYPT_KEY_PROV_INFO pInfo = NULL;
DWORD cbInfo;
cbInfo = 0;
CertGetCertificateContextProperty(
pCert,
CERT_KEY_PROV_INFO_PROP_ID,
NULL, // pvData
&cbInfo
);
if (cbInfo)
{
pInfo = (PCRYPT_KEY_PROV_INFO) ToolUtlAlloc(cbInfo);
if (pInfo)
{
if (CertGetCertificateContextProperty(
pCert,
CERT_KEY_PROV_INFO_PROP_ID,
pInfo,
&cbInfo
))
{
//"Provider Type:: %d"
IDSwprintf(hModule, IDS_KEY_PROVIDER, pInfo->dwProvType);
//" Provider Name:: %s"
if (pInfo->pwszProvName)
IDSwprintf(hModule, IDS_PROV_NAME, pInfo->pwszProvName);
//" Flags: 0x%x"
if (pInfo->dwFlags)
IDSwprintf(hModule, IDS_FLAGS, pInfo->dwFlags);
//" Container: %S"
if (pInfo->pwszContainerName)
IDSwprintf(hModule, IDS_CONTAINER, pInfo->pwszContainerName);
//" Params: %d"
if (pInfo->cProvParam)
IDSwprintf(hModule, IDS_PARAM,pInfo->cProvParam);
//" KeySpec: %d"
if (pInfo->dwKeySpec)
IDSwprintf(hModule, IDS_KEY_SPEC, pInfo->dwKeySpec);
printf("\n");
}
ToolUtlFree(pInfo);
}
}
}
//"NotBefore:: %s\n"
IDSwprintf(hModule, IDS_NOT_BEFORE, FileTimeText(&pCert->pCertInfo->NotBefore));
//"NotAfter:: %s\n"
IDSwprintf(hModule, IDS_NOT_AFTER, FileTimeText(&pCert->pCertInfo->NotAfter));
//Display the aux properties if verbose
if(dwDisplayFlags & ITEM_VERBOSE)
PrintAuxCertProperties(pCert,dwDisplayFlags);
if (dwDisplayFlags & ITEM_VERBOSE)
{
LPSTR pszObjId;
ALG_ID aiPubKey;
DWORD dwBitLen;
//"Version:: %d\n"
IDSwprintf(hModule, IDS_VERSION, pCert->pCertInfo->dwVersion);
pszObjId = pCert->pCertInfo->SignatureAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"SignatureAlgorithm:: "
IDSwprintf(hModule, IDS_SIG_ALGO);
printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
if (pCert->pCertInfo->SignatureAlgorithm.Parameters.cbData)
{
//"SignatureAlgorithm.Parameters::\n"
IDSwprintf(hModule, IDS_SIG_ALGO_PARAM);
PrintBytes(L" ",
pCert->pCertInfo->SignatureAlgorithm.Parameters.pbData,
pCert->pCertInfo->SignatureAlgorithm.Parameters.cbData);
}
//public key algorithm
pszObjId = pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
// "SubjectPublicKeyInfo.Algorithm::
IDSwprintf(hModule, IDS_SUB_KEY_ALGO);
printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_PUBKEY_ALG_OID_GROUP_ID));
aiPubKey = GetAlgid(pszObjId, CRYPT_PUBKEY_ALG_OID_GROUP_ID);
if (pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData)
{
//"SubjectPublicKeyInfo.Algorithm.Parameters::\n"
IDSwprintf(hModule, IDS_SUB_KEY_ALGO_PARAM);
PrintBytes(L" ",
pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData);
//display DSS sign key
if (CALG_DSS_SIGN == aiPubKey)
{
PCERT_DSS_PARAMETERS pDssParameters;
DWORD cbDssParameters;
if (pDssParameters =
(PCERT_DSS_PARAMETERS) TestNoCopyDecodeObject(
X509_DSS_PARAMETERS,
pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.pbData,
pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.Parameters.cbData,
&cbDssParameters
))
{
DWORD cbKey = pDssParameters->p.cbData;
//"DSS Key Length:: %d bytes, %d bits\n"
IDSwprintf(hModule, IDS_DSS_LENGTH, cbKey, cbKey*8);
//"DSS P (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_P);
PrintBytes(L" ", pDssParameters->p.pbData,
pDssParameters->p.cbData);
//"DSS Q (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_Q);
PrintBytes(L" ", pDssParameters->q.pbData,
pDssParameters->q.cbData);
//"DSS G (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_G);
PrintBytes(L" ", pDssParameters->g.pbData,
pDssParameters->g.cbData);
ToolUtlFree(pDssParameters);
}
}
}
//"SubjectPublicKeyInfo.PublicKey"
IDSwprintf(hModule, IDS_SUB_KEY_INFO);
if (0 != (dwBitLen = CertGetPublicKeyLength(
g_dwCertEncodingType,
&pCert->pCertInfo->SubjectPublicKeyInfo)))
//" (BitLength: %d)"
IDSwprintf(hModule, IDS_BIT_LENGTH, dwBitLen);
if (pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cUnusedBits)
//" (UnusedBits: %d)"
IDSwprintf(hModule, IDS_UNUSED_BITS,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cUnusedBits);
printf("\n");
//print public key
if (pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)
{
PrintBytes(L" ",
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData);
if (CALG_RSA_SIGN == aiPubKey || CALG_RSA_KEYX == aiPubKey)
{
PUBLICKEYSTRUC *pPubKeyStruc=NULL;
DWORD cbPubKeyStruc;
//"RSA_CSP_PUBLICKEYBLOB::\n"
IDSwprintf(hModule, IDS_RSA_CSP);
if (pPubKeyStruc = (PUBLICKEYSTRUC *) TestNoCopyDecodeObject(
RSA_CSP_PUBLICKEYBLOB,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
&cbPubKeyStruc
))
{
PrintBytes(L" ", (BYTE *) pPubKeyStruc, cbPubKeyStruc);
ToolUtlFree(pPubKeyStruc);
}
}
else if (CALG_DSS_SIGN == aiPubKey)
{
PCRYPT_UINT_BLOB pDssPubKey;
DWORD cbDssPubKey;
//"DSS Y (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_Y);
if (pDssPubKey = (PCRYPT_UINT_BLOB) TestNoCopyDecodeObject
(
X509_DSS_PUBLICKEY,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
&cbDssPubKey
))
{
PrintBytes(L" ", pDssPubKey->pbData, pDssPubKey->cbData);
ToolUtlFree(pDssPubKey);
}
}
}
else
//" No public key\n"
IDSwprintf(hModule, IDS_NO_PUB_KEY);
DisplaySignature
(
pCert->pbCertEncoded,
pCert->cbCertEncoded,
dwDisplayFlags);
//IssuerUniqueId
if (pCert->pCertInfo->IssuerUniqueId.cbData)
{
//"IssuerUniqueId"
IDSwprintf(hModule, IDS_ISSUER_ID);
if (pCert->pCertInfo->IssuerUniqueId.cUnusedBits)
//" (UnusedBits: %d)"
IDSwprintf(hModule, IDS_UNUSED_BITS,
pCert->pCertInfo->IssuerUniqueId.cUnusedBits);
printf("\n");
PrintBytes(L" ", pCert->pCertInfo->IssuerUniqueId.pbData,
pCert->pCertInfo->IssuerUniqueId.cbData);
}
if (pCert->pCertInfo->SubjectUniqueId.cbData)
{
//"SubjectUniqueId"
IDSwprintf(hModule, IDS_SUBJECT_ID);
if (pCert->pCertInfo->SubjectUniqueId.cUnusedBits)
//" (UnusedBits: %d)"
IDSwprintf(hModule, IDS_UNUSED_BITS,
pCert->pCertInfo->SubjectUniqueId.cUnusedBits);
printf("\n");
PrintBytes(L" ", pCert->pCertInfo->SubjectUniqueId.pbData,
pCert->pCertInfo->SubjectUniqueId.cbData);
}
//extensions
if (pCert->pCertInfo->cExtension != 0)
{
PrintExtensions(pCert->pCertInfo->cExtension,
pCert->pCertInfo->rgExtension, dwDisplayFlags);
}
}//ITEM_VERBOSE
fResult=TRUE;
return fResult;
}
//-------------------------------------------------------------------------
//
// Display a CTL
//
//-------------------------------------------------------------------------
BOOL DisplayCTL(PCCTL_CONTEXT pCtl, DWORD dwDisplayFlags)
{
BOOL fResult=FALSE;
PCTL_INFO pInfo = pCtl->pCtlInfo;
DWORD cId;
LPSTR *ppszId = NULL;
DWORD i;
BYTE rgbHash[MAX_HASH_LEN];
DWORD cbHash = MAX_HASH_LEN;
// "SubjectUsage::\n"
IDSwprintf(hModule, IDS_SUBJECT_USAGE);
cId = pInfo->SubjectUsage.cUsageIdentifier;
ppszId = pInfo->SubjectUsage.rgpszUsageIdentifier;
if (cId == 0)
{
//" No Usage Identifiers\n"
IDSwprintf(hModule, IDS_NO_USAGE_IDS );
}
else
{
for (i = 0; i < cId; i++, ppszId++)
printf(" [%d] %s\n", i, *ppszId);
}
//list identifier
if (pInfo->ListIdentifier.cbData)
{
//"ListIdentifier::\n"
IDSwprintf(hModule, IDS_LIST_DIS);
PrintBytes(L" ",
pInfo->ListIdentifier.pbData,
pInfo->ListIdentifier.cbData);
}
if (pInfo->SequenceNumber.cbData)
{
//"SequenceNumber::"
IDSwprintf(hModule, IDS_SEQUENCE);
DisplaySerialNumber(&pInfo->SequenceNumber);
printf("\n");
}
//update
//"ThisUpdate:: %s\n"
IDSwprintf(hModule, IDS_THIS_UPDATE, FileTimeText(&pCtl->pCtlInfo->ThisUpdate));
//"NextUpdate:: %s\n"
IDSwprintf(hModule,IDS_NEXT_UPDATE, FileTimeText(&pCtl->pCtlInfo->NextUpdate));
//check the time validity
if (!IsTimeValidCtl(pCtl))
// "****** Time Invalid CTL\n"
IDSwprintf(hModule, IDS_TIME_INVALID);
//Display SHA1 thumbprint
CertGetCTLContextProperty(
pCtl,
CERT_SHA1_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
cbHash=MAX_HASH_LEN;
CertGetCTLContextProperty(
pCtl,
CERT_MD5_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
// PrintAuxCtlProperties(pCtl, dwDisplayFlags);
//Display SubjectAlgorithm
if (dwDisplayFlags & ITEM_VERBOSE)
{
LPSTR pszObjId;
//"Version:: %d\n"
IDSwprintf(hModule, IDS_VERSION, pInfo->dwVersion);
pszObjId = pInfo->SubjectAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"SubjectAlgorithm:: "
IDSwprintf(hModule, IDS_SUB_ALGO);
printf("%s \n", pszObjId);
if (pInfo->SubjectAlgorithm.Parameters.cbData)
{
//"SubjectAlgorithm.Parameters::\n"
IDSwprintf(hModule, IDS_SUB_ALGO_PARAM);
PrintBytes(L" ",
pInfo->SubjectAlgorithm.Parameters.pbData,
pInfo->SubjectAlgorithm.Parameters.cbData);
}
if (pInfo->cExtension != 0)
{
PrintExtensions(pInfo->cExtension, pInfo->rgExtension,
dwDisplayFlags);
}
}
if (pInfo->cCTLEntry == 0)
//"----- No Entries -----\n"
IDSwprintf(hModule, IDS_NO_ENTRIES);
else
{
//"----- Entries -----\n"
IDSwprintf(hModule, IDS_ENTRIES);
PrintCtlEntries(pCtl,dwDisplayFlags);
}
//print the signer info
DisplaySignerInfo(pCtl->hCryptMsg, dwDisplayFlags);
fResult=TRUE;
return fResult;
}
//-------------------------------------------------------------------------
//
// Display a CTL entries
//
//-------------------------------------------------------------------------
void PrintCtlEntries(PCCTL_CONTEXT pCtl, DWORD dwDisplayFlags)
{
PCTL_INFO pInfo = pCtl->pCtlInfo;
DWORD cEntry = pInfo->cCTLEntry;
PCTL_ENTRY pEntry = pInfo->rgCTLEntry;
DWORD i;
for (i = 0; i < cEntry; i++, pEntry++)
{
//" [%d] SubjectIdentifier::\n"
IDSwprintf(hModule, IDS_SUB_ID,i);
PrintBytes(L" ",
pEntry->SubjectIdentifier.pbData,
pEntry->SubjectIdentifier.cbData);
if (dwDisplayFlags & ITEM_VERBOSE)
{
if (pEntry->cAttribute)
{
//" [%d] Attributes::\n"
IDSwprintf(hModule, IDS_ATTR, i);
PrintAttributes(pEntry->cAttribute, pEntry->rgAttribute,
dwDisplayFlags);
}
}
}
}
//-------------------------------------------------------------------------
//
// Display a CRL
//
//-------------------------------------------------------------------------
BOOL DisplayCRL(PCCRL_CONTEXT pCrl, DWORD dwDisplayFlags)
{
BOOL fResult=FALSE;
BYTE rgbHash[MAX_HASH_LEN];
DWORD cbHash = MAX_HASH_LEN;
//"Issuer::\n"
IDSwprintf(hModule, IDS_ISSUER);
DecodeName(pCrl->pCrlInfo->Issuer.pbData,
pCrl->pCrlInfo->Issuer.cbData, dwDisplayFlags);
//"ThisUpdate:: %s\n"
IDSwprintf(hModule, IDS_THIS_UPDATE, FileTimeText(&pCrl->pCrlInfo->ThisUpdate));
//"NextUpdate:: %s\n"
IDSwprintf(hModule,IDS_NEXT_UPDATE, FileTimeText(&pCrl->pCrlInfo->NextUpdate));
CertGetCRLContextProperty(
pCrl,
CERT_SHA1_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszSHA1, rgbHash, cbHash);
cbHash=MAX_HASH_LEN;
CertGetCRLContextProperty(
pCrl,
CERT_MD5_HASH_PROP_ID,
rgbHash,
&cbHash
);
DisplayThumbprint(g_wszMD5, rgbHash, cbHash);
// PrintAuxCrlProperties(pCrl, dwDisplayFlags);
if (dwDisplayFlags & ITEM_VERBOSE)
{
LPSTR pszObjId;
//"Version:: %d\n"
IDSwprintf(hModule, IDS_VERSION, pCrl->pCrlInfo->dwVersion);
pszObjId = pCrl->pCrlInfo->SignatureAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"SignatureAlgorithm:: "
IDSwprintf(hModule, IDS_SIG_ALGO);
printf("%s \n", pszObjId);
if (pCrl->pCrlInfo->SignatureAlgorithm.Parameters.cbData)
{
//"SignatureAlgorithm.Parameters::\n"
IDSwprintf(hModule, IDS_SIG_ALGO_PARAM);
PrintBytes(L" ",
pCrl->pCrlInfo->SignatureAlgorithm.Parameters.pbData,
pCrl->pCrlInfo->SignatureAlgorithm.Parameters.cbData);
}
//extensions
if (pCrl->pCrlInfo->cExtension != 0)
{
PrintExtensions(pCrl->pCrlInfo->cExtension,
pCrl->pCrlInfo->rgExtension,
dwDisplayFlags);
}
}
if (pCrl->pCrlInfo->cCRLEntry == 0)
//"----- No Entries -----\n"
IDSwprintf(hModule, IDS_NO_ENTRIES);
else
{
//"----- Entries -----\n"
IDSwprintf(hModule, IDS_ENTRIES);
PrintCrlEntries(pCrl->pCrlInfo->cCRLEntry,
pCrl->pCrlInfo->rgCRLEntry, dwDisplayFlags);
}
fResult=TRUE;
return fResult;
}
//-------------------------------------------------------------------------
//
// PrintCrlEntries
//
//-------------------------------------------------------------------------
void PrintCrlEntries(DWORD cEntry, PCRL_ENTRY pEntry,
DWORD dwDisplayFlags)
{
DWORD i;
for (i = 0; i < cEntry; i++, pEntry++)
{
//" [%d] SerialNumber::"
IDSwprintf(hModule, IDS_SERIAL_NUM_I, i);
DisplaySerialNumber(&pEntry->SerialNumber);
printf("\n");
if (dwDisplayFlags & ITEM_VERBOSE)
{
//" [%d] RevocationDate:: %s\n"
IDSwprintf(hModule, IDS_REVOC_DATE,
i,FileTimeText(&pEntry->RevocationDate));
}
if (pEntry->cExtension == 0)
//" [%d] Extensions:: NONE\n"
IDSwprintf(hModule, IDS_NO_EXTENSION,i);
else
{
//" [%d] Extensions::\n"
IDSwprintf(hModule, IDS_EXTENSION, i);
PrintExtensions(pEntry->cExtension, pEntry->rgExtension,
dwDisplayFlags);
}
}
}
//-------------------------------------------------------------------------
//
// Display a signer info
//
//-------------------------------------------------------------------------
BOOL DisplaySignerInfo(HCRYPTMSG hMsg, DWORD dwItem)
{
BOOL fResult=FALSE;
DWORD dwSignerCount=0;
DWORD cbData=0;
DWORD dwSignerIndex=0;
PCRYPT_ATTRIBUTES pAttrs;
LPSTR pszObjId=NULL;
if(!hMsg)
return FALSE;
//decide the number of signers
cbData=sizeof(dwSignerCount);
if(!CryptMsgGetParam(hMsg,
CMSG_SIGNER_COUNT_PARAM,
0,
&dwSignerCount,
&cbData) )
{
IDSwprintf(hModule, IDS_ERR_GET_SINGER_COUNT);
return FALSE;
}
if(dwSignerCount==0)
{
IDSwprintf(hModule, IDS_DIS_NO_SIGNER);
return TRUE;
}
for(dwSignerIndex=0; dwSignerIndex < dwSignerCount; dwSignerIndex++)
{
PCCERT_CONTEXT pSigner;
PCMSG_SIGNER_INFO pSignerInfo;
//"----- Signer [%d] -----\n");
IDSwprintf(hModule, IDS_SIGNER_INDEX, dwSignerIndex+1);
//get the signerInfo
if(pSignerInfo=(PCMSG_SIGNER_INFO) AllocAndGetMsgParam(
hMsg,
CMSG_SIGNER_INFO_PARAM,
dwSignerIndex,
&cbData))
{
//Dispaly the hash algorithm
pszObjId = pSignerInfo->HashAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"Hash Algorithm:: "
IDSwprintf(hModule, IDS_HASH_ALGO);
printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_HASH_ALG_OID_GROUP_ID));
if (pSignerInfo->HashAlgorithm.Parameters.cbData)
{
//"HashAlgorithm.Parameters::\n"
IDSwprintf(hModule, IDS_HASH_ALGO_PARAM);
PrintBytes(L" ",
pSignerInfo->HashAlgorithm.Parameters.pbData,
pSignerInfo->HashAlgorithm.Parameters.cbData);
}
//Display the encrypt algorithm
pszObjId = pSignerInfo->HashEncryptionAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"Encrypt Algorithm:: "
IDSwprintf(hModule, IDS_ENCRYPT_ALGO);
printf("%s (%S)\n", pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
if (pSignerInfo->HashEncryptionAlgorithm.Parameters.cbData)
{
//"Encrypt Algorithm.Parameters::\n"
IDSwprintf(hModule, IDS_ENCRYPT_ALGO_PARAM);
PrintBytes(L" ",
pSignerInfo->HashEncryptionAlgorithm.Parameters.pbData,
pSignerInfo->HashEncryptionAlgorithm.Parameters.cbData);
}
ToolUtlFree(pSignerInfo);
}
if (CryptMsgGetAndVerifySigner(
hMsg,
0, // cSignerStore
NULL, // rghSignerStore
CMSG_USE_SIGNER_INDEX_FLAG,
&pSigner,
&dwSignerIndex
))
{
//"----- Signer [%d] Certificate-----\n");
IDSwprintf(hModule, IDS_SIGNER_INDEX_CERT, dwSignerIndex+1);
DisplayCert(pSigner, dwItem);
CertFreeCertificateContext(pSigner);
}
else
{
IDSwprintf(hModule, IDS_ERR_GET_SIGNER_CERT);
goto CLEANUP;
}
//DisplaySigner information
if (pAttrs = (PCRYPT_ATTRIBUTES) AllocAndGetMsgParam(
hMsg,
CMSG_SIGNER_AUTH_ATTR_PARAM,
dwSignerIndex,
&cbData))
{
//"----- Signer [%d] AuthenticatedAttributes -----\n"
IDSwprintf(hModule, IDS_DIS_SIGNER_AUTH_ATTR, dwSignerIndex+1);
PrintAttributes(pAttrs->cAttr, pAttrs->rgAttr, dwItem);
ToolUtlFree(pAttrs);
}
if (pAttrs = (PCRYPT_ATTRIBUTES) AllocAndGetMsgParam(
hMsg,
CMSG_SIGNER_UNAUTH_ATTR_PARAM,
dwSignerIndex,
&cbData))
{
//"----- Signer [%d] UnauthenticatedAttributes -----\n",
IDSwprintf(hModule, IDS_DIS_SIGNER_UNAUTH_ATTR, dwSignerIndex+1);
PrintAttributes(pAttrs->cAttr, pAttrs->rgAttr, dwItem);
ToolUtlFree(pAttrs);
}
}
fResult=TRUE;
CLEANUP:
return fResult;
}
//-------------------------------------------------------------------------
//
// Open a store file using sip functions
//
//-------------------------------------------------------------------------
HCERTSTORE OpenSipStore(LPWSTR pwszStoreFilename)
{
HCERTSTORE hStore = NULL;
CRYPT_DATA_BLOB SignedData;
memset(&SignedData, 0, sizeof(SignedData));
DWORD dwGetEncodingType;
DWORD dwMsgType=0;
GUID gSubject;
SIP_DISPATCH_INFO SipDispatch;
SIP_SUBJECTINFO SubjectInfo;
if (!CryptSIPRetrieveSubjectGuid(
pwszStoreFilename,
NULL, // hFile
&gSubject)) goto CommonReturn;
memset(&SipDispatch, 0, sizeof(SipDispatch));
SipDispatch.cbSize = sizeof(SipDispatch);
if (!CryptSIPLoad(
&gSubject,
0, // dwFlags
&SipDispatch)) goto CommonReturn;
memset(&SubjectInfo, 0, sizeof(SubjectInfo));
SubjectInfo.cbSize = sizeof(SubjectInfo);
SubjectInfo.pgSubjectType = (GUID*) &gSubject;
SubjectInfo.hFile = INVALID_HANDLE_VALUE;
SubjectInfo.pwsFileName = pwszStoreFilename;
// SubjectInfo.pwsDisplayName =
// SubjectInfo.lpSIPInfo =
// SubjectInfo.dwReserved =
// SubjectInfo.hProv =
// SubjectInfo.DigestAlgorithm =
// SubjectInfo.dwFlags =
SubjectInfo.dwEncodingType = g_dwMsgAndCertEncodingType;
// SubjectInfo.lpAddInfo =
if (!SipDispatch.pfGet(
&SubjectInfo,
&dwGetEncodingType,
0, // dwIndex
&SignedData.cbData,
NULL // pbSignedData
) || 0 == SignedData.cbData)
goto CommonReturn;
if (NULL == (SignedData.pbData = (BYTE *) ToolUtlAlloc(SignedData.cbData)))
goto CommonReturn;
if (!SipDispatch.pfGet(
&SubjectInfo,
&dwGetEncodingType,
0, // dwIndex
&SignedData.cbData,
SignedData.pbData
))
goto CommonReturn;
hStore = CertOpenStore(
CERT_STORE_PROV_PKCS7,
g_dwMsgAndCertEncodingType,
0, // hCryptProv
0, // dwFlags
(const void *) &SignedData
);
if(!hStore)
goto CommonReturn;
//now, we want to update the g_hMsg to hold the signer info
if(SignNoContentWrap(SignedData.pbData, SignedData.cbData))
dwMsgType = CMSG_SIGNED;
if (!(g_hMsg = CryptMsgOpenToDecode(g_dwMsgAndCertEncodingType,
0, // dwFlags
dwMsgType,
NULL,
NULL, // pRecipientInfo
NULL)))
{
CertCloseStore(hStore, 0);
hStore=NULL;
goto CommonReturn;
}
if (!CryptMsgUpdate(g_hMsg,
SignedData.pbData,
SignedData.cbData,
TRUE)) // fFinal
{
CertCloseStore(hStore, 0);
hStore=NULL;
CryptMsgClose(g_hMsg);
g_hMsg=NULL;
}
CommonReturn:
if(SignedData.pbData)
ToolUtlFree(SignedData.pbData);
return hStore;
}
//-------------------------------------------------------------------------
//
// BytesToBase64: ascii:
// conver base64 bstr to bytes
//
//-------------------------------------------------------------------------
HRESULT Base64ToBytes(CHAR *pEncode, DWORD cbEncode, BYTE **ppb, DWORD *pcb)
{
DWORD dwErr;
BYTE *pb;
DWORD cb;
*ppb = NULL;
*pcb = 0;
cb = 0;
if (!CryptStringToBinaryA(
pEncode,
cbEncode,
CRYPT_STRING_ANY,
NULL,
&cb,
NULL,
NULL
))
return HRESULT_FROM_WIN32(GetLastError());
if (cb == 0)
return S_OK;
if (NULL == (pb = (BYTE *) ToolUtlAlloc(cb)))
return E_OUTOFMEMORY;
if (!CryptStringToBinaryA(
pEncode,
cbEncode,
CRYPT_STRING_ANY,
pb,
&cb,
NULL,
NULL
)) {
ToolUtlFree(pb);
return HRESULT_FROM_WIN32(GetLastError());
} else {
*ppb = pb;
*pcb = cb;
return S_OK;
}
}
//-------------------------------------------------------------------------
//
// BytesToBase64 wchar version:
// conver base64 bstr to bytes
//
//-------------------------------------------------------------------------
HRESULT Base64ToBytesW(WCHAR *pEncode, DWORD cbEncode, BYTE **ppb, DWORD *pcb)
{
DWORD dwErr;
BYTE *pb;
DWORD cb;
*ppb = NULL;
*pcb = 0;
cb = 0;
if (!CryptStringToBinaryW(
pEncode,
cbEncode,
CRYPT_STRING_ANY,
NULL,
&cb,
NULL,
NULL
))
return HRESULT_FROM_WIN32(GetLastError());
if (cb == 0)
return S_OK;
if (NULL == (pb = (BYTE *) ToolUtlAlloc(cb)))
return E_OUTOFMEMORY;
if (!CryptStringToBinaryW(
pEncode,
cbEncode,
CRYPT_STRING_ANY,
pb,
&cb,
NULL,
NULL
)) {
ToolUtlFree(pb);
return HRESULT_FROM_WIN32(GetLastError());
} else {
*ppb = pb;
*pcb = cb;
return S_OK;
}
}
//------------------------------------------------------------------------------------
//
// Base64 decode the file
//
//------------------------------------------------------------------------------------
BOOL GetBase64Decoded(LPWSTR wszStoreName,
BYTE **ppbByte,
DWORD *pcbByte)
{
BOOL fResult=FALSE;
BYTE *pbEncoded=NULL;
DWORD cbEncoded=0;
//get the blob
if (S_OK != RetrieveBLOBFromFile(wszStoreName,&cbEncoded, &pbEncoded))
return FALSE;
//base64 decode. ascii version
if(S_OK != Base64ToBytes((CHAR *)pbEncoded, cbEncoded,
ppbByte, pcbByte))
{
//WCHAR version
if(cbEncoded %2 == 0)
{
if(S_OK !=Base64ToBytesW((WCHAR *)pbEncoded, cbEncoded/2,
ppbByte, pcbByte))
goto CLEANUP;
}
else
{
goto CLEANUP;
}
}
fResult=TRUE;
CLEANUP:
if(pbEncoded)
UnmapViewOfFile(pbEncoded);
return fResult;
}
//------------------------------------------------------------------------------------
//
// Attempt to read as a file containing an encoded CRL.
//
//------------------------------------------------------------------------------------
HCERTSTORE OpenEncodedCRL(LPWSTR pwszStoreFilename)
{
HCERTSTORE hStore=NULL;
BYTE *pbEncoded;
DWORD cbEncoded;
if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded,&pbEncoded))
return NULL;
if (NULL == (hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)))
goto CommonReturn;
if (!CertAddEncodedCRLToStore(
hStore,
g_dwCertEncodingType,
pbEncoded,
cbEncoded,
CERT_STORE_ADD_ALWAYS,
NULL // ppCrlContext
))
{
CertCloseStore(hStore, 0);
hStore = NULL;
}
CommonReturn:
if(pbEncoded)
UnmapViewOfFile(pbEncoded);
return hStore;
}
//------------------------------------------------------------------------------------
//
// Attempt to read as a file containing an encoded CER.
//
//------------------------------------------------------------------------------------
HCERTSTORE OpenEncodedCert (LPWSTR pwszStoreFilename)
{
HCERTSTORE hStore;
BYTE *pbEncoded;
DWORD cbEncoded;
if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded, &pbEncoded))
return NULL;
if (NULL == (hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)))
goto CommonReturn;
if (!CertAddEncodedCertificateToStore(
hStore,
g_dwMsgAndCertEncodingType,
pbEncoded,
cbEncoded,
CERT_STORE_ADD_ALWAYS,
NULL // ppCtlContext
))
{
CertCloseStore(hStore, 0);
hStore = NULL;
}
CommonReturn:
if(pbEncoded)
UnmapViewOfFile(pbEncoded);
return hStore;
}
//------------------------------------------------------------------------------------
//
// Attempt to read as a file containing an encoded CTL.
//
//------------------------------------------------------------------------------------
HCERTSTORE OpenEncodedCTL (LPWSTR pwszStoreFilename)
{
HCERTSTORE hStore;
BYTE *pbEncoded;
DWORD cbEncoded;
if (S_OK != RetrieveBLOBFromFile(pwszStoreFilename, &cbEncoded, &pbEncoded))
return NULL;
if (NULL == (hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)))
goto CommonReturn;
if (!CertAddEncodedCTLToStore(
hStore,
g_dwMsgAndCertEncodingType,
pbEncoded,
cbEncoded,
CERT_STORE_ADD_ALWAYS,
NULL // ppCtlContext
))
{
CertCloseStore(hStore, 0);
hStore = NULL;
}
CommonReturn:
if(pbEncoded)
UnmapViewOfFile(pbEncoded);
return hStore;
}
//--------------------------------------------------------------------------------
// Set the parameters. They can only be set once
//--------------------------------------------------------------------------------
BOOL SetParam(WCHAR **ppwszParam, WCHAR *pwszValue)
{
if(*ppwszParam!=NULL)
{
IDSwprintf(hModule,IDS_ERR_TOO_MANY_PARAM);
return FALSE;
}
*ppwszParam=pwszValue;
return TRUE;
}
//--------------------------------------------------------------------------------
// Convert an array of wchars to a BLOB
//--------------------------------------------------------------------------------
HRESULT WSZtoBLOB(LPWSTR pwsz, BYTE **ppbByte, DWORD *pcbByte)
{
HRESULT hr=E_FAIL;
DWORD dwIndex=0;
ULONG ulHalfByte=0;
DWORD dw1st=0;
DWORD dw2nd=0;
if((!pwsz) || (!ppbByte) || (!pcbByte))
return E_INVALIDARG;
*ppbByte=NULL;
*pcbByte=0;
//make sure the pwsz consists of 20 characters
if(wcslen(pwsz)!= 2*SHA1_LENGTH)
return E_FAIL;
//memory allocation
*ppbByte=(BYTE *)ToolUtlAlloc(SHA1_LENGTH);
if(NULL==(*ppbByte))
return E_INVALIDARG;
memset(*ppbByte, 0, SHA1_LENGTH);
//go through two characters (one byte) at a time
for(dwIndex=0; dwIndex<SHA1_LENGTH; dwIndex++)
{
dw1st=dwIndex * 2;
dw2nd=dwIndex * 2 +1;
//1st character
if(((int)(pwsz[dw1st])-(int)(L'0')) <=9 &&
((int)(pwsz[dw1st])-(int)(L'0')) >=0)
{
ulHalfByte=(ULONG)((ULONG)(pwsz[dw1st])-(ULONG)(L'0'));
}
else
{
if(((int)(towupper(pwsz[dw1st]))-(int)(L'A')) >=0 &&
((int)(towupper(pwsz[dw1st]))-(int)(L'A')) <=5 )
ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw1st]))-(ULONG)(L'A'));
else
{
hr=E_INVALIDARG;
goto CLEANUP;
}
}
//copy the 1st character
(*ppbByte)[dwIndex]=(BYTE)ulHalfByte;
//left shift 4 bits
(*ppbByte)[dwIndex]= (*ppbByte)[dwIndex] <<4;
//2nd character
if(((int)(pwsz[dw2nd])-(int)(L'0')) <=9 &&
((int)(pwsz[dw2nd])-(int)(L'0')) >=0)
{
ulHalfByte=(ULONG)((ULONG)(pwsz[dw2nd])-(ULONG)(L'0'));
}
else
{
if(((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) >=0 &&
((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) <=5 )
ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw2nd]))-(ULONG)(L'A'));
else
{
hr=E_INVALIDARG;
goto CLEANUP;
}
}
//ORed the second character
(*ppbByte)[dwIndex]=(*ppbByte)[dwIndex] | ((BYTE)ulHalfByte);
}
hr=S_OK;
CLEANUP:
if(hr!=S_OK)
{
if(*ppbByte)
ToolUtlFree(*ppbByte);
*ppbByte=NULL;
}
else
*pcbByte=SHA1_LENGTH;
return hr;
}
//+-------------------------------------------------------------------------
// Skip over the identifier and length octets in an ASN encoded blob.
// Returns the number of bytes skipped.
//
// For an invalid identifier or length octet returns 0.
//--------------------------------------------------------------------------
DWORD SkipOverIdentifierAndLengthOctets(
IN const BYTE *pbDER,
IN DWORD cbDER
)
{
#define TAG_MASK 0x1f
DWORD cb;
DWORD cbLength;
const BYTE *pb = pbDER;
// Need minimum of 2 bytes
if (cbDER < 2)
return 0;
// Skip over the identifier octet(s)
if (TAG_MASK == (*pb++ & TAG_MASK)) {
// high-tag-number form
for (cb=2; *pb++ & 0x80; cb++) {
if (cb >= cbDER)
return 0;
}
} else
// low-tag-number form
cb = 1;
// need at least one more byte for length
if (cb >= cbDER)
return 0;
if (0x80 == *pb)
// Indefinite
cb++;
else if ((cbLength = *pb) & 0x80) {
cbLength &= ~0x80; // low 7 bits have number of bytes
cb += cbLength + 1;
if (cb > cbDER)
return 0;
} else
cb++;
return cb;
}
//--------------------------------------------------------------------------
//
// Skip over the tag and length
//----------------------------------------------------------------------------
BOOL SignNoContentWrap(IN const BYTE *pbDER, IN DWORD cbDER)
{
DWORD cb;
cb = SkipOverIdentifierAndLengthOctets(pbDER, cbDER);
if (cb > 0 && cb < cbDER && pbDER[cb] == 0x02)
return TRUE;
else
return FALSE;
}
//--------------------------------------------------------------------------
//
// Print out bytes
//--------------------------------------------------------------------------
#define CROW 16
void PrintBytes(LPWSTR pwszHdr, BYTE *pb, DWORD cbSize)
{
ULONG cb, i;
if (cbSize == 0)
{
//"%s NO Value Bytes\n"
IDSwprintf(hModule, IDS_NO_BYTE,pwszHdr);
return;
}
while (cbSize > 0)
{
wprintf(L"%s", pwszHdr);
cb = min(CROW, cbSize);
cbSize -= cb;
for (i = 0; i<cb; i++)
wprintf(L" %02X", pb[i]);
for (i = cb; i<CROW; i++)
wprintf(L" ");
wprintf(L" '");
for (i = 0; i<cb; i++)
if (pb[i] >= 0x20 && pb[i] <= 0x7f)
wprintf(L"%c", pb[i]);
else
wprintf(L".");
pb += cb;
wprintf(L"'\n");
}
}
//+-------------------------------------------------------------------------
// Allocates and returns the specified cryptographic message parameter.
//--------------------------------------------------------------------------
void PrintAttributes(DWORD cAttr, PCRYPT_ATTRIBUTE pAttr,
DWORD dwItem)
{
DWORD i;
DWORD j;
LPWSTR pwszObjId=NULL;
for (i = 0; i < cAttr; i++, pAttr++)
{
DWORD cValue = pAttr->cValue;
PCRYPT_ATTR_BLOB pValue = pAttr->rgValue;
LPSTR pszObjId = pAttr->pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
if (cValue)
{
for (j = 0; j < cValue; j++, pValue++)
{
printf(" [%d,%d] %s\n", i, j, pszObjId);
if (pValue->cbData)
{
if(dwItem & ITEM_VERBOSE)
PrintBytes(L" ", pValue->pbData, pValue->cbData);
if (strcmp(pszObjId, szOID_NEXT_UPDATE_LOCATION) == 0)
{
//" NextUpdateLocation::\n"
IDSwprintf(hModule, IDS_NEXT_UPDATE_LOCATION);
DecodeAndDisplayAltName(pValue->pbData, pValue->cbData,
dwItem);
}
//Display the timestamp attriute
if(strcmp(pszObjId, szOID_RSA_counterSign)==0)
{
//" Timestamp:: \n"
IDSwprintf(hModule, IDS_TIMESTMAP);
DisplayTimeStamp(pValue->pbData,
pValue->cbData,
dwItem);
}
//Display the signing time
if(strcmp(pszObjId, szOID_RSA_signingTime)==0)
{
FILETIME *pSigningTime=NULL;
if(pSigningTime=(FILETIME *)TestNoCopyDecodeObject(
PKCS_UTC_TIME,
pValue->pbData,
pValue->cbData))
{
//" Signing Time:: \n %s\n"
IDSwprintf(hModule, IDS_SIGNING_TIME,
FileTimeText(pSigningTime));
ToolUtlFree(pSigningTime);
}
}
}
else
//" NO Value Bytes\n"
IDSwprintf(hModule, IDS_NO_VALUE_BYTES);
}
}
else
{
if(S_OK==SZtoWSZ(pszObjId, &pwszObjId))
//" [%d] %s :: No Values\n"
IDSwprintf(hModule, IDS_I_ID_NO_VALUE, i, pwszObjId);
}
}
if(pwszObjId)
ToolUtlFree(pwszObjId);
}
//+-------------------------------------------------------------------------
// DecodeAndDisplayAltName
//--------------------------------------------------------------------------
void DecodeAndDisplayAltName(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_ALT_NAME_INFO pInfo = NULL;
if (NULL == (pInfo = (PCERT_ALT_NAME_INFO) TestNoCopyDecodeObject(
X509_ALTERNATE_NAME,
pbEncoded,
cbEncoded
))) goto CommonReturn;
DisplayAltName(pInfo, dwDisplayFlags);
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// Display AltName
//--------------------------------------------------------------------------
void DisplayAltName(
PCERT_ALT_NAME_INFO pInfo,
DWORD dwDisplayFlags)
{
DWORD i;
PCERT_ALT_NAME_ENTRY pEntry = pInfo->rgAltEntry;
DWORD cEntry = pInfo->cAltEntry;
for (i = 0; i < cEntry; i++, pEntry++) {
wprintf(L" [%d] ", i);
DisplayAltNameEntry(pEntry, dwDisplayFlags);
}
}
//+-------------------------------------------------------------------------
// Display an alternative name entry
//--------------------------------------------------------------------------
void DisplayAltNameEntry(
PCERT_ALT_NAME_ENTRY pEntry,
DWORD dwDisplayFlags)
{
switch (pEntry->dwAltNameChoice) {
case CERT_ALT_NAME_OTHER_NAME:
//"OtherName:\n"
IDSwprintf(hModule, IDS_OTHER_NAME);
break;
case CERT_ALT_NAME_X400_ADDRESS:
//"X400Address:\n");
IDSwprintf(hModule, IDS_X400);
break;
case CERT_ALT_NAME_DIRECTORY_NAME:
//("DirectoryName:\n");
IDSwprintf(hModule, IDS_DIRECTORY_NAME);
DecodeName(pEntry->DirectoryName.pbData,
pEntry->DirectoryName.cbData, dwDisplayFlags);
break;
case CERT_ALT_NAME_EDI_PARTY_NAME:
//"EdiPartyName:\n"
IDSwprintf(hModule, IDS_EDI_PARTY);
break;
case CERT_ALT_NAME_RFC822_NAME:
//"RFC822: %s\n"
IDSwprintf(hModule, IDS_RFC,pEntry->pwszRfc822Name );
break;
case CERT_ALT_NAME_DNS_NAME:
//"DNS: %s\n",
IDSwprintf(hModule, IDS_DNS, pEntry->pwszDNSName);
break;
case CERT_ALT_NAME_URL:
//"URL: %s\n"
IDSwprintf(hModule, IDS_ALT_NAME_URL,pEntry->pwszURL);
break;
case CERT_ALT_NAME_IP_ADDRESS:
//"IPAddress:\n"
IDSwprintf(hModule, IDS_IP);
PrintBytes(L" ", pEntry->IPAddress.pbData, pEntry->IPAddress.cbData);
break;
case CERT_ALT_NAME_REGISTERED_ID:
//"RegisteredID:",
IDSwprintf(hModule, IDS_REG_ID);
printf("%s\n", pEntry->pszRegisteredID);
break;
default:
//"Unknown choice: %d\n"
IDSwprintf(hModule, IDS_UNKNOWN_ALT_NAME,pEntry->dwAltNameChoice);
}
}
//+-------------------------------------------------------------------------
// Display an alternative name entry
//--------------------------------------------------------------------------
void DisplayThumbprint(
LPWSTR pwszHash,
BYTE *pbHash,
DWORD cbHash
)
{
//"%s Thumbprint:: "
IDSwprintf(hModule, IDS_Thumbprint, pwszHash);
if (cbHash == 0)
printf("%s", g_szNULL);
else
{
ULONG cb;
while (cbHash > 0) {
cb = min(4, cbHash);
cbHash -= cb;
for (; cb > 0; cb--, pbHash++)
printf("%02X", *pbHash);
printf(" ");
}
}
printf("\n");
}
//+-------------------------------------------------------------------------
// Print out the FileTime
//--------------------------------------------------------------------------
LPWSTR FileTimeText(FILETIME *pft)
{
static WCHAR wszbuf[100];
FILETIME ftLocal;
struct tm ctm;
SYSTEMTIME st;
WCHAR wszFileTime[50];
WCHAR wszMilliSecond[50];
//init
wszbuf[0]=L'\0';
//check if the time is available
if((pft->dwLowDateTime==0) &&
(pft->dwHighDateTime==0))
{
LoadStringU(hModule, IDS_NOT_AVAILABLE, wszbuf, 100);
return wszbuf;
}
//load the string we need
//" <milliseconds:: %03d>"
//"<FILETIME %08lX:%08lX>"
if(!LoadStringU(hModule, IDS_FILE_TIME, wszFileTime, 50) ||
!LoadStringU(hModule, IDS_MILLI_SECOND, wszMilliSecond, 50))
return wszbuf;
FileTimeToLocalFileTime(pft, &ftLocal);
if (FileTimeToSystemTime(&ftLocal, &st))
{
ctm.tm_sec = st.wSecond;
ctm.tm_min = st.wMinute;
ctm.tm_hour = st.wHour;
ctm.tm_mday = st.wDay;
ctm.tm_mon = st.wMonth-1;
ctm.tm_year = st.wYear-1900;
ctm.tm_wday = st.wDayOfWeek;
ctm.tm_yday = 0;
ctm.tm_isdst = 0;
wcscpy(wszbuf, _wasctime(&ctm));
wszbuf[wcslen(wszbuf)-1] = 0;
if (st.wMilliseconds)
{
WCHAR *pwch = wszbuf + wcslen(wszbuf);
swprintf(pwch, wszMilliSecond, st.wMilliseconds);
}
}
else
swprintf(wszbuf, wszFileTime, pft->dwHighDateTime, pft->dwLowDateTime);
return wszbuf;
}
//+-------------------------------------------------------------------------
// Print other cer properies
//--------------------------------------------------------------------------
void PrintAuxCertProperties(PCCERT_CONTEXT pCert, DWORD dwDisplayFlags)
{
DWORD dwPropId = 0;
while (dwPropId = CertEnumCertificateContextProperties(pCert, dwPropId))
{
switch (dwPropId)
{
case CERT_KEY_PROV_INFO_PROP_ID:
case CERT_SHA1_HASH_PROP_ID:
case CERT_MD5_HASH_PROP_ID:
case CERT_KEY_CONTEXT_PROP_ID:
// Formatted elsewhere
break;
default:
{
BYTE *pbData;
DWORD cbData;
//"Aux PropId %d (0x%x) ::\n"
IDSwprintf(hModule, IDS_AUX_PROP_ID, dwPropId, dwPropId);
CertGetCertificateContextProperty(
pCert,
dwPropId,
NULL, // pvData
&cbData
);
if (cbData)
{
if (pbData = (BYTE *) ToolUtlAlloc(cbData))
{
if (CertGetCertificateContextProperty(
pCert,
dwPropId,
pbData,
&cbData
))
{
PrintBytes(L" ", pbData, cbData);
if (CERT_CTL_USAGE_PROP_ID == dwPropId)
{
// " EnhancedKeyUsage::\n"
IDSwprintf(hModule, IDS_ENHANCED_KEY_USAGE);
DecodeAndDisplayCtlUsage(pbData, cbData,
dwDisplayFlags);
}
}
ToolUtlFree(pbData);
}
}
else
//" NO Property Bytes\n"
IDSwprintf(hModule, IDS_NO_PROP_BYTES);
}
break;
}
}
}
//+-------------------------------------------------------------------------
// DecodeAndDisplayCtlUsage
//--------------------------------------------------------------------------
void DecodeAndDisplayCtlUsage(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCTL_USAGE pInfo;
DWORD cId;
LPSTR *ppszId;
DWORD i;
if (NULL == (pInfo =
(PCTL_USAGE) TestNoCopyDecodeObject(
X509_ENHANCED_KEY_USAGE,
pbEncoded,
cbEncoded
))) goto CLEANUP;
cId = pInfo->cUsageIdentifier;
ppszId = pInfo->rgpszUsageIdentifier;
if (cId == 0)
//" No Usage Identifiers\n"
IDSwprintf(hModule, IDS_NO_USAGE_ID);
for (i = 0; i < cId; i++, ppszId++)
printf(" [%d] %s\n", i, *ppszId);
CLEANUP:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplaySignature
//--------------------------------------------------------------------------
void DisplaySignature(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags
)
{
PCERT_SIGNED_CONTENT_INFO pSignedContent;
if (pSignedContent = (PCERT_SIGNED_CONTENT_INFO) TestNoCopyDecodeObject(
X509_CERT,
pbEncoded,
cbEncoded
))
{
LPSTR pszObjId;
pszObjId = pSignedContent->SignatureAlgorithm.pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
//"Content SignatureAlgorithm::
IDSwprintf(hModule, IDS_CONTENT_SIG_ALGO);
printf("%s (%S)\n",
pszObjId, GetOIDName(pszObjId, CRYPT_SIGN_ALG_OID_GROUP_ID));
if (pSignedContent->SignatureAlgorithm.Parameters.cbData)
{
//"Content SignatureAlgorithm.Parameters::\n"
IDSwprintf(hModule, IDS_CONTENT_SIG_ALGO_PARAM);
PrintBytes(L" ",
pSignedContent->SignatureAlgorithm.Parameters.pbData,
pSignedContent->SignatureAlgorithm.Parameters.cbData);
}
if (pSignedContent->Signature.cbData)
{
ALG_ID aiHash;
ALG_ID aiPubKey;
//"Content Signature (little endian)::\n"
IDSwprintf(hModule, IDS_CONTEXT_SIG);
PrintBytes(L" ", pSignedContent->Signature.pbData,
pSignedContent->Signature.cbData);
GetSignAlgids(pszObjId, &aiHash, &aiPubKey);
if (CALG_SHA == aiHash && CALG_DSS_SIGN == aiPubKey)
{
BYTE *pbDssSignature;
DWORD cbDssSignature;
ReverseBytes(pSignedContent->Signature.pbData,
pSignedContent->Signature.cbData);
if (pbDssSignature =
(BYTE *) TestNoCopyDecodeObject(
X509_DSS_SIGNATURE,
pSignedContent->Signature.pbData,
pSignedContent->Signature.cbData,
&cbDssSignature
)) {
if (CERT_DSS_SIGNATURE_LEN == cbDssSignature)
{
//"DSS R (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_R);
PrintBytes(L" ", pbDssSignature, CERT_DSS_R_LEN);
//"DSS S (little endian)::\n"
IDSwprintf(hModule, IDS_DSS_S);
PrintBytes(L" ", pbDssSignature + CERT_DSS_R_LEN,
CERT_DSS_S_LEN);
}
else
{
//"DSS Signature (unexpected length, little endian)::\n"
IDSwprintf(hModule, IDS_DSS_INFO);
PrintBytes(L" ", pbDssSignature, cbDssSignature);
}
ToolUtlFree(pbDssSignature);
}
}
} else
//"Content Signature:: NONE\n"
IDSwprintf(hModule, IDS_CONTENT_SIG_NONE);
ToolUtlFree(pSignedContent);
}
}
//+-------------------------------------------------------------------------
// Decode an X509 Name
//--------------------------------------------------------------------------
BOOL DecodeName(BYTE *pbEncoded, DWORD cbEncoded, DWORD dwDisplayFlags)
{
BOOL fResult;
PCERT_NAME_INFO pInfo = NULL;
DWORD i,j;
PCERT_RDN pRDN;
PCERT_RDN_ATTR pAttr;
if (NULL == (pInfo = (PCERT_NAME_INFO) TestNoCopyDecodeObject
(
X509_NAME,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
for (i = 0, pRDN = pInfo->rgRDN; i < pInfo->cRDN; i++, pRDN++)
{
for (j = 0, pAttr = pRDN->rgRDNAttr; j < pRDN->cRDNAttr; j++, pAttr++)
{
LPSTR pszObjId = pAttr->pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
if ((dwDisplayFlags & ITEM_VERBOSE) ||
(pAttr->dwValueType == CERT_RDN_ENCODED_BLOB) ||
(pAttr->dwValueType == CERT_RDN_OCTET_STRING))
{
printf(" [%d,%d] %s (%S) ", i, j, pszObjId, GetOIDName(pszObjId));
//ValueType: %d\n"
IDSwprintf(hModule, IDS_VALUE_TYPE, pAttr->dwValueType);
PrintBytes(L" ", pAttr->Value.pbData, pAttr->Value.cbData);
} else if (pAttr->dwValueType == CERT_RDN_UNIVERSAL_STRING)
{
printf(" [%d,%d] %s (%S)",
i, j, pszObjId, GetOIDName(pszObjId));
DWORD cdw = pAttr->Value.cbData / 4;
DWORD *pdw = (DWORD *) pAttr->Value.pbData;
for ( ; cdw > 0; cdw--, pdw++)
printf(" 0x%08X", *pdw);
printf("\n");
DWORD csz;
csz = CertRDNValueToStrA(
pAttr->dwValueType,
&pAttr->Value,
NULL, // psz
0 // csz
);
if (csz > 1)
{
LPSTR psz = (LPSTR) ToolUtlAlloc(csz);
if (psz)
{
CertRDNValueToStrA(
pAttr->dwValueType,
&pAttr->Value,
psz,
csz
);
//" Str: "
IDSwprintf(hModule, IDS_STR);
printf("%s\n", psz);
ToolUtlFree(psz);
}
}
DWORD cwsz;
cwsz = CertRDNValueToStrW(
pAttr->dwValueType,
&pAttr->Value,
NULL, // pwsz
0 // cwsz
);
if (cwsz > 1)
{
LPWSTR pwsz =
(LPWSTR) ToolUtlAlloc(cwsz * sizeof(WCHAR));
if (pwsz)
{
CertRDNValueToStrW(
pAttr->dwValueType,
&pAttr->Value,
pwsz,
cwsz
);
//" WStr: %S\n"
IDSwprintf(hModule, IDS_WSTR, pwsz);
ToolUtlFree(pwsz);
}
}
} else if (pAttr->dwValueType == CERT_RDN_BMP_STRING)
{
printf(" [%d,%d] %s (%S) %S\n",
i, j, pszObjId, GetOIDName(pszObjId), (LPWSTR) pAttr->Value.pbData);
} else
printf(" [%d,%d] %s (%S) %s\n",
i, j, pszObjId, GetOIDName(pszObjId), pAttr->Value.pbData);
}
}
fResult = TRUE;
goto CommonReturn;
ErrorReturn:
fResult = FALSE;
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
return fResult;
}
//+-------------------------------------------------------------------------
// PrintExtensions
//--------------------------------------------------------------------------
void PrintExtensions(DWORD cExt, PCERT_EXTENSION pExt, DWORD dwDisplayFlags)
{
DWORD i;
for (i = 0; i < cExt; i++, pExt++)
{
LPSTR pszObjId = pExt->pszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
int idsCritical = pExt->fCritical ? IDS_TRUE : IDS_FALSE;
//print the end of line
printf("\n");
//"Extension[%d] "
IDSwprintf(hModule, IDS_EXTENSION_INDEX, i);
printf("%s", pszObjId);
//(%s) Critical: ",
IDSwprintf(hModule, IDS_NAME_CRITICAL, GetOIDName(pszObjId));
//"%s::\n"
IDS_IDSwprintf(hModule, IDS_STRING, idsCritical);
//print bytes on verbose options
if(dwDisplayFlags & ITEM_VERBOSE)
PrintBytes(L" ", pExt->Value.pbData, pExt->Value.cbData);
//try the installed formatting routine 1st
if(TRUE==InstalledFormat(pszObjId, pExt->Value.pbData, pExt->Value.cbData))
continue;
if (strcmp(pszObjId, szOID_AUTHORITY_KEY_IDENTIFIER) == 0)
DisplayAuthorityKeyIdExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_AUTHORITY_KEY_IDENTIFIER2) == 0)
DisplayAuthorityKeyId2Extension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
// Will add back after PKIX stabilizes on the definition of this extension
// else if (strcmp(pszObjId, szOID_AUTHORITY_INFO_ACCESS) == 0)
// DisplayAuthorityInfoAccessExtension(
// pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_CRL_DIST_POINTS) == 0)
DisplayCrlDistPointsExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_SUBJECT_KEY_IDENTIFIER) == 0)
//" <SubjectKeyIdentifer> \n"
DisplayOctetString(IDS_SUB_KEY_ID,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_KEY_ATTRIBUTES) == 0)
DisplayKeyAttrExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_SUBJECT_ALT_NAME) == 0)
//" <Subject AltName> \n"
DisplayAltNameExtension(IDS_SUB_ALT,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME) == 0)
//" <Issuer AltName> \n"
DisplayAltNameExtension(IDS_ISS_ALT,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_SUBJECT_ALT_NAME2) == 0)
//" <Subject AltName #2> \n"
DisplayAltNameExtension(IDS_SUB_ALT2,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME2) == 0)
//" <Issuer AltName #2> \n"
DisplayAltNameExtension(IDS_ISS_ALT2,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NEXT_UPDATE_LOCATION) == 0)
//" <NextUpdateLocation> \n"
DisplayAltNameExtension(IDS_NEXT_UPDATE_LOC,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_KEY_USAGE_RESTRICTION) == 0)
DisplayKeyUsageRestrictionExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_BASIC_CONSTRAINTS) == 0)
DisplayBasicConstraintsExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_KEY_USAGE) == 0)
DisplayKeyUsageExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_BASIC_CONSTRAINTS2) == 0)
DisplayBasicConstraints2Extension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_CERT_POLICIES) == 0)
//" <Certificate Policies> \n"
DisplayPoliciesExtension(IDS_CERT_POLICIES,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, SPC_SP_AGENCY_INFO_OBJID) == 0)
DisplaySpcSpAgencyExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, SPC_FINANCIAL_CRITERIA_OBJID) == 0)
DisplaySpcFinancialCriteriaExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, SPC_MINIMAL_CRITERIA_OBJID) == 0)
DisplaySpcMinimalCriteriaExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_COMMON_NAME) == 0)
DisplayCommonNameExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_ENHANCED_KEY_USAGE) == 0)
DisplayEnhancedKeyUsageExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_RSA_SMIMECapabilities) == 0)
DisplaySMIMECapabilitiesExtension(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
// CRL extensions
else if (strcmp(pszObjId, szOID_CRL_REASON_CODE) == 0)
DisplayCRLReason(
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
// Netscape extensions
else if (strcmp(pszObjId, szOID_NETSCAPE_CERT_TYPE) == 0)
//" <NetscapeCertType> \n"
DisplayBits(IDS_NSCP_CERT,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_BASE_URL) == 0)
//" <NetscapeBaseURL> \n"
DisplayAnyString(IDS_NSCP_BASE,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_REVOCATION_URL) == 0)
//" <NetscapeRevocationURL> \n"
DisplayAnyString(IDS_NSCP_REV,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_CA_REVOCATION_URL) == 0)
//" <NetscapeCARevocationURL> \n"
DisplayAnyString(IDS_NSCP_CA_REV,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_CERT_RENEWAL_URL) == 0)
//" <NetscapeCertRenewalURL> \n"
DisplayAnyString(IDS_NSCP_RENEW,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_CA_POLICY_URL) == 0)
//" <NetscapeCAPolicyURL> \n"
DisplayAnyString(IDS_NSCP_CA_URL,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_SSL_SERVER_NAME) == 0)
//" <NetscapeSSLServerName> \n"
DisplayAnyString(IDS_NSCP_SSL,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if (strcmp(pszObjId, szOID_NETSCAPE_COMMENT) == 0)
//" <NetscapeComment> \n"
DisplayAnyString(IDS_NSCP_COM,
pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags);
else if(0==(dwDisplayFlags & ITEM_VERBOSE))
PrintBytes(L" ", pExt->Value.pbData, pExt->Value.cbData);
}
}
//+-------------------------------------------------------------------------
// DisplaySMIMECapabilitiesExtension
//--------------------------------------------------------------------------
void DisplaySMIMECapabilitiesExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCRYPT_SMIME_CAPABILITIES pInfo;
DWORD cCap;
PCRYPT_SMIME_CAPABILITY pCap;
DWORD i;
if (NULL == (pInfo =
(PCRYPT_SMIME_CAPABILITIES) TestNoCopyDecodeObject(
PKCS_SMIME_CAPABILITIES,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
cCap = pInfo->cCapability;
pCap = pInfo->rgCapability;
//" <SMIME Capabilties>\n"
IDSwprintf(hModule, IDS_SMIME);
if (cCap == 0)
IDSwprintf(hModule, IDS_NONE);
for (i = 0; i < cCap; i++, pCap++)
{
LPSTR pszObjId = pCap->pszObjId;
printf(" [%d] %s (%S)", i, pszObjId, GetOIDName(pszObjId));
if (pCap->Parameters.cbData)
{
//" Parameters::\n"
IDSwprintf(hModule, IDS_PARAMS);
PrintBytes(L" ",
pCap->Parameters.pbData,
pCap->Parameters.cbData);
} else
printf("\n");
}
ErrorReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayEnhancedKeyUsageExtension
//--------------------------------------------------------------------------
void DisplayEnhancedKeyUsageExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
//" <EnhancedKeyUsage> \n");
IDSwprintf(hModule, IDS_ENH_KEY_USAGE);
DecodeAndDisplayCtlUsage(pbEncoded, cbEncoded, dwDisplayFlags);
}
//+-------------------------------------------------------------------------
// DisplaySpcFinancialCriteriaExtension
//--------------------------------------------------------------------------
void DisplayCommonNameExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_NAME_VALUE pInfo = NULL;
LPWSTR pwsz = NULL;
DWORD cwsz;
if (NULL == (pInfo = (PCERT_NAME_VALUE) TestNoCopyDecodeObject(
X509_NAME_VALUE,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//" <Common Name> \n"
IDSwprintf(hModule, IDS_COMMON_NAME);
cwsz = CertRDNValueToStrW(
pInfo->dwValueType,
&pInfo->Value,
NULL, // pwsz
0 // cwsz
);
if (cwsz > 1)
{
pwsz = (LPWSTR)ToolUtlAlloc(cwsz * sizeof(WCHAR));
if (pwsz)
CertRDNValueToStrW(
pInfo->dwValueType,
&pInfo->Value,
pwsz,
cwsz
);
}
//" ValueType: %d String: ",
IDSwprintf(hModule, IDS_VALUE_STRING, pInfo->dwValueType);
if (pwsz)
wprintf(L"%s", pwsz);
else
IDSwprintf(hModule, IDS_NULL);
printf("\n");
goto CommonReturn;
ErrorReturn:
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
if (pwsz)
ToolUtlFree(pwsz);
}
//+-------------------------------------------------------------------------
// DisplaySpcFinancialCriteriaExtension
//--------------------------------------------------------------------------
void DisplaySpcFinancialCriteriaExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
SPC_FINANCIAL_CRITERIA FinancialCriteria;
DWORD cbInfo = sizeof(FinancialCriteria);
if (!CryptDecodeObject(
g_dwCertEncodingType,
SPC_FINANCIAL_CRITERIA_OBJID,
pbEncoded,
cbEncoded,
0, // dwFlags
&FinancialCriteria,
&cbInfo
)) {
return;
}
//" <FinancialCriteria> \n "
IDSwprintf(hModule, IDS_FIN_CRI);
if (FinancialCriteria.fFinancialInfoAvailable)
//"Financial Info Available.");
IDSwprintf(hModule, IDS_FIN_AVAI);
else
IDSwprintf(hModule, IDS_NONE);
if (FinancialCriteria.fMeetsCriteria)
//" Meets Criteria."
IDSwprintf(hModule, IDS_MEET_CRI);
else
//" Doesn't Meets Criteria."
IDSwprintf(hModule, IDS_NO_MEET_CRI);
printf("\n");
}
//+-------------------------------------------------------------------------
// DisplaySpcMinimalCriteriaExtension
//--------------------------------------------------------------------------
void DisplaySpcMinimalCriteriaExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
BOOL fMinimalCriteria;
DWORD cbInfo = sizeof(fMinimalCriteria);
if (!CryptDecodeObject(
g_dwCertEncodingType,
SPC_MINIMAL_CRITERIA_OBJID,
pbEncoded,
cbEncoded,
0, // dwFlags
&fMinimalCriteria,
&cbInfo)) {
return;
}
//" <MinimalCriteria> \n ");
IDSwprintf(hModule, IDS_MIN_CRI);
if (fMinimalCriteria)
//"Meets Minimal Criteria."
IDSwprintf(hModule, IDS_MEET_MIN);
else
//"Doesn't Meet Minimal Criteria."
IDSwprintf(hModule, IDS_NO_MEET_MIN);
printf("\n");
}
//+-------------------------------------------------------------------------
// DisplaySpcLink
//--------------------------------------------------------------------------
void DisplaySpcLink(PSPC_LINK pSpcLink)
{
switch (pSpcLink->dwLinkChoice)
{
case SPC_URL_LINK_CHOICE:
//"URL=> %S\n", );
IDSwprintf(hModule, IDS_SPC_URL, pSpcLink->pwszUrl);
break;
case SPC_MONIKER_LINK_CHOICE:
wprintf(L"%s\n", GuidText((GUID *) pSpcLink->Moniker.ClassId));
if (pSpcLink->Moniker.SerializedData.cbData)
{
//" SerializedData::\n");
IDSwprintf(hModule, IDS_SERIAL_DATA);
PrintBytes(L" ", pSpcLink->Moniker.SerializedData.pbData,
pSpcLink->Moniker.SerializedData.cbData);
}
break;
case SPC_FILE_LINK_CHOICE:
//"FILE=> %S\n",
IDSwprintf(hModule, IDS_SPC_FILE,pSpcLink->pwszFile);
break;
default:
//"Unknown SPC Link Choice:: %d\n",
IDSwprintf(hModule, IDS_UNKNOWN_SPC, pSpcLink->dwLinkChoice);
}
}
//+-------------------------------------------------------------------------
// DisplaySpcSpAgencyExtension
//--------------------------------------------------------------------------
void DisplaySpcSpAgencyExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PSPC_SP_AGENCY_INFO pInfo;
if (NULL == (pInfo = (PSPC_SP_AGENCY_INFO) TestNoCopyDecodeObject(
SPC_SP_AGENCY_INFO_OBJID,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//" <SpcSpAgencyInfo> \n");
IDSwprintf(hModule, IDS_SPC_AGENCY);
if (pInfo->pPolicyInformation)
{
//" PolicyInformation: "
IDSwprintf(hModule, IDS_POL_INFO);
DisplaySpcLink(pInfo->pPolicyInformation);
}
if (pInfo->pwszPolicyDisplayText)
{
//" PolicyDisplayText: %s\n",
IDSwprintf(hModule, IDS_POL_DIS, pInfo->pwszPolicyDisplayText);
}
if (pInfo->pLogoImage)
{
PSPC_IMAGE pImage = pInfo->pLogoImage;
if (pImage->pImageLink)
{
//" ImageLink: ");
IDSwprintf(hModule, IDS_IMG_LINK);
DisplaySpcLink(pImage->pImageLink);
}
if (pImage->Bitmap.cbData)
{
//" Bitmap:\n");
IDSwprintf(hModule, IDS_BITMAP);
PrintBytes(L" ", pImage->Bitmap.pbData, pImage->Bitmap.cbData);
}
if (pImage->Metafile.cbData)
{
//" Metafile:\n");
IDSwprintf(hModule, IDS_META_FILE);
PrintBytes(L" ", pImage->Metafile.pbData,
pImage->Metafile.cbData);
}
if (pImage->EnhancedMetafile.cbData)
{
//" EnhancedMetafile:\n");
IDSwprintf(hModule, IDS_ENH_META);
PrintBytes(L" ", pImage->EnhancedMetafile.pbData,
pImage->EnhancedMetafile.cbData);
}
if (pImage->GifFile.cbData)
{
//" GifFile:\n"
IDSwprintf(hModule, IDS_GIF_FILE);
PrintBytes(L" ", pImage->GifFile.pbData,
pImage->GifFile.cbData);
}
}
if (pInfo->pLogoLink)
{
//" LogoLink: ");
IDSwprintf(hModule, IDS_LOGO_LINK);
DisplaySpcLink(pInfo->pLogoLink);
}
goto CommonReturn;
ErrorReturn:
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayPoliciesExtension
//--------------------------------------------------------------------------
void DisplayPoliciesExtension(
int idsIDS,
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_POLICIES_INFO pInfo;
DWORD cPolicy;
PCERT_POLICY_INFO pPolicy;
DWORD i;
if (NULL == (pInfo =
(PCERT_POLICIES_INFO) TestNoCopyDecodeObject(
X509_CERT_POLICIES,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
cPolicy = pInfo->cPolicyInfo;
pPolicy = pInfo->rgPolicyInfo;
//Display the name of the extension
IDSwprintf(hModule, idsIDS);
if (cPolicy == 0)
IDSwprintf(hModule, IDS_NONE);
for (i = 0; i < cPolicy; i++, pPolicy++)
{
DWORD cQualifier = pPolicy->cPolicyQualifier;
PCERT_POLICY_QUALIFIER_INFO pQualifier;
DWORD j;
printf(" [%d] %s", i, pPolicy->pszPolicyIdentifier);
if (cQualifier)
//" Qualifiers:: \n"
IDSwprintf(hModule, IDS_QUALI);
pQualifier = pPolicy->rgPolicyQualifier;
for (j = 0; j < cQualifier; j++, pQualifier++)
{
printf(" [%d] %s", j, pQualifier->pszPolicyQualifierId);
if (pQualifier->Qualifier.cbData)
{
//" Encoded Data::\n"
IDSwprintf(hModule, IDS_ENCODED_DATA);
PrintBytes(L" ",
pQualifier->Qualifier.pbData, pQualifier->Qualifier.cbData);
} else
printf("\n");
}
}
ErrorReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayKeyUsageExtension
//--------------------------------------------------------------------------
void DisplayKeyUsageExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCRYPT_BIT_BLOB pInfo;
BYTE bFlags;
if (NULL == (pInfo =
(PCRYPT_BIT_BLOB) TestNoCopyDecodeObject(
X509_KEY_USAGE,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//" <KeyUsage> \n"
IDSwprintf(hModule, IDS_KEY_USAGE);
if (pInfo->cbData)
bFlags = *pInfo->pbData;
else
bFlags = 0;
DisplayKeyUsage(bFlags);
ErrorReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayBasicConstraints2Extension
//--------------------------------------------------------------------------
void DisplayBasicConstraints2Extension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_BASIC_CONSTRAINTS2_INFO pInfo;
if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) TestNoCopyDecodeObject(
X509_BASIC_CONSTRAINTS2,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//" <Basic Constraints2> \n"
IDSwprintf(hModule, IDS_BASIC_CON2);
if (pInfo->fCA)
IDSwprintf(hModule, IDS_SUB_CA);
else
IDSwprintf(hModule, IDS_SUB_EE);
printf("\n");
//" PathLenConstraint:: "
IDSwprintf(hModule, IDS_PATH_LEN);
if (pInfo->fPathLenConstraint)
printf("%d", pInfo->dwPathLenConstraint);
else
IDSwprintf(hModule, IDS_NONE);
printf("\n");
ErrorReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayBasicConstraintsExtension
//--------------------------------------------------------------------------
void DisplayBasicConstraintsExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_BASIC_CONSTRAINTS_INFO pInfo;
if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS_INFO) TestNoCopyDecodeObject(
X509_BASIC_CONSTRAINTS,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//" <Basic Constraints> \n"
IDSwprintf(hModule, IDS_BASIC_CON);
//" SubjectType:: ";
IDSwprintf(hModule, IDS_SUB_TYPE);
if (pInfo->SubjectType.cbData == 0)
IDSwprintf(hModule, IDS_NONE);
else
{
BYTE bSubjectType = *pInfo->SubjectType.pbData;
if (bSubjectType == 0)
IDSwprintf(hModule, IDS_NONE);
if (bSubjectType & CERT_CA_SUBJECT_FLAG)
//" CA ");
IDSwprintf(hModule, IDS_SUB_CA);
if (bSubjectType & CERT_END_ENTITY_SUBJECT_FLAG)
//" END_ENTITY ")
IDSwprintf(hModule, IDS_SUB_EE);
}
printf("\n");
//" PathLenConstraint:: "
IDSwprintf(hModule, IDS_PATH_LEN);
if (pInfo->fPathLenConstraint)
printf("%d", pInfo->dwPathLenConstraint);
else
IDSwprintf(hModule, IDS_NONE_NOELN);
printf("\n");
if (pInfo->cSubtreesConstraint)
{
DWORD i;
PCERT_NAME_BLOB pSubtrees = pInfo->rgSubtreesConstraint;
for (i = 0; i < pInfo->cSubtreesConstraint; i++, pSubtrees++)
{
//" SubtreesConstraint[%d]::\n"
IDSwprintf(hModule, IDS_SUB_CON, i);
DecodeName(pSubtrees->pbData, pSubtrees->cbData, dwDisplayFlags);
}
}
goto CommonReturn;
ErrorReturn:
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayKeyUsageRestrictionExtension
//--------------------------------------------------------------------------
void DisplayKeyUsage(BYTE bFlags)
{
if (bFlags == 0)
IDSwprintf(hModule, IDS_NONE);
if (bFlags & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
//"DIGITAL_SIGNATURE "
IDSwprintf(hModule, IDS_DIG_SIG);
if (bFlags & CERT_NON_REPUDIATION_KEY_USAGE)
//"NON_REPUDIATION "
IDSwprintf(hModule, IDS_NON_REP);
if (bFlags & CERT_KEY_ENCIPHERMENT_KEY_USAGE)
//"KEY_ENCIPHERMENT "
IDSwprintf(hModule, IDS_KEY_ENCI);
if (bFlags & CERT_DATA_ENCIPHERMENT_KEY_USAGE)
//"DATA_ENCIPHERMENT ");
IDSwprintf(hModule, IDS_DATA_ENCI);
if (bFlags & CERT_KEY_AGREEMENT_KEY_USAGE)
//"KEY_AGREEMENT ");
IDSwprintf(hModule, IDS_KEY_AGRE);
if (bFlags & CERT_KEY_CERT_SIGN_KEY_USAGE)
//"KEY_CERT_SIGN "
IDSwprintf(hModule, IDS_CERT_SIGN);
if (bFlags & CERT_OFFLINE_CRL_SIGN_KEY_USAGE)
//"OFFLINE_CRL_SIGN "
IDSwprintf(hModule, IDS_OFFLINE_CRL);
printf("\n");
}
//+-------------------------------------------------------------------------
// DisplayKeyUsageRestrictionExtension
//--------------------------------------------------------------------------
void DisplayKeyUsageRestrictionExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_KEY_USAGE_RESTRICTION_INFO pInfo;
if (NULL == (pInfo =
(PCERT_KEY_USAGE_RESTRICTION_INFO) TestNoCopyDecodeObject(
X509_KEY_USAGE_RESTRICTION,
pbEncoded,
cbEncoded
))) goto ErrorReturn;
//Display the name of the certificate
//" <KeyUsageRestriction> \n "
IDSwprintf(hModule, IDS_KEY_RESTRIC);
if (pInfo->cCertPolicyId)
{
DWORD i, j;
//" CertPolicySet::\n"
IDSwprintf(hModule, IDS_CERT_POLICY);
PCERT_POLICY_ID pPolicyId = pInfo->rgCertPolicyId;
for (i = 0; i < pInfo->cCertPolicyId; i++, pPolicyId++)
{
if (pPolicyId->cCertPolicyElementId == 0)
printf(" [%d,*] %s\n", i, g_szNULL);
LPSTR *ppszObjId = pPolicyId->rgpszCertPolicyElementId;
for (j = 0; j < pPolicyId->cCertPolicyElementId; j++, ppszObjId++)
{
LPSTR pszObjId = *ppszObjId;
if (pszObjId == NULL)
pszObjId = g_szNULL;
printf(" [%d,%d] %s\n", i, j, pszObjId);
}
}
}
if (pInfo->RestrictedKeyUsage.cbData)
{
BYTE bFlags = *pInfo->RestrictedKeyUsage.pbData;
//" RestrictedKeyUsage:: "
IDSwprintf(hModule, IDS_RESTRIC_KEY);
DisplayKeyUsage(bFlags);
}
goto CommonReturn;
ErrorReturn:
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayCRLReason
//--------------------------------------------------------------------------
void DisplayCRLReason(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
DWORD cbInfo;
int CRLReason;
cbInfo = sizeof(CRLReason);
if (!CryptDecodeObject(
g_dwCertEncodingType,
szOID_CRL_REASON_CODE,
pbEncoded,
cbEncoded,
0, // dwFlags
&CRLReason,
&cbInfo
))
{
return;
}
//" <CRL Reason> \n");
IDSwprintf(hModule, IDS_CRL_REASON);
switch (CRLReason)
{
case CRL_REASON_UNSPECIFIED:
//"REASON_UNSPECIFIED"
IDSwprintf(hModule, IDS_CRL_UNSPECIFIED);
break;
case CRL_REASON_KEY_COMPROMISE:
//"KEY_COMPROMISE"
IDSwprintf(hModule, IDS_KEY_COMP);
break;
case CRL_REASON_CA_COMPROMISE:
//"CA_COMPROMISE"
IDSwprintf(hModule, IDS_CA_COMP);
break;
case CRL_REASON_AFFILIATION_CHANGED:
//"AFFILIATION_CHANGED"
IDSwprintf(hModule, IDS_AFFI_CHANGED);
break;
case CRL_REASON_SUPERSEDED:
//"SUPERSEDED"
IDSwprintf(hModule, IDS_SUPERSEDED);
break;
case CRL_REASON_CESSATION_OF_OPERATION:
//"CESSATION_OF_OPERATION"
IDSwprintf(hModule, IDS_CESS_OPER);
break;
case CRL_REASON_CERTIFICATE_HOLD:
//"CERTIFICATE_HOLD"
IDSwprintf(hModule, IDS_CERT_HOLD);
break;
case CRL_REASON_REMOVE_FROM_CRL:
//REMOVE_FROM_CRL);
IDSwprintf(hModule, IDS_REMOVE_CRL);
break;
default:
printf("%d", CRLReason);
break;
}
printf("\n");
}
//+-------------------------------------------------------------------------
// DisplayAltNameExtension
//--------------------------------------------------------------------------
void DisplayAltNameExtension(
int idsIDS,
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
IDSwprintf(hModule, idsIDS);
DecodeAndDisplayAltName(pbEncoded, cbEncoded, dwDisplayFlags);
}
//+-------------------------------------------------------------------------
// DisplayKeyAttrExtension
//--------------------------------------------------------------------------
void DisplayKeyAttrExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_KEY_ATTRIBUTES_INFO pInfo;
if (NULL == (pInfo = (PCERT_KEY_ATTRIBUTES_INFO) TestNoCopyDecodeObject(
X509_KEY_ATTRIBUTES,
pbEncoded,
cbEncoded
))) goto CommonReturn;
//" <KeyAttributes>\n"
IDSwprintf(hModule ,IDS_KEY_ATTR);
if (pInfo->KeyId.cbData)
{
//" KeyId::\n"
IDSwprintf(hModule, IDS_KEY_ID);
PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
}
if (pInfo->IntendedKeyUsage.cbData)
{
BYTE bFlags = *pInfo->IntendedKeyUsage.pbData;
//" IntendedKeyUsage:: "
IDSwprintf(hModule, IDS_INTEND_KEY_USAGE);
if (bFlags == 0)
IDSwprintf(hModule, IDS_NONE);
if (bFlags & CERT_DIGITAL_SIGNATURE_KEY_USAGE)
//"DIGITAL_SIGNATURE "
IDSwprintf(hModule, IDS_DIG_SIG);
if (bFlags & CERT_NON_REPUDIATION_KEY_USAGE)
//"NON_REPUDIATION "
IDSwprintf(hModule, IDS_NON_REP);
if (bFlags & CERT_KEY_ENCIPHERMENT_KEY_USAGE)
//"KEY_ENCIPHERMENT "
IDSwprintf(hModule, IDS_KEY_ENCI);
if (bFlags & CERT_DATA_ENCIPHERMENT_KEY_USAGE)
//"DATA_ENCIPHERMENT ");
IDSwprintf(hModule, IDS_DATA_ENCI);
if (bFlags & CERT_KEY_AGREEMENT_KEY_USAGE)
//"KEY_AGREEMENT ");
IDSwprintf(hModule, IDS_KEY_AGRE);
if (bFlags & CERT_KEY_CERT_SIGN_KEY_USAGE)
//"KEY_CERT_SIGN "
IDSwprintf(hModule, IDS_CERT_SIGN);
if (bFlags & CERT_OFFLINE_CRL_SIGN_KEY_USAGE)
//"OFFLINE_CRL_SIGN "
IDSwprintf(hModule, IDS_OFFLINE_CRL);
printf("\n");
}
if (pInfo->pPrivateKeyUsagePeriod)
{
PCERT_PRIVATE_KEY_VALIDITY p = pInfo->pPrivateKeyUsagePeriod;
//"NotBefore:: %s\n"
IDSwprintf(hModule, IDS_NOT_BEFORE, FileTimeText(&p->NotBefore));
IDSwprintf(hModule, IDS_NOT_AFTER, FileTimeText(&p->NotAfter));
}
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayCrlDistPointsExtension
//--------------------------------------------------------------------------
void DisplayCrlDistPointsExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCRL_DIST_POINTS_INFO pInfo = NULL;
DWORD i;
if (NULL == (pInfo = (PCRL_DIST_POINTS_INFO) TestNoCopyDecodeObject(
X509_CRL_DIST_POINTS,
pbEncoded,
cbEncoded
))) goto CommonReturn;
if (0 == pInfo->cDistPoint)
//" NO CRL Distribution Points\n"
IDSwprintf(hModule, IDS_NO_CRL_DIS);
else
{
DWORD cPoint = pInfo->cDistPoint;
PCRL_DIST_POINT pPoint = pInfo->rgDistPoint;
for (i = 0; i < cPoint; i++, pPoint++)
{
//" CRL Distribution Point[%d]\n"
IDSwprintf(hModule,IDS_CRL_IDS_I, i);
DWORD dwNameChoice = pPoint->DistPointName.dwDistPointNameChoice;
switch (dwNameChoice)
{
case CRL_DIST_POINT_NO_NAME:
break;
case CRL_DIST_POINT_FULL_NAME:
//" FullName:\n"
IDSwprintf(hModule, IDS_CRL_DIS_FULL_NAME);
DisplayAltName(&pPoint->DistPointName.FullName,
dwDisplayFlags);
break;
case CRL_DIST_POINT_ISSUER_RDN_NAME:
//printf(" IssuerRDN: (Not Implemented)\n");
IDSwprintf(hModule, IDS_CRL_RDN);
break;
default:
//" Unknown name choice: %d\n", dwNameChoice);
IDSwprintf(hModule, IDS_CRL_UNKNOWN, dwNameChoice);
break;
}
if (pPoint->ReasonFlags.cbData)
{
BYTE bFlags;
//" ReasonFlags: "
IDSwprintf(hModule, IDS_REASON_FLAG);
bFlags = *pPoint->ReasonFlags.pbData;
if (bFlags == 0)
//"<NONE> \n"
IDSwprintf(hModule, IDS_NONE);
if (bFlags & CRL_REASON_UNUSED_FLAG)
//"UNUSED "
IDSwprintf(hModule, IDS_REASON_UNUSED);
if (bFlags & CRL_REASON_KEY_COMPROMISE_FLAG)
//"KEY_COMPROMISE "
IDSwprintf(hModule, IDS_KEY_COMP);
if (bFlags & CRL_REASON_CA_COMPROMISE_FLAG)
//"CA_COMPROMISE "
IDSwprintf(hModule, IDS_CA_COMP);
if (bFlags & CRL_REASON_AFFILIATION_CHANGED_FLAG)
//"AFFILIATION_CHANGED "
IDSwprintf(hModule, IDS_AFFI_CHANGED);
if (bFlags & CRL_REASON_SUPERSEDED_FLAG)
//"SUPERSEDED "
IDSwprintf(hModule, IDS_SUPERSEDED);
if (bFlags & CRL_REASON_CESSATION_OF_OPERATION_FLAG)
//"CESSATION_OF_OPERATION "
IDSwprintf(hModule, IDS_CESS_OPER);
if (bFlags & CRL_REASON_CERTIFICATE_HOLD_FLAG)
//"CERTIFICATE_HOLD "
IDSwprintf(hModule, IDS_CERT_HOLD);
printf("\n");
}
if (pPoint->CRLIssuer.cAltEntry)
{
//" ISSUER::\n"
IDSwprintf(hModule, IDS_CRL_ISSUER);
DisplayAltName(&pPoint->CRLIssuer, dwDisplayFlags);
}
}
}
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayAuthorityKeyIdExtension
//--------------------------------------------------------------------------
void DisplayAuthorityKeyIdExtension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_AUTHORITY_KEY_ID_INFO pInfo;
//" <AuthorityKeyId>\n"
IDSwprintf(hModule, IDS_AUTH_KEY_ID);
if (NULL == (pInfo = (PCERT_AUTHORITY_KEY_ID_INFO) TestNoCopyDecodeObject(
X509_AUTHORITY_KEY_ID,
pbEncoded,
cbEncoded
))) goto CommonReturn;
if (pInfo->KeyId.cbData)
{
//" KeyId::\n"
IDSwprintf(hModule, IDS_KEY_ID);
PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
}
if (pInfo->CertIssuer.cbData)
{
//" AuthorityCertIssuer::\n"
IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER);
DecodeName(pInfo->CertIssuer.pbData, pInfo->CertIssuer.cbData,
dwDisplayFlags);
}
if (pInfo->CertSerialNumber.cbData)
{
//" CertSerialNumber::"
IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER_SERIAL_NUMBER);
DisplaySerialNumber(&pInfo->CertSerialNumber);
printf("\n");
}
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// Get the name of an OID
//--------------------------------------------------------------------------
void DisplayAuthorityKeyId2Extension(
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCERT_AUTHORITY_KEY_ID2_INFO pInfo;
//" <AuthorityKeyId #2>\n"
IDSwprintf(hModule, IDS_AUTH_KEY_ID2);
if (NULL == (pInfo = (PCERT_AUTHORITY_KEY_ID2_INFO) TestNoCopyDecodeObject(
X509_AUTHORITY_KEY_ID2,
pbEncoded,
cbEncoded
))) goto CommonReturn;
if (pInfo->KeyId.cbData)
{
//" KeyId::\n"
IDSwprintf(hModule, IDS_KEY_ID);
PrintBytes(L" ", pInfo->KeyId.pbData, pInfo->KeyId.cbData);
}
if (pInfo->AuthorityCertIssuer.cAltEntry)
{
//" AuthorityCertIssuer::\n"
IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER);
DisplayAltName(&pInfo->AuthorityCertIssuer, dwDisplayFlags);
}
if (pInfo->AuthorityCertSerialNumber.cbData)
{
//" AuthorityCertSerialNumber::"
IDSwprintf(hModule, IDS_AUTH_CERT_ISSUER_SERIAL_NUMBER);
DisplaySerialNumber(&pInfo->AuthorityCertSerialNumber);
printf("\n");
}
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayAnyString
//--------------------------------------------------------------------------
void DisplayAnyString(
int idsIDS,
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags
)
{
PCERT_NAME_VALUE pInfo = NULL;
if (NULL == (pInfo = (PCERT_NAME_VALUE) TestNoCopyDecodeObject(
X509_UNICODE_ANY_STRING,
pbEncoded,
cbEncoded
))) goto CommonReturn;
//print the pre-fix
IDSwprintf(hModule, idsIDS);
if (pInfo->dwValueType == CERT_RDN_ENCODED_BLOB ||
pInfo->dwValueType == CERT_RDN_OCTET_STRING)
{
//"ValueType: %d\n"
IDSwprintf(hModule, IDS_VALUE_TYPE, pInfo->dwValueType);
PrintBytes(L" ", pInfo->Value.pbData, pInfo->Value.cbData);
} else
//"ValueType: %d String: %s\n"
IDSwprintf(hModule, IDS_VALUE_STRING_S,
pInfo->dwValueType, pInfo->Value.pbData);
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayBits
//--------------------------------------------------------------------------
void DisplayBits(
int idsIDS,
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCRYPT_BIT_BLOB pInfo = NULL;
if (NULL == (pInfo = (PCRYPT_BIT_BLOB) TestNoCopyDecodeObject(
X509_BITS,
pbEncoded,
cbEncoded
))) goto CommonReturn;
IDSwprintf(hModule, idsIDS);
if (1 == pInfo->cbData)
{
printf(" %02X", *pInfo->pbData);
if (pInfo->cUnusedBits)
{
//" (UnusedBits: %d)"
IDSwprintf(hModule, IDS_UNUSED_BITS, pInfo->cUnusedBits);
}
printf("\n");
}
else
{
if (pInfo->cbData)
{
printf("\n");
PrintBytes(L" ", pInfo->pbData, pInfo->cbData);
IDSwprintf(hModule, IDS_UNUSED_BITS, pInfo->cUnusedBits);
printf("\n");
}
else
IDSwprintf(hModule, IDS_NONE);
}
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// DisplayOctetString
//--------------------------------------------------------------------------
void DisplayOctetString(
int idsIDS,
BYTE *pbEncoded,
DWORD cbEncoded,
DWORD dwDisplayFlags)
{
PCRYPT_DATA_BLOB pInfo = NULL;
if (NULL == (pInfo = (PCRYPT_DATA_BLOB) TestNoCopyDecodeObject(
X509_OCTET_STRING,
pbEncoded,
cbEncoded
))) goto CommonReturn;
IDSwprintf(hModule, idsIDS);
PrintBytes(L" ", pInfo->pbData, pInfo->cbData);
CommonReturn:
if (pInfo)
ToolUtlFree(pInfo);
}
//+-------------------------------------------------------------------------
// Get the name of an OID
//--------------------------------------------------------------------------
LPCWSTR GetOIDName(LPCSTR pszOID, DWORD dwGroupId)
{
PCCRYPT_OID_INFO pInfo;
if (pInfo = CryptFindOIDInfo
(
CRYPT_OID_INFO_OID_KEY,
(void *) pszOID,
dwGroupId
))
{
if (L'\0' != pInfo->pwszName[0])
return pInfo->pwszName;
}
return g_wszUnKnown;
}
//--------------------------------------------------------------------------
//
// FormatBasicConstraints2
//--------------------------------------------------------------------------
BOOL
WINAPI
FormatBasicConstraints2(
DWORD dwCertEncodingType,
DWORD dwFormatType,
DWORD dwFormatStrType,
void *pFormatStruct,
LPCSTR lpszStructType,
const BYTE *pbEncoded,
DWORD cbEncoded,
void *pbFormat,
DWORD *pcbFormat)
{
WCHAR wszFormat[100]=L"\0";
WCHAR wszLength[15];
PCERT_BASIC_CONSTRAINTS2_INFO pInfo=NULL;
DWORD cbNeeded=0;
//check for input parameters
if(( pbEncoded!=NULL && cbEncoded==0)
||(pbEncoded==NULL && cbEncoded!=0)
|| (pcbFormat==NULL))
{
SetLastError(E_INVALIDARG);
return FALSE;
}
//check for simple case. No work needed
if(pbEncoded==NULL && cbEncoded==0)
{
*pcbFormat=0;
return TRUE;
}
if (NULL == (pInfo = (PCERT_BASIC_CONSTRAINTS2_INFO) TestNoCopyDecodeObject(
X509_BASIC_CONSTRAINTS2,
pbEncoded,
cbEncoded
)))
return FALSE;
//" <Basic Constraints2> \n"
IDSwcscat(hModule, wszFormat, IDS_BASIC_CON2);
if (pInfo->fCA)
//" CA ");
IDSwcscat(hModule,wszFormat,IDS_SUB_CA);
else
//" End-Entity"
IDSwcscat(hModule,wszFormat, IDS_SUB_EE);
//"\n"
IDSwcscat(hModule, wszFormat, IDS_ELN);
//" PathLenConstraint:: "
IDSwcscat(hModule, wszFormat, IDS_PATH_LEN);
if (pInfo->fPathLenConstraint)
{
swprintf(wszLength, L"%d",pInfo->dwPathLenConstraint);
wcscat(wszFormat, wszLength);
}
else
IDSwcscat(hModule, wszFormat, IDS_NONE_NOELN);
if (pInfo)
ToolUtlFree(pInfo);
cbNeeded=sizeof(WCHAR)*(wcslen(wszFormat)+1);
//length only calculation
if(NULL==pbFormat)
{
*pcbFormat=cbNeeded;
return TRUE;
}
if((*pcbFormat)<cbNeeded)
{
SetLastError(ERROR_MORE_DATA);
return FALSE;
}
//copy the data
memcpy(pbFormat, wszFormat, cbNeeded);
//copy the size
*pcbFormat=cbNeeded;
return TRUE;
}
//+-------------------------------------------------------------------------
// Get the name of an OID
//--------------------------------------------------------------------------
BOOL InstalledFormat(LPSTR szStructType, BYTE *pbEncoded, DWORD cbEncoded)
{
BOOL fResult=FALSE;
void *pvFuncAddr=NULL;
HCRYPTOIDFUNCADDR hFuncAddr=NULL;
DWORD cbFormat=0;
LPWSTR wszFormat=NULL;
DWORD dwFormatStrType=0;
if(TRUE==g_fMulti)
dwFormatStrType |=CRYPT_FORMAT_STR_MULTI_LINE;
if(NULL==pbEncoded || 0==cbEncoded)
return FALSE;
//load the formatting functions
if (!CryptGetOIDFunctionAddress(
hFormatFuncSet,
g_dwCertEncodingType,
szStructType,
0, // dwFlags
&pvFuncAddr,
&hFuncAddr))
goto CLEANUP;
//call the functions
if(!((PFN_FORMAT_FUNC) pvFuncAddr)(
g_dwCertEncodingType,
0,
dwFormatStrType,
NULL,
szStructType,
pbEncoded,
cbEncoded,
NULL,
&cbFormat
))
goto CLEANUP;
//allocate
wszFormat=(LPWSTR)ToolUtlAlloc(cbFormat * sizeof(WCHAR));
if(!wszFormat)
goto CLEANUP;
if(!((PFN_FORMAT_FUNC) pvFuncAddr)(
g_dwCertEncodingType,
0,
dwFormatStrType,
NULL,
szStructType,
pbEncoded,
cbEncoded,
wszFormat,
&cbFormat
))
goto CLEANUP;
//print
wprintf(L"%s\n", wszFormat);
fResult=TRUE;
CLEANUP:
if(wszFormat)
ToolUtlFree(wszFormat);
if(hFuncAddr)
CryptFreeOIDFunctionAddress(hFuncAddr, 0);
return fResult;
}
#pragma pack(1)
struct SplitGuid
{
DWORD dw1;
WORD w1;
WORD w2;
BYTE b[8];
};
#pragma pack()
WCHAR *GuidText(GUID *pguid)
{
static WCHAR buf[39];
SplitGuid *psg = (SplitGuid *)pguid;
swprintf(buf, L"{%08lX-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}",
psg->dw1, psg->w1, psg->w2, psg->b[0], psg->b[1], psg->b[2],
psg->b[3], psg->b[4], psg->b[5], psg->b[6], psg->b[7]);
return buf;
}