//+------------------------------------------------------------------------- // // 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) // ||!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) // ||!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; dwIndex1) { //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; dwIndex1) { //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; dwIndexcUsageIdentifier = 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=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=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=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; dwIndexdwVersion); //"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=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= 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 //" " //"" 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) //" \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) //" \n" DisplayAltNameExtension(IDS_SUB_ALT, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME) == 0) //" \n" DisplayAltNameExtension(IDS_ISS_ALT, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_SUBJECT_ALT_NAME2) == 0) //" \n" DisplayAltNameExtension(IDS_SUB_ALT2, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_ISSUER_ALT_NAME2) == 0) //" \n" DisplayAltNameExtension(IDS_ISS_ALT2, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NEXT_UPDATE_LOCATION) == 0) //" \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) //" \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) //" \n" DisplayBits(IDS_NSCP_CERT, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_BASE_URL) == 0) //" \n" DisplayAnyString(IDS_NSCP_BASE, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_REVOCATION_URL) == 0) //" \n" DisplayAnyString(IDS_NSCP_REV, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_CA_REVOCATION_URL) == 0) //" \n" DisplayAnyString(IDS_NSCP_CA_REV, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_CERT_RENEWAL_URL) == 0) //" \n" DisplayAnyString(IDS_NSCP_RENEW, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_CA_POLICY_URL) == 0) //" \n" DisplayAnyString(IDS_NSCP_CA_URL, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_SSL_SERVER_NAME) == 0) //" \n" DisplayAnyString(IDS_NSCP_SSL, pExt->Value.pbData, pExt->Value.cbData, dwDisplayFlags); else if (strcmp(pszObjId, szOID_NETSCAPE_COMMENT) == 0) //" \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; //" \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) { //" \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; //" \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; } //" \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; } //" \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; //" \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; //" \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; //" \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; //" \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 //" \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; } //" \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; //" \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) //" \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; //" \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; //" \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; //" \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)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; }