|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: tcopycer.cpp
//
// Contents: Cert Store Copy Cert/CRL/CTL context API Tests
//
// See Usage() for list of test options.
//
//
// Functions: main
//
// History: 11-Apr-96 philh created
// 07-Jun-96 HelleS Added printing the command line
// and Failed or Passed at the end.
// 20-Aug-96 jeffspel name changes
//
//--------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include "wincrypt.h"
#include "certtest.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
static void Usage(void) { printf("Usage: tcopycer [options] <Src StoreName> <Dst StoreName>\n"); printf("Options are:\n"); printf(" -h - This message\n"); printf(" -s - Dst \"StoreName\" System store\n"); printf(" -7 - PKCS# 7 save for Dst if filename\n"); printf(" -S - Src \"StoreName\" System store\n"); printf(" -R - Replace certs that exist\n"); printf(" -I - Replace certs with property inheritance\n"); printf(" -A - Always add a new cert\n"); printf(" -b<number> - Add Base CRL having specified number\n"); printf(" -f<number> - Add Freshest CRL having specified number\n"); printf(" -a[<ValueString>] - Only certs matching name attribute value\n"); printf("\n"); printf("-b and/or -f only copy the CRL having the specified number\n"); printf("-b and/or -f delete all CRLs unless -A is also specified\n"); printf("\n"); }
static void DisplayFindAttr(DWORD cRDNAttr, CERT_RDN_ATTR rgRDNAttr[]) { DWORD i;
for (i = 0; i < cRDNAttr; i++) { LPSTR pszObjId = rgRDNAttr[i].pszObjId; LPSTR pszValue = (LPSTR) rgRDNAttr[i].Value.pbData; printf(" [%d] ", i); if (pszObjId) printf("%s ", pszObjId); if (rgRDNAttr[i].dwValueType) printf("ValueType: %d ", rgRDNAttr[i].dwValueType); if (pszValue == NULL) pszValue = "<NONE>"; printf("Value: %s\n", pszValue); } }
int _cdecl main(int argc, char * argv[]) { int ReturnStatus = 0; BOOL fSrcSystemStore = FALSE; BOOL fDstSystemStore = FALSE; LPSTR pszSrcStoreFilename = NULL; LPSTR pszDstStoreFilename = NULL;
BOOL fPKCS7Save = FALSE; DWORD dwAddDisposition = CERT_STORE_ADD_USE_EXISTING;
HANDLE hSrcStore = NULL; HANDLE hDstStore = NULL;
#define MAX_RDN_ATTR 20
DWORD cRDNAttr = 0; CERT_RDN_ATTR rgRDNAttr[MAX_RDN_ATTR + 1]; memset (rgRDNAttr, 0, sizeof(rgRDNAttr)); CERT_RDN NameRDN;
BOOL fBaseOrFreshestCrl = FALSE; int iBaseCrl = -1; int iFreshestCrl = -1;
while (--argc>0) { if (**++argv == '-') { switch(argv[0][1]) { case 's': fDstSystemStore = TRUE; break; case '7': fPKCS7Save = TRUE; break; case 'S': fSrcSystemStore = TRUE; break; case 'R': dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING; break; case 'A': dwAddDisposition = CERT_STORE_ADD_ALWAYS; break; case 'I': dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES; break; case 'a': if (cRDNAttr >= MAX_RDN_ATTR) { printf("Maximum number of attributes: %d\n", MAX_RDN_ATTR); Usage(); return -1; } rgRDNAttr[cRDNAttr].Value.cbData = strlen(argv[0] + 2); if (rgRDNAttr[cRDNAttr].Value.cbData == 0) rgRDNAttr[cRDNAttr].Value.pbData = NULL; else rgRDNAttr[cRDNAttr].Value.pbData = (BYTE *) (argv[0] + 2); cRDNAttr++; break; case 'b': iBaseCrl = atoi(argv[0]+2); fBaseOrFreshestCrl = TRUE; break; case 'f': iFreshestCrl = atoi(argv[0]+2); fBaseOrFreshestCrl = TRUE; break; case 'h': default: goto BadUsage;
} } else { if (pszSrcStoreFilename == NULL) pszSrcStoreFilename = argv[0]; else if (pszDstStoreFilename == NULL) pszDstStoreFilename = argv[0]; else { printf("too many store filenames\n"); goto BadUsage; } } }
if (pszDstStoreFilename == NULL) { printf("missing store filename\n"); goto BadUsage; }
printf("command line: %s\n", GetCommandLine());
// Attempt to open the source and destination stores
hSrcStore = OpenStore(fSrcSystemStore, pszSrcStoreFilename); if (hSrcStore == NULL) goto ErrorReturn; hDstStore = OpenStore(fDstSystemStore, pszDstStoreFilename); if (hDstStore == NULL) { if (!CertCloseStore(hSrcStore, 0)) PrintLastError("CertCloseStore"); goto ErrorReturn; }
if (cRDNAttr) { printf("Copy certs matching attribute values::\n"); DisplayFindAttr(cRDNAttr, rgRDNAttr); NameRDN.cRDNAttr = cRDNAttr; NameRDN.rgRDNAttr = rgRDNAttr; }
if (!fBaseOrFreshestCrl) { DWORD dwCopyCnt = 0; PCCERT_CONTEXT pCert = NULL; int i = 0;
while (TRUE) { BOOL fResult;
if (cRDNAttr) { pCert = CertFindCertificateInStore( hSrcStore, dwCertEncodingType, 0, // dwFindFlags,
CERT_FIND_SUBJECT_ATTR, &NameRDN, pCert ); if (pCert) { printf("===== Copy Cert %d =====\n", i++); DisplayCert(pCert, DISPLAY_BRIEF_FLAG); } } else pCert = CertEnumCertificatesInStore( hSrcStore, pCert ); if (pCert == NULL) break; if (!(fResult = CertAddCertificateContextToStore( hDstStore, pCert, CERT_STORE_ADD_NEW, NULL))) { if (GetLastError() == CRYPT_E_EXISTS) { printf("Cert %d already exists in store\n", dwCopyCnt);
DWORD dwNewer;
if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING) dwNewer = CERT_STORE_ADD_NEWER; else if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES) dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES; else dwNewer = 0;
fResult = FALSE; if (dwNewer) { fResult = CertAddCertificateContextToStore( hDstStore, pCert, dwNewer, NULL); if (fResult) printf("Added newer cert\n"); else { DWORD dwErr = GetLastError(); if (dwErr == CRYPT_E_EXISTS) printf("Didn't add older cert\n"); else PrintLastError("Cert: CERT_ADD_NEWER"); } }
if (!fResult) fResult = CertAddCertificateContextToStore( hDstStore, pCert, dwAddDisposition, NULL); } } if (!fResult) { PrintLastError("CertAddCertificateContextToStore"); ReturnStatus = -1; CertFreeCertificateContext(pCert); break; } else { dwCopyCnt++;
}
} printf("Copied %d certificates\n", dwCopyCnt);
}
if (fBaseOrFreshestCrl) { DWORD fCopyCrl = FALSE; PCCRL_CONTEXT pCrl;
if (dwAddDisposition != CERT_STORE_ADD_ALWAYS) { // Delete all existing CRLs from the destination store
pCrl = NULL; while (pCrl = CertEnumCRLsInStore(hDstStore, pCrl)) { PCCRL_CONTEXT pDeleteCrl = CertDuplicateCRLContext(pCrl); if (!CertDeleteCRLFromStore(pDeleteCrl)) PrintLastError("CertDeleteCRLFromStore"); } }
pCrl = NULL; while (pCrl = CertEnumCRLsInStore(hSrcStore, pCrl)) { PCERT_EXTENSION pDeltaExt; PCERT_EXTENSION pBaseExt; DWORD cbInt; int iNum;
pDeltaExt = CertFindExtension( szOID_DELTA_CRL_INDICATOR, pCrl->pCrlInfo->cExtension, pCrl->pCrlInfo->rgExtension ); pBaseExt = CertFindExtension( szOID_CRL_NUMBER, pCrl->pCrlInfo->cExtension, pCrl->pCrlInfo->rgExtension ); if (pDeltaExt) { // Freshest, delta CRL
if (0 <= iFreshestCrl) { cbInt = sizeof(iNum); if (!CryptDecodeObject( pCrl->dwCertEncodingType, X509_INTEGER, pDeltaExt->Value.pbData, pDeltaExt->Value.cbData, 0, // dwFlags
&iNum, &cbInt )) PrintLastError("CryptDecodeObject(DeltaCrlNumber)"); else if (iFreshestCrl == iNum) { if (CertAddCRLContextToStore( hDstStore, pCrl, CERT_STORE_ADD_ALWAYS, NULL )) { printf("Added freshest CRL %d\n", iNum); fCopyCrl = TRUE; } else PrintLastError("CertAddCRLContextToStore(Freshest)"); } } } else if (pBaseExt) { // Base CRL
if (0 <= iBaseCrl) { cbInt = sizeof(iNum); if (!CryptDecodeObject( pCrl->dwCertEncodingType, X509_INTEGER, pBaseExt->Value.pbData, pBaseExt->Value.cbData, 0, // dwFlags
&iNum, &cbInt )) PrintLastError("CryptDecodeObject(BaseCrlNumber)"); else if (iBaseCrl == iNum) { if (CertAddCRLContextToStore( hDstStore, pCrl, CERT_STORE_ADD_ALWAYS, NULL )) { printf("Added base CRL %d\n", iNum); fCopyCrl = TRUE; } else PrintLastError("CertAddCRLContextToStore(Base)"); } } } }
if (!fCopyCrl) printf("failed => no base or freshest, delta CRLs copied\n");
} else if (cRDNAttr == 0) { DWORD dwCopyCnt; PCCRL_CONTEXT pCrl = NULL; PCCTL_CONTEXT pCtl = NULL; DWORD dwFlags;
dwCopyCnt = 0; while (TRUE) { BOOL fResult;
dwFlags = 0; pCrl = CertGetCRLFromStore( hSrcStore, NULL, // pIssuerContext
pCrl, &dwFlags); if (pCrl == NULL) break; if (!(fResult = CertAddCRLContextToStore( hDstStore, pCrl, CERT_STORE_ADD_NEW, NULL))) { if (GetLastError() == CRYPT_E_EXISTS) { printf("CRL %d already exists in store\n", dwCopyCnt);
DWORD dwNewer;
if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING) dwNewer = CERT_STORE_ADD_NEWER; else if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES) dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES; else dwNewer = 0;
fResult = FALSE; if (dwNewer) { fResult = CertAddCRLContextToStore( hDstStore, pCrl, dwNewer, NULL); if (fResult) printf("Added newer CRL\n"); else { DWORD dwErr = GetLastError(); if (dwErr == CRYPT_E_EXISTS) printf("Didn't add older CRL\n"); else PrintLastError("CRL: CERT_ADD_NEWER"); } }
if (!fResult) fResult = CertAddCRLContextToStore( hDstStore, pCrl, dwAddDisposition, NULL); } } if (!fResult) { PrintLastError("CertAddCRLContextToStore"); ReturnStatus = -1; CertFreeCRLContext(pCrl); break; } else dwCopyCnt++;
} printf("Copied %d CRLs\n", dwCopyCnt);
dwCopyCnt = 0; while (TRUE) { BOOL fResult;
dwFlags = 0; pCtl = CertEnumCTLsInStore( hSrcStore, pCtl ); if (pCtl == NULL) break; if (!(fResult = CertAddCTLContextToStore( hDstStore, pCtl, CERT_STORE_ADD_NEW, NULL))) { if (GetLastError() == CRYPT_E_EXISTS) { printf("CTL %d already exists in store\n", dwCopyCnt);
DWORD dwNewer;
if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING) dwNewer = CERT_STORE_ADD_NEWER; else if (dwAddDisposition == CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES) dwNewer = CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES; else dwNewer = 0;
fResult = FALSE; if (dwNewer) { fResult = CertAddCTLContextToStore( hDstStore, pCtl, dwNewer, NULL); if (fResult) printf("Added newer CTL\n"); else { DWORD dwErr = GetLastError(); if (dwErr == CRYPT_E_EXISTS) printf("Didn't add older CTL\n"); else PrintLastError("CTL: CERT_ADD_NEWER"); } }
if (!fResult) fResult = CertAddCTLContextToStore( hDstStore, pCtl, dwAddDisposition, NULL); } } if (!fResult) { PrintLastError("CertAddCTLContextToStore"); ReturnStatus = -1; CertFreeCTLContext(pCtl); break; } else dwCopyCnt++;
} printf("Copied %d CTLs\n", dwCopyCnt);
}
if (!fDstSystemStore) SaveStoreEx(hDstStore, fPKCS7Save, pszDstStoreFilename);
if (!CertCloseStore(hSrcStore, 0)) { PrintLastError("CertCloseStore(hSrcStore)"); ReturnStatus = -1; } if (!CertCloseStore(hDstStore, 0)) { PrintLastError("CertCloseStore(hDstStore)"); ReturnStatus = -1; } if (-1 == ReturnStatus) goto ErrorReturn; ReturnStatus = 0; goto CommonReturn;
BadUsage: Usage(); ErrorReturn: ReturnStatus = -1; CommonReturn: if (!ReturnStatus) printf("Passed\n"); else printf("Failed\n"); return ReturnStatus; }
|