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.
539 lines
18 KiB
539 lines
18 KiB
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|