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

1636 lines
56 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: tstore.cpp
//
// Contents: Cert Store API Tests
//
// See Usage() for list of test options.
//
//
// Functions: main
//
// History: 04-Mar-96 philh created
// 07-Jun-96 HelleS Added printing the command line
// 20-Aug-96 jeffspel name changes
//
//--------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "certtest.h"
#include "crypthlp.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
//
// FIsWinNT: check OS type on x86. On non-x86, assume WinNT
//
#ifdef _M_IX86
static BOOL WINAPI FIsWinNT(void) {
static BOOL fIKnow = FALSE;
static BOOL fIsWinNT = FALSE;
OSVERSIONINFO osVer;
if(fIKnow)
return(fIsWinNT);
memset(&osVer, 0, sizeof(OSVERSIONINFO));
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( GetVersionEx(&osVer) )
fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
// even on an error, this is as good as it gets
fIKnow = TRUE;
return(fIsWinNT);
}
#else
static BOOL WINAPI FIsWinNT(void) {
return(TRUE);
}
#endif
static void PrintExpectedError(LPCSTR pszMsg)
{
DWORD dwErr = GetLastError();
printf("%s got expected error => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
}
void PrintNoError(LPCSTR pszMsg)
{
printf("%s failed => expected error\n", pszMsg);
}
static BOOL AddCert(HCERTSTORE hStore, LPSTR pszAddFilename,
DWORD dwAddDisposition, BOOL fExpectError)
{
BYTE *pbEncoded;
DWORD cbEncoded;
BOOL fResult;
PCCERT_CONTEXT pCert = NULL;
if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("AddCert");
return FALSE;
}
fResult = FALSE;
if (!CertAddEncodedCertificateToStore(hStore, dwCertEncodingType,
pbEncoded, cbEncoded, dwAddDisposition, &pCert)) {
if (fExpectError)
PrintExpectedError("CertAddEncodedCertificateToStore");
else
PrintLastError("CertAddEncodedCertificateToStore");
} else {
if (fExpectError)
PrintNoError("CertAddEncodedCertificateToStore");
else
fResult = TRUE;
printf("===== Added Cert =====\n");
DisplayCert(pCert, 0, 0);
CertFreeCertificateContext(pCert);
}
TestFree(pbEncoded);
return fResult;
}
static BOOL ReadCert(
HCERTSTORE hStore,
LPSTR pszReadFilename,
DWORD dwDisplayFlags)
{
BOOL fResult;
BYTE *pbEncoded;
DWORD cbEncoded;
PCCERT_CONTEXT pCert;
if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("ReadCert");
return FALSE;
}
pCert = CertCreateCertificateContext(
dwCertEncodingType,
pbEncoded,
cbEncoded
);
if (pCert == NULL) {
fResult = FALSE;
PrintLastError("CertCreateCertificateContext");
} else {
fResult = TRUE;
DisplayCert2(hStore, pCert, dwDisplayFlags);
CertFreeCertificateContext(pCert);
}
TestFree(pbEncoded);
return fResult;
}
// Attempt to read as a file containing an embedded PKCS#7 via SIP
static HCERTSTORE OpenSIPStoreFile(
LPSTR pszStoreFilename)
{
HCERTSTORE hStore = NULL;
LPWSTR pwszStoreFilename = NULL;
CRYPT_DATA_BLOB SignedData;
memset(&SignedData, 0, sizeof(SignedData));
DWORD dwGetEncodingType;
GUID gSubject;
SIP_DISPATCH_INFO SipDispatch;
SIP_SUBJECTINFO SubjectInfo;
if (NULL == (pwszStoreFilename = AllocAndSzToWsz(pszStoreFilename)))
goto CommonReturn;
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 = dwMsgAndCertEncodingType;
// SubjectInfo.lpAddInfo =
if (!SipDispatch.pfGet(
&SubjectInfo,
&dwGetEncodingType,
0, // dwIndex
&SignedData.cbData,
NULL // pbSignedData
) || 0 == SignedData.cbData)
goto CommonReturn;
if (NULL == (SignedData.pbData = (BYTE *) TestAlloc(SignedData.cbData)))
goto CommonReturn;
if (!SipDispatch.pfGet(
&SubjectInfo,
&dwGetEncodingType,
0, // dwIndex
&SignedData.cbData,
SignedData.pbData
))
goto CommonReturn;
hStore = CertOpenStore(
CERT_STORE_PROV_PKCS7,
dwMsgAndCertEncodingType,
0, // hCryptProv
0, // dwFlags
(const void *) &SignedData
);
if (hStore) {
WCHAR wszGUID[128];
StringFromGUID2(gSubject, wszGUID, 128);
printf("Opening Store as SIP Subject GUID:: %S \n", wszGUID);
}
CommonReturn:
TestFree(pwszStoreFilename);
TestFree(SignedData.pbData);
return hStore;
}
static HCERTSTORE OpenCertStoreFile(
LPSTR pszStoreFilename)
{
HCERTSTORE hStore;
if (hStore = OpenSIPStoreFile(pszStoreFilename))
return hStore;
return NULL;
}
static BOOL AddCrl(HCERTSTORE hStore, LPSTR pszAddFilename,
DWORD dwAddDisposition, BOOL fExpectError)
{
BYTE *pbEncoded;
DWORD cbEncoded;
BOOL fResult;
PCCRL_CONTEXT pCrl = NULL;
if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("AddCrl");
return FALSE;
}
fResult = FALSE;
if (!CertAddEncodedCRLToStore(hStore, dwCertEncodingType, pbEncoded,
cbEncoded, dwAddDisposition, &pCrl)) {
if (fExpectError)
PrintExpectedError("CertAddEncodedCRLToStore");
else
PrintLastError("CertAddEncodedCRLToStore");
} else {
if (fExpectError)
PrintNoError("CertAddEncodedCRLToStore");
else
fResult = TRUE;
printf("===== Added CRL =====\n");
DisplayCrl(pCrl, 0);
CertFreeCRLContext(pCrl);
}
TestFree(pbEncoded);
return fResult;
}
static BOOL ReadCrl(
LPSTR pszReadFilename,
DWORD dwDisplayFlags)
{
BOOL fResult;
BYTE *pbEncoded;
DWORD cbEncoded;
PCCRL_CONTEXT pCrl;
if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("ReadCrl");
return FALSE;
}
pCrl = CertCreateCRLContext(
dwCertEncodingType,
pbEncoded,
cbEncoded
);
if (pCrl == NULL) {
fResult = FALSE;
PrintLastError("CertCreateCRLContext");
} else {
fResult = TRUE;
DisplayCrl(pCrl, dwDisplayFlags);
CertFreeCRLContext(pCrl);
}
TestFree(pbEncoded);
return fResult;
}
// Attempt to read as a file containing an encoded CRL.
static HCERTSTORE OpenCrlStoreFile(
LPSTR pszStoreFilename)
{
HCERTSTORE hStore;
BYTE *pbEncoded;
DWORD cbEncoded;
if (!ReadDERFromFile(pszStoreFilename, &pbEncoded, &cbEncoded))
return NULL;
if (NULL == (hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)))
return NULL;
if (!CertAddEncodedCRLToStore(
hStore,
dwCertEncodingType,
pbEncoded,
cbEncoded,
CERT_STORE_ADD_ALWAYS,
NULL // ppCrlContext
)) {
CertCloseStore(hStore, 0);
hStore = NULL;
}
TestFree(pbEncoded);
return hStore;
}
static BOOL AddRootCtl(
HCERTSTORE hStore,
PCCTL_CONTEXT pCtl,
DWORD dwAddDisposition,
BOOL fExpectError
)
{
BOOL fResult;
DWORD i;
DWORD cCtlEntry = pCtl->pCtlInfo->cCTLEntry;
PCTL_ENTRY pCtlEntry = pCtl->pCtlInfo->rgCTLEntry;
HCERTSTORE hMsgStore = NULL;
hMsgStore = CertOpenStore(
CERT_STORE_PROV_MSG,
dwMsgAndCertEncodingType,
0, // hCryptProv
0, // dwFlags
(const void *) pCtl->hCryptMsg
);
if (NULL == hMsgStore) {
PrintLastError("Open Msg Store");
goto ErrorReturn;
}
// Loop through entries. Either add or remove the certificate from the
// store
for (i = 0; i< cCtlEntry; i++, pCtlEntry++) {
PCRYPT_ATTRIBUTE pDelAttr;
pDelAttr = CertFindAttribute(
szOID_REMOVE_CERTIFICATE,
pCtlEntry->cAttribute,
pCtlEntry->rgAttribute
);
if (pDelAttr) {
BYTE rgbDelValue[] = {0x02, 0x1, 0x1};
if (0 == pDelAttr->cValue || 3 != pDelAttr->rgValue[0].cbData ||
0 != memcmp(pDelAttr->rgValue[0].pbData, rgbDelValue, 3))
printf("Failed ==> bad delete attribute for Cert[%d]\n", i);
else {
PCCERT_CONTEXT pDelCert;
pDelCert = CertFindCertificateInStore(
hStore,
0, // dwCertEncodingType
0, // dwFindFlags
CERT_FIND_SHA1_HASH,
(const void *) &pCtlEntry->SubjectIdentifier,
NULL //pPrevCertContext
);
if (pDelCert) {
if (CertDeleteCertificateFromStore(pDelCert))
printf("===== Deleted Root Cert[%d] =====\n", i);
else
printf("Failed ==> delete Cert[%d]\n", i);
}
}
} else {
PCCERT_CONTEXT pAddCert;
pAddCert = CertFindCertificateInStore(
hMsgStore,
0, // dwCertEncodingType
0, // dwFindFlags
CERT_FIND_SHA1_HASH,
(const void *) &pCtlEntry->SubjectIdentifier,
NULL //pPrevCertContext
);
if (pAddCert) {
if (!CertSetCertificateContextPropertiesFromCTLEntry(
pAddCert,
pCtlEntry,
CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG
))
printf("Failed ==> SetPropFromCTLEntry for Cert [%d]\n",
i);
else {
if (!CertAddCertificateContextToStore(
hStore,
pAddCert,
dwAddDisposition,
NULL // ppStoreContext
))
printf("Failed ==> Add Cert [%d]\n", i);
else
printf("===== Added Root Cert[%d] =====\n", i);
}
CertFreeCertificateContext(pAddCert);
} else
printf("Failed ==> No Cert [%d]\n", i);
}
}
fResult = TRUE;
CommonReturn:
if (hMsgStore)
CertCloseStore(hMsgStore, 0);
return fResult;
ErrorReturn:
fResult = FALSE;
goto CommonReturn;
}
static BOOL AddCtl(HCERTSTORE hStore, LPSTR pszAddFilename,
DWORD dwAddDisposition, BOOL fExpectError)
{
BYTE *pbEncoded;
DWORD cbEncoded;
BOOL fResult;
PCCTL_CONTEXT pCtl = NULL;
if (!ReadDERFromFile(pszAddFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("AddCtl");
return FALSE;
}
// Determine if Root CTL
pCtl = CertCreateCTLContext(
dwMsgAndCertEncodingType,
pbEncoded,
cbEncoded
);
if (pCtl) {
PCTL_USAGE pSubjectUsage = &pCtl->pCtlInfo->SubjectUsage;
if (0 == pSubjectUsage->cUsageIdentifier ||
0 != strcmp(pSubjectUsage->rgpszUsageIdentifier[0],
szOID_ROOT_LIST_SIGNER)) {
CertFreeCTLContext(pCtl);
pCtl = NULL;
}
}
fResult = FALSE;
if (pCtl) {
fResult = AddRootCtl(
hStore,
pCtl,
dwAddDisposition,
fExpectError
);
CertFreeCTLContext(pCtl);
} else if (!CertAddEncodedCTLToStore(hStore, dwMsgAndCertEncodingType, pbEncoded,
cbEncoded, dwAddDisposition, &pCtl)) {
if (fExpectError)
PrintExpectedError("CertAddEncodedCTLToStore");
else
PrintLastError("CertAddEncodedCTLToStore");
} else {
if (fExpectError)
PrintNoError("CertAddEncodedCTLToStore");
else
fResult = TRUE;
printf("===== Added CTL =====\n");
DisplayCtl(pCtl, 0, hStore);
CertFreeCTLContext(pCtl);
}
TestFree(pbEncoded);
return fResult;
}
static BOOL ReadCtl(
LPSTR pszReadFilename,
DWORD dwDisplayFlags)
{
BOOL fResult;
BYTE *pbEncoded;
DWORD cbEncoded;
PCCTL_CONTEXT pCtl;
if (!ReadDERFromFile(pszReadFilename, &pbEncoded, &cbEncoded)) {
PrintLastError("ReadCtl");
return FALSE;
}
pCtl = CertCreateCTLContext(
dwMsgAndCertEncodingType,
pbEncoded,
cbEncoded
);
if (pCtl == NULL) {
fResult = FALSE;
PrintLastError("CertCreateCTLContext");
} else {
fResult = TRUE;
DisplayCtl(pCtl, dwDisplayFlags, NULL);
CertFreeCTLContext(pCtl);
}
TestFree(pbEncoded);
return fResult;
}
// Attempt to read as a file containing an encoded CTL.
static HCERTSTORE OpenCtlStoreFile(
LPSTR pszStoreFilename)
{
HCERTSTORE hStore;
BYTE *pbEncoded;
DWORD cbEncoded;
if (!ReadDERFromFile(pszStoreFilename, &pbEncoded, &cbEncoded))
return NULL;
if (NULL == (hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
NULL // pvPara
)))
goto CommonReturn;
if (!CertAddEncodedCTLToStore(
hStore,
dwMsgAndCertEncodingType,
pbEncoded,
cbEncoded,
CERT_STORE_ADD_ALWAYS,
NULL // ppCtlContext
)) {
CertCloseStore(hStore, 0);
hStore = NULL;
}
CommonReturn:
TestFree(pbEncoded);
return hStore;
}
static PCCERT_CONTEXT GetNthCert(
IN HCERTSTORE hStore,
IN DWORD N
)
{
PCCERT_CONTEXT pCert = NULL;
while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
if (0 == N--)
break;
}
return pCert;
}
static void SetKeyProvParams(
IN PCCERT_CONTEXT pCert
)
{
CRYPT_KEY_PROV_INFO Info;
CRYPT_KEY_PROV_PARAM Param[3];
DWORD i;
BYTE rgb[11*3];
Info.pwszContainerName = L"Test Container With Parameters";
Info.pwszProvName = L"test provider with parameters";
Info.dwProvType = 77;
Info.dwFlags = 0x12345678;
Info.cProvParam = 3;
Info.rgProvParam = Param;
Info.dwKeySpec = 66;
for (i = 0; i < sizeof(rgb); i++)
rgb[i] = (BYTE) i;
for (i = 0; i < 3; i++) {
Param[i].dwParam = 0x10 + i;
if (i == 0)
Param[i].pbData = NULL;
else
Param[i].pbData = rgb;
Param[i].cbData = i * 11;
Param[i].dwFlags = 1 << i;
}
if (!CertSetCertificateContextProperty(
pCert,
CERT_KEY_PROV_INFO_PROP_ID,
0, // dwFlags
&Info
))
PrintLastError("CertSetCertificateContextProperty(KeyProvParams)");
}
static void Usage(void)
{
printf("Usage: tstore [options] <StoreName>\n");
printf("Options are:\n");
printf(" -h - This message\n");
printf(" -b - Brief\n");
printf(" -c - Verify ALL checks enabled\n");
printf(" -cSign - Verify Signature check enabled\n");
printf(" -cTime - Verify Time Validity check enabled\n");
printf(" -d - Delete cert/CRL/CTL\n");
printf(" -dALL - Delete all certs/CRLs/CTLs\n");
printf(" -P - Set or Delete property\n");
printf(" -PKey - Find or Delete KeyProvInfo property\n");
printf(" -PSilentKey - Silent Find or Delete KeyProvInfo property\n");
printf(" -PArchive - Find or Delete Archive property\n");
printf(" -PKeyProvParam - Set KeyProvInfo with parameters\n");
printf(" -F - Test Force store close\n");
printf(" -e<number> - Cert encoding type\n");
printf(" -f<number> - Open dwFlags\n");
printf(" -E - Error is expected for add, delete or set\n");
printf(" -i<number> - Cert/CRL/CTL index\n");
printf(" -l - List (Default)\n");
printf(" -R - Revocation (CRL)\n");
printf(" -T - Trust (CTL)\n");
printf(" -N - Enable change Notify\n");
printf(" -C - Commit before close\n");
printf(" -CForce - Force Commit before close\n");
printf(" -CClear - Clear Commit before close\n");
printf(" -s - Open the \"StoreName\" System store\n");
printf(" -s<StoreProviderName> - Open using store provider\n");
printf(" -v - Verbose\n");
printf(" -u - UI Dialog Viewer\n");
printf(" -a<filename> - Add encoded cert/CRL/CTL from file\n");
printf(" -A<filename> - Add (replace) encoded cert/CRL/CTL from file\n");
printf(" -I<filename> - Add (inherit properties) encoded cert/CRL/CTL from file\n");
printf(" -p<filename> - Put encoded cert/CRL/CTL to file\n");
printf(" -r<filename> - Read encoded cert/CRL/CTL from file\n");
printf(" -t - Save thumprints (digests/hashes) in store\n");
printf(" -K - Display Public Key Thumbprint\n");
printf(" -S[<SaveFilename>] - Save store to file\n");
printf(" -7[<SaveFilename>] - PKCS# 7 formated save\n");
printf("\n");
printf("Default: list of certs for the store\n");
}
int _cdecl main(int argc, char * argv[])
{
DWORD dwDisplayFlags = 0;
LONG lIndex = -1;
BOOL fDelete = FALSE;
BOOL fDeleteAll = FALSE;
DWORD dwOpenFlags = 0;
BOOL fExpectError = FALSE;
BOOL fProperty = FALSE;
BOOL fKeyProperty = FALSE;
BOOL fKeyProvParam = FALSE;
BOOL fSilentKey = FALSE;
BOOL fArchiveProperty = FALSE;
DWORD dwContextType = CERT_STORE_CERTIFICATE_CONTEXT;
BOOL fThumbprint = FALSE;
BOOL fSystemStore = FALSE;
BOOL fForceClose = FALSE;
BOOL fSave = FALSE;
BOOL fPKCS7Save = FALSE;
DWORD dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
LPSTR pszAddFilename = NULL;
LPSTR pszPutFilename = NULL;
LPSTR pszReadFilename = NULL;
LPSTR pszStoreFilename = NULL;
LPSTR pszSaveFilename = NULL;
LPSTR pszStoreProvider = NULL;
HCERTSTORE hStore;
BOOL fNotify = FALSE;
HANDLE hEvent = NULL;
BOOL fCommit = FALSE;
DWORD dwCommitFlags = 0;
BOOL fDeferClose = FALSE;
#define DEFER_CERT_CNT 5
PCCERT_CONTEXT rgpDeferCert[DEFER_CERT_CNT];
memset(rgpDeferCert, 0, sizeof(rgpDeferCert));
while (--argc>0)
{
if (**++argv == '-')
{
switch(argv[0][1])
{
case 'c':
dwDisplayFlags |= DISPLAY_CHECK_FLAG;
if (argv[0][2]) {
if (0 == _stricmp(argv[0]+2, "Sign"))
dwDisplayFlags |= DISPLAY_CHECK_SIGN_FLAG;
else if (0 == _stricmp(argv[0]+2, "Time"))
dwDisplayFlags |= DISPLAY_CHECK_TIME_FLAG;
else {
printf("Need to specify -cSign | -cTime\n");
Usage();
return -1;
}
}
break;
case 'b':
dwDisplayFlags |= DISPLAY_BRIEF_FLAG;
break;
case 'v':
dwDisplayFlags |= DISPLAY_VERBOSE_FLAG;
break;
case 'u':
dwDisplayFlags |= DISPLAY_UI_FLAG;
break;
case 'K':
dwDisplayFlags |= DISPLAY_KEY_THUMB_FLAG;
break;
case 'd':
if (argv[0][2]) {
if (0 != _stricmp(argv[0]+2, "ALL")) {
printf("Need to specify -dALL\n");
Usage();
return -1;
}
fDeleteAll = TRUE;
} else
fDelete = TRUE;
break;
case 'P':
if (argv[0][2]) {
if (0 == _stricmp(argv[0]+2, "Key"))
fKeyProperty = TRUE;
else if (0 == _stricmp(argv[0]+2, "Archive"))
fArchiveProperty = TRUE;
else if (0 == _stricmp(argv[0]+2, "KeyProvParam"))
fKeyProvParam = TRUE;
else if (0 == _stricmp(argv[0]+2, "SilentKey")) {
fKeyProperty = TRUE;
fSilentKey = TRUE;
} else {
printf("Need to specify -PKey\n");
Usage();
return -1;
}
} else
fProperty = TRUE;
break;
case 'F':
fForceClose = TRUE;
break;
case 'R':
dwContextType = CERT_STORE_CRL_CONTEXT;
break;
case 'T':
dwContextType = CERT_STORE_CTL_CONTEXT;
break;
case 'N':
fNotify = TRUE;
break;
case 'C':
if (argv[0][2]) {
if (0 == _stricmp(argv[0]+2, "Force"))
dwCommitFlags |= CERT_STORE_CTRL_COMMIT_FORCE_FLAG;
else if (0 == _stricmp(argv[0]+2, "Clear"))
dwCommitFlags |= CERT_STORE_CTRL_COMMIT_CLEAR_FLAG;
else {
printf("Need to specify -CForce or -CClear\n");
Usage();
return -1;
}
}
fCommit = TRUE;
break;
case 's':
if (argv[0][2])
pszStoreProvider = argv[0]+2;
fSystemStore = TRUE;
break;
case 't':
fThumbprint = TRUE;
break;
case 'l':
break;
case 'e':
dwCertEncodingType = (DWORD) strtoul(argv[0]+2, NULL, 0);
break;
case 'f':
dwOpenFlags = (DWORD) strtoul(argv[0]+2, NULL, 0);
break;
case 'E':
fExpectError = TRUE;
break;
case 'i':
lIndex = (DWORD) strtol(argv[0]+2, NULL, 0);
break;
case 'a':
case 'A':
case 'I':
pszAddFilename = argv[0]+2;
if (*pszAddFilename == '\0') {
printf("Need to specify filename\n");
Usage();
return -1;
}
if (argv[0][1] == 'A')
dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING;
else if (argv[0][1] == 'I')
dwAddDisposition =
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES;
else
dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
break;
case 'p':
pszPutFilename = argv[0]+2;
if (*pszPutFilename == '\0') {
printf("Need to specify filename\n");
Usage();
return -1;
}
break;
case 'r':
pszReadFilename = argv[0]+2;
if (*pszReadFilename == '\0') {
printf("Need to specify filename\n");
Usage();
return -1;
}
break;
case '7':
fPKCS7Save = TRUE;
case 'S':
fSave = TRUE;
if (argv[0][2])
pszSaveFilename = argv[0]+2;
break;
case 'h':
default:
Usage();
return -1;
}
} else
pszStoreFilename = argv[0];
}
if (dwDisplayFlags & DISPLAY_VERBOSE_FLAG)
dwDisplayFlags &= ~DISPLAY_BRIEF_FLAG;
if (pszStoreFilename == NULL) {
printf("missing store filename\n");
Usage();
return -1;
}
if (pszSaveFilename == NULL) {
if (!fSystemStore)
pszSaveFilename = pszStoreFilename;
else if (fSave) {
printf("missing save filename\n");
Usage();
return -1;
}
}
if (lIndex < 0 && (fDelete || pszPutFilename)) {
printf("Must specify index value\n");
Usage();
return -1;
}
printf("command line: %s\n", GetCommandLine());
{
DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
if (I_CryptGetFileVersion(L"crypt32.dll",
&dwFileVersionMS, &dwFileVersionLS))
printf("crypt32.dll file version:: %d.%d.%d.%d\n",
(dwFileVersionMS >> 16) & 0xFFFF,
dwFileVersionMS & 0xFFFF,
(dwFileVersionLS >> 16) & 0xFFFF,
dwFileVersionLS & 0xFFFF
);
else
PrintLastError("I_CryptGetFileVersion(crypt32.dll)");
}
hStore = NULL;
if (pszStoreProvider) {
LPWSTR pwszStore;
if (pwszStore = AllocAndSzToWsz(pszStoreFilename)) {
hStore = CertOpenStore(
pszStoreProvider,
0, // dwEncodingType
0, // hCryptProv
dwOpenFlags,
pwszStore
);
TestFree(pwszStore);
}
if (hStore == NULL) {
if (dwOpenFlags & CERT_STORE_DELETE_FLAG) {
if (0 == GetLastError())
printf("Successful delete store\n");
else
PrintLastError("CertOpenStore(CERT_STORE_DELETE_FLAG)");
return 0;
} else {
PrintLastError("CertOpenStore");
return -1;
}
}
} else if (!fSystemStore) {
// Attempt to open as encoded certificate CRL or CTL file
switch (dwContextType) {
case CERT_STORE_CRL_CONTEXT:
hStore = OpenCrlStoreFile(pszStoreFilename);
break;
case CERT_STORE_CTL_CONTEXT:
hStore = OpenCtlStoreFile(pszStoreFilename);
break;
case CERT_STORE_CERTIFICATE_CONTEXT:
hStore = OpenCertStoreFile(pszStoreFilename);
default:
break;
}
}
if (NULL == hStore) {
// Attempt to open the store
if (!fSystemStore && fCommit) {
dwOpenFlags |= CERT_FILE_STORE_COMMIT_ENABLE_FLAG;
pszSaveFilename = NULL;
}
dwOpenFlags |= CERT_STORE_SET_LOCALIZED_NAME_FLAG;
hStore = OpenStoreEx(fSystemStore, pszStoreFilename, dwOpenFlags);
if (hStore == NULL)
return -1;
}
if (dwOpenFlags & CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG) {
printf("CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG was set\n");
if (!fForceClose)
fDeferClose = TRUE;
}
#if 0
if (fNotify && fSystemStore && !FIsWinNT()) {
printf("Change Notify not supported for Win95 Registry\n");
fNotify = FALSE;
}
#endif
if (fNotify) {
// Create event to be notified
if (NULL == (hEvent = CreateEvent(
NULL, // lpsa
FALSE, // fManualReset
FALSE, // fInitialState
NULL))) // lpszEventName
PrintLastError("CreateEvent");
else {
// Register the event to be signaled when the store changes
if (!CertControlStore(
hStore,
0, // dwFlags
CERT_STORE_CTRL_NOTIFY_CHANGE,
&hEvent
)) {
PrintLastError("CertControlStore(NOTIFY_CHANGE)");
fNotify = FALSE;
} else
Sleep(5); // Allow callback thread to be scheduled
}
}
if (pszReadFilename) {
printf("Reading\n");
switch (dwContextType) {
case CERT_STORE_CRL_CONTEXT:
ReadCrl(pszReadFilename, dwDisplayFlags);
break;
case CERT_STORE_CTL_CONTEXT:
ReadCtl(pszReadFilename, dwDisplayFlags);
break;
default:
ReadCert(hStore, pszReadFilename, dwDisplayFlags);
}
} else if (pszAddFilename) {
BOOL fResult;
printf("Adding\n");
switch (dwContextType) {
case CERT_STORE_CRL_CONTEXT:
fResult = AddCrl(hStore, pszAddFilename, dwAddDisposition,
fExpectError);
break;
case CERT_STORE_CTL_CONTEXT:
fResult = AddCtl(hStore, pszAddFilename, dwAddDisposition,
fExpectError);
break;
default:
fResult = AddCert(hStore, pszAddFilename, dwAddDisposition,
fExpectError);
}
if (fResult)
fSave = TRUE;
} else if (fDeleteAll & !fArchiveProperty) {
printf("Deleting All\n");
if (CERT_STORE_CRL_CONTEXT == dwContextType) {
PCCRL_CONTEXT pCrl;
while (pCrl = CertEnumCRLsInStore(hStore, NULL)) {
if (!CertDeleteCRLFromStore(pCrl)) {
if (fExpectError)
PrintExpectedError("CertDeleteCRLFromStore");
else
PrintLastError("CertDeleteCRLFromStore");
break;
} else if (fExpectError)
PrintNoError("CertDeleteCRLFromStore");
else
fSave = TRUE;
}
} else if (CERT_STORE_CTL_CONTEXT == dwContextType) {
PCCTL_CONTEXT pCtl;
while (pCtl = CertEnumCTLsInStore(hStore, NULL)) {
if (!CertDeleteCTLFromStore(pCtl)) {
if (fExpectError)
PrintExpectedError("CertDeleteCTLFromStore");
else
PrintLastError("CertDeleteCTLFromStore");
break;
} else if (fExpectError)
PrintNoError("CertDeleteCTLFromStore");
else
fSave = TRUE;
}
} else {
PCCERT_CONTEXT pCert;
while (pCert = CertEnumCertificatesInStore(hStore, NULL)) {
if (!CertDeleteCertificateFromStore(pCert)) {
if (fExpectError)
PrintExpectedError("CertDeleteCertificateFromStore");
else
PrintLastError("CertDeleteCertificateFromStore");
break;
} else if (fExpectError)
PrintNoError("CertDeleteCertificateFromStore");
else
fSave = TRUE;
}
}
} else if (CERT_STORE_CRL_CONTEXT == dwContextType) {
BOOL fFound = FALSE;
LONG i;
PCCRL_CONTEXT pCrl = NULL;
DWORD dwFlags;
for (i = 0;; i++) {
dwFlags = CERT_STORE_TIME_VALIDITY_FLAG;
pCrl = CertGetCRLFromStore(
hStore,
NULL, // pIssuerContext
pCrl,
&dwFlags);
if (pCrl == NULL)
break;
if ((lIndex >= 0) && (lIndex != i))
continue;
fFound = TRUE;
if (fProperty) {
CRYPT_DATA_BLOB Data;
BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
Data.pbData = rgbAux;
Data.cbData = sizeof(rgbAux);
if (!CertSetCRLContextProperty(
pCrl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&Data
)) {
if (fExpectError)
PrintExpectedError("CertSetCRLContextProperty");
else
PrintLastError("CertSetCRLContextProperty");
} else if (fExpectError)
PrintNoError("CertSetCRLContextProperty");
else
fSave = TRUE;
}
if (fDelete) {
printf("Deleting\n");
if (!CertDeleteCRLFromStore(pCrl)) {
if (fExpectError)
PrintExpectedError("CertDeleteCRLFromStore");
else
PrintLastError("CertDeleteCRLFromStore");
} else if (fExpectError)
PrintNoError("CertDeleteCRLFromStore");
else
fSave = TRUE;
break;
} else if (pszPutFilename) {
printf("Putting\n");
if (!WriteDERToFile(
pszPutFilename,
pCrl->pbCrlEncoded,
pCrl->cbCrlEncoded
))
PrintLastError("Put CRL::WriteDERToFile");
CertFreeCRLContext(pCrl);
break;
} else {
if (fThumbprint)
fSave = TRUE;
printf("===== %d =====\n", i);
DisplayCrl(pCrl, dwDisplayFlags);
DisplayVerifyFlags("CRL", dwFlags);
if (lIndex == i) {
CertFreeCRLContext(pCrl);
break;
}
}
}
if (!fFound)
printf("CRL not found\n");
} else if (CERT_STORE_CTL_CONTEXT == dwContextType) {
BOOL fFound = FALSE;
LONG i;
PCCTL_CONTEXT pCtl = NULL;
for (i = 0;; i++) {
pCtl = CertEnumCTLsInStore(
hStore,
pCtl);
if (pCtl == NULL)
break;
if ((lIndex >= 0) && (lIndex != i))
continue;
fFound = TRUE;
if (fProperty) {
CRYPT_DATA_BLOB Data;
BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
Data.pbData = rgbAux;
Data.cbData = sizeof(rgbAux);
if (!CertSetCTLContextProperty(
pCtl,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&Data
)) {
if (fExpectError)
PrintExpectedError("CertSetCTLContextProperty");
else
PrintLastError("CertSetCTLContextProperty");
} else if (fExpectError)
PrintNoError("CertSetCTLContextProperty");
else
fSave = TRUE;
}
if (fDelete) {
printf("Deleting\n");
if (!CertDeleteCTLFromStore(pCtl)) {
if (fExpectError)
PrintExpectedError("CertDeleteCTLFromStore");
else
PrintLastError("CertDeleteCTLFromStore");
} else if (fExpectError)
PrintNoError("CertDeleteCTLFromStore");
else
fSave = TRUE;
break;
} else if (pszPutFilename) {
printf("Putting\n");
if (!WriteDERToFile(
pszPutFilename,
pCtl->pbCtlEncoded,
pCtl->cbCtlEncoded
))
PrintLastError("Put CTL::WriteDERToFile");
CertFreeCTLContext(pCtl);
break;
} else {
if (fThumbprint)
fSave = TRUE;
printf("===== %d =====\n", i);
DisplayCtl(pCtl, dwDisplayFlags, hStore);
if (lIndex == i) {
CertFreeCTLContext(pCtl);
break;
}
}
}
if (!fFound)
printf("CTL not found\n");
} else {
BOOL fFound = FALSE;
LONG i;
PCCERT_CONTEXT pCert = NULL;
pCert = NULL;
for (i = 0;; i++) {
pCert = CertEnumCertificatesInStore(
hStore,
pCert);
if (pCert == NULL)
break;
if ((lIndex >= 0) && (lIndex != i))
continue;
fFound = TRUE;
if (fForceClose)
CertDuplicateCertificateContext(pCert);
else if (fDeferClose) {
CertFreeCertificateContext(rgpDeferCert[0]);
rgpDeferCert[0] = CertDuplicateCertificateContext(pCert);
}
if (fProperty && !fDelete) {
CRYPT_DATA_BLOB Data;
BYTE rgbAux[] = {0xDE, 0xAD, 0xBE, 0xEF};
Data.pbData = rgbAux;
Data.cbData = sizeof(rgbAux);
if (!CertSetCertificateContextProperty(
pCert,
CERT_FIRST_USER_PROP_ID,
0, // dwFlags
&Data
)) {
if (fExpectError)
PrintExpectedError("CertSetCertificateContextProperty");
else
PrintLastError("CertSetCertificateContextProperty");
} else if (fExpectError)
PrintNoError("CertSetCertificateContextProperty");
else
fSave = TRUE;
// Test that we properly update the PROV_HANDLE and KEY_SPEC
// properties
HCRYPTPROV hProv = (HCRYPTPROV) 0x12345678;
HCRYPTPROV hProv2 = 0;
DWORD dwKeySpec = 0xdeadbeef;
DWORD dwKeySpec2 = 0;
if (!CertSetCertificateContextProperty(
pCert,
CERT_KEY_PROV_HANDLE_PROP_ID,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
(void *) hProv
))
PrintLastError(
"CertSetCertificateContextProperty(PROV_HANDLE)");
else if (!CertSetCertificateContextProperty(
pCert,
CERT_KEY_SPEC_PROP_ID,
0, // dwFlags
&dwKeySpec
))
PrintLastError(
"CertSetCertificateContextProperty(KEY_SPEC)");
else {
DWORD cbData = sizeof(hProv);
CERT_KEY_CONTEXT KeyContext;
if (!CertGetCertificateContextProperty(
pCert,
CERT_KEY_PROV_HANDLE_PROP_ID,
&hProv2,
&cbData))
PrintLastError(
"CertGetCertificateContextProperty(PROV_HANDLE)");
else if (hProv2 != hProv)
PrintLastError(
"PROV_HANDLE property not updated properly\n");
cbData = sizeof(dwKeySpec);
if (!CertGetCertificateContextProperty(
pCert,
CERT_KEY_SPEC_PROP_ID,
&dwKeySpec2,
&cbData))
PrintLastError(
"CertGetCertificateContextProperty(KEY_SPEC)");
else if (dwKeySpec2 != dwKeySpec)
PrintLastError(
"KEY_SPEC property not updated properly\n");
cbData = sizeof(KeyContext);
if (!CertGetCertificateContextProperty(
pCert,
CERT_KEY_CONTEXT_PROP_ID,
&KeyContext,
&cbData))
PrintLastError(
"CertGetCertificateContextProperty(KEY_CONTEXT)");
else if (KeyContext.dwKeySpec != dwKeySpec ||
KeyContext.hCryptProv != hProv)
PrintLastError(
"KEY_CONTEXT property not updated properly\n");
}
hProv = 0;
if (!CertSetCertificateContextProperty(
pCert,
CERT_KEY_PROV_HANDLE_PROP_ID,
0, // dwFlags
(void *) hProv
))
PrintLastError(
"CertSetCertificateContextProperty(PROV_HANDLE)");
}
if (fKeyProperty && !fDelete) {
if (!CryptFindCertificateKeyProvInfo(
pCert,
fSilentKey ? CRYPT_FIND_SILENT_KEYSET_FLAG : 0,
NULL // pvReserved
)) {
if (fExpectError)
PrintExpectedError("CryptFindCertificateKeyProvInfo");
else
PrintLastError("CryptFindCertificateKeyProvInfo");
} else {
printf("Found KEY_PROV_INFO property\n");
if (fExpectError)
PrintNoError("CryptFindCertificateKeyProvInfo");
else {
HCRYPTPROV hProv1 = 0;
HCRYPTPROV hProv2 = 0;
DWORD dwKeySpec1;
DWORD dwKeySpec2;
BOOL fCallerFreeProv;
fSave = TRUE;
dwKeySpec1 = 0x12341111;
fCallerFreeProv = TRUE;
if (!CryptAcquireCertificatePrivateKey(
pCert,
(fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
CRYPT_ACQUIRE_CACHE_FLAG |
CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL, // pvReserved
&hProv1,
&dwKeySpec1,
&fCallerFreeProv
))
PrintLastError("CryptAcquireCertificatePrivateKey");
else if (fCallerFreeProv)
printf("failed => cached acquire returned FreeProv\n");
dwKeySpec2 = 0x12342222;
fCallerFreeProv = FALSE;
if (!CryptAcquireCertificatePrivateKey(
pCert,
(fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL, // pvReserved
&hProv2,
&dwKeySpec2,
&fCallerFreeProv
))
PrintLastError("CryptAcquireCertificatePrivateKey");
else {
if (!fCallerFreeProv)
printf("failed => uncached acquire didn't return FreeProv\n");
if (hProv2 == hProv1)
printf("failed => uncached == cached hProv\n");
if (dwKeySpec2 != dwKeySpec1)
printf("failed => uncached != cached dwKeySpec\n");
CryptReleaseContext(hProv2, 0);
}
if (hProv1) {
dwKeySpec2 = 0x12343333;
fCallerFreeProv = TRUE;
if (!CryptAcquireCertificatePrivateKey(
pCert,
(fSilentKey ? CRYPT_ACQUIRE_SILENT_FLAG : 0) |
CRYPT_ACQUIRE_CACHE_FLAG |
CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL, // pvReserved
&hProv2,
&dwKeySpec2,
&fCallerFreeProv
))
PrintLastError("CryptAcquireCertificatePrivateKey");
else {
if (fCallerFreeProv)
printf("failed => uncached acquire returned FreeProv\n");
if (hProv2 != hProv1)
printf("failed => cached != cached hProv\n");
if (dwKeySpec2 != dwKeySpec1)
printf("failed => cached != cached dwKeySpec\n");
}
}
}
}
}
if (fArchiveProperty) {
CRYPT_DATA_BLOB ArchiveBlob = { 0, NULL };
if (!CertSetCertificateContextProperty(
pCert,
CERT_ARCHIVED_PROP_ID,
0, // dwFlags
(fDelete || fDeleteAll) ? NULL : &ArchiveBlob
)) {
if (fExpectError)
PrintExpectedError(
"CertSetCertificateContextProperty(ARCHIVE)");
else
PrintLastError(
"CertSetCertificateContextProperty(ARCHIVE)");
}
} else if (fDelete) {
if (fProperty || fKeyProperty) {
DWORD PropId;
if (fKeyProperty) {
printf("Deleting KEY_PROV_INFO property\n");
PropId = CERT_KEY_PROV_INFO_PROP_ID;
} else {
printf("Deleting property\n");
PropId = CERT_FIRST_USER_PROP_ID;
}
if (!CertSetCertificateContextProperty(
pCert,
PropId,
0, // dwFlags
NULL
)) {
if (fExpectError)
PrintExpectedError("CertSetCertificateContextProperty");
else
PrintLastError("CertSetCertificateContextProperty");
} else if (fExpectError)
PrintNoError("CertSetCertificateContextProperty");
else
fSave = TRUE;
CertFreeCertificateContext(pCert);
} else {
printf("Deleting\n");
if (!CertDeleteCertificateFromStore(pCert)) {
if (fExpectError)
PrintExpectedError("CertDeleteCertificateFromStore");
else
PrintLastError("CertDeleteCertificateFromStore");
} else if (fExpectError)
PrintNoError("CertDeleteCertificateFromStore");
else
fSave = TRUE;
}
break;
} else if (pszPutFilename) {
printf("Putting\n");
if (!WriteDERToFile(
pszPutFilename,
pCert->pbCertEncoded,
pCert->cbCertEncoded
))
PrintLastError("Put Cert::WriteDERToFile");
CertFreeCertificateContext(pCert);
break;
} else {
if (fKeyProvParam) {
printf("Setting KeyProvInfo parameters\n");
SetKeyProvParams(pCert);
}
if (fThumbprint)
fSave = TRUE;
printf("===== %d =====\n", i);
DisplayCert(pCert, dwDisplayFlags);
if (lIndex == i) {
CertFreeCertificateContext(pCert);
break;
}
}
}
if (!fFound)
printf("Certificate not found\n");
if (fForceClose) {
// Do incomplete enumerations to test out external store
// logic
pCert = GetNthCert(hStore, 0);
CertFreeCertificateContext(pCert);
pCert = GetNthCert(hStore, 0);
GetNthCert(hStore, (i-1)/2);
GetNthCert(hStore, i-1);
} else if (fDeferClose) {
rgpDeferCert[1] = GetNthCert(hStore, 0);
CertFreeCertificateContext(rgpDeferCert[1]);
rgpDeferCert[1] = GetNthCert(hStore, 0);
rgpDeferCert[2] = GetNthCert(hStore, (i-1)/2);
rgpDeferCert[3] = GetNthCert(hStore, i-1);
}
}
if (fSave && pszSaveFilename)
SaveStoreEx(hStore, fPKCS7Save, pszSaveFilename);
if (fCommit) {
printf("Committing store changes::");
if (dwCommitFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG)
printf(" FORCE");
if (dwCommitFlags & CERT_STORE_CTRL_COMMIT_CLEAR_FLAG)
printf(" CLEAR");
printf("\n");
if (!CertControlStore(
hStore,
dwCommitFlags,
CERT_STORE_CTRL_COMMIT,
NULL
))
PrintLastError("CertControlStore(COMMIT)");
}
if (fNotify) {
BOOL fSignaled;
// Check if event was signaled
if (WAIT_TIMEOUT == WaitForSingleObjectEx(
hEvent,
100, // dwMilliseconds
FALSE // bAlertable
))
fSignaled = FALSE;
else
fSignaled = TRUE;
if (!fSignaled) {
printf("No store change notify\n");
if (pszAddFilename || fDeleteAll || fDelete || fProperty)
printf("failed => expected notify for add, delete or property\n");
} else {
printf("There was a store change notify\n");
if (!(pszAddFilename || fDeleteAll || fDelete || fProperty))
printf("failed => unexpected notify\n");
if (!CertControlStore(
hStore,
0, // dwFlags
CERT_STORE_CTRL_RESYNC,
NULL // pvCtrlPara
))
PrintLastError("CertControlStore(RESYNC)");
else {
printf("\n");
printf(">>>>> After Resync >>>>>\n");
DisplayStore(hStore, DISPLAY_BRIEF_FLAG);
}
}
}
if (hEvent)
CloseHandle(hEvent);
if (fForceClose) {
CertDuplicateStore(hStore);
if (CertCloseStore(hStore,
CERT_CLOSE_STORE_CHECK_FLAG | CERT_CLOSE_STORE_FORCE_FLAG))
printf("failed => CertCloseStore(FORCE) didn't fail as expected\n");
else
printf("CertCloseStore(FORCE) returned expected nonzero status: 0x%x\n",
GetLastError());
} else if (fDeferClose) {
// Check if any defered certificates
DWORD i;
fDeferClose = FALSE;
for (i = 0; i < DEFER_CERT_CNT; i++) {
if (rgpDeferCert[i]) {
fDeferClose = TRUE;
break;
}
}
if (fDeferClose) {
CertDuplicateStore(hStore);
CertCloseStore(hStore, 0);
if (CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
printf("failed => CertCloseStore(DEFER) didn't fail as expected\n");
else
printf("CertCloseStore(DEFER) returned expected nonzero status: 0x%x\n",
GetLastError());
for (i = 0; i < DEFER_CERT_CNT; i++) {
CertFreeCertificateContext(rgpDeferCert[i]);
}
} else {
if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore(DEFER)");
}
} else {
if (!CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG))
PrintLastError("CertCloseStore");
}
return 0;
}