windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/initpki/initpki.cpp

1206 lines
34 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: initpki.cpp
//
// Contents: migrates Bob Store to SPC store and adds root certificates
//
// History: 03-Jun-97 kirtd Created
//
//----------------------------------------------------------------------------
#include "global.hxx"
#include "cryptreg.h"
#include "..\mscat32\mscatprv.h"
HMODULE hModule = NULL;
//////////////////////////////////////////////////////////////////
#define INITPKI_HRESULT_FROM_WIN32(a) ((a >= 0x80000000) ? a : HRESULT_FROM_WIN32(a))
#define SHA1_HASH_LENGTH 20
#define wsz_ROOT_STORE L"Root"
#define wsz_TRUST_STORE L"Trust"
#define wsz_CA_STORE L"CA"
#define wsz_TRUST_PUB_STORE L"TrustedPublisher"
#define wsz_DISALLOWED_STORE L"Disallowed"
static LPCWSTR rgpwszPredefinedEnterpriseStore[] = {
wsz_ROOT_STORE,
wsz_TRUST_STORE,
wsz_CA_STORE,
wsz_TRUST_PUB_STORE,
wsz_DISALLOWED_STORE
};
#define NUM_PREDEFINED_ENTERPRISE_STORE \
(sizeof(rgpwszPredefinedEnterpriseStore) / \
sizeof(rgpwszPredefinedEnterpriseStore[0]))
void RegisterEnterpriseStores()
{
DWORD i;
for (i = 0; i < NUM_PREDEFINED_ENTERPRISE_STORE; i++) {
CertRegisterSystemStore(
rgpwszPredefinedEnterpriseStore[i],
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
NULL, // pSystemStoreInfo
NULL // pvReserved
);
}
}
void RemoveCert(HCERTSTORE hStore, BYTE *pThumbPrint)
{
PCERT_CONTEXT pCertContext;
CRYPT_HASH_BLOB CryptHashBlob;
CryptHashBlob.cbData = SHA1_HASH_LENGTH;
CryptHashBlob.pbData = pThumbPrint;
pCertContext = (PCERT_CONTEXT)CertFindCertificateInStore( hStore,
X509_ASN_ENCODING,
0,
CERT_FIND_SHA1_HASH,
&CryptHashBlob,
NULL);
if (pCertContext)
{
CertDeleteCertificateFromStore(pCertContext);
}
}
//
// if byte 0 is null, make sure to change while loop below!
//
BYTE CertRemoveList[][SHA1_HASH_LENGTH] =
{
{ 0x4B, 0x33, 0x8D, 0xCD, 0x50, 0x18, 0x10, 0xB9, 0x36, 0xA0,
0x63, 0x61, 0x4C, 0x3C, 0xDD, 0x3F, 0xC2, 0xC4, 0x88, 0x55 }, // GTE Glue - '96
{ 0x56, 0xB0, 0x65, 0xA7, 0x4B, 0xDC, 0xE3, 0x7C, 0x96, 0xD3,
0xBA, 0x69, 0x81, 0x08, 0x02, 0xD5, 0x87, 0x03, 0xC0, 0xBD }, // Verisign Comm Glue - '96
{ 0x13, 0x39, 0x72, 0xAA, 0x97, 0xD3, 0x65, 0xFB, 0x6A, 0x1D,
0x47, 0xA5, 0xC7, 0x7A, 0x5C, 0x03, 0x94, 0xBD, 0xB9, 0xED }, // Verisign Indv Glue - '96
{ 0x69, 0xD0, 0x4F, 0xFB, 0x62, 0xE1, 0xC9, 0xAE, 0x30, 0x76,
0x99, 0x2A, 0xE7, 0x46, 0xFD, 0x69, 0x08, 0x3A, 0xBD, 0xE9 }, // MS Root cert - '96
{ 0xA7, 0xD7, 0xD5, 0xFD, 0xBB, 0x26, 0xB4, 0x10, 0xC1, 0xD6,
0x7A, 0xFB, 0xF5, 0xC9, 0x05, 0x39, 0x42, 0xDE, 0xE0, 0xEF }, // MS SGC Root Authority - '99
// { 0xCC, 0x7E, 0xD0, 0x77, 0xF0, 0xF2, 0x92, 0x59, 0x5A, 0x81,
// 0x66, 0xB0, 0x17, 0x09, 0xE2, 0x0C, 0x08, 0x84, 0xA5, 0xF8 }, // verisign "Class1" - '97
//
// { 0xD4, 0x73, 0x5D, 0x8A, 0x9A, 0xE5, 0xBC, 0x4B, 0x0A, 0x0D,
// 0xC2, 0x70, 0xD6, 0xA6, 0x25, 0x38, 0xA5, 0x87, 0xD3, 0x2F }, // verisign "timestamp" - '97
//
// { 0x68, 0x8B, 0x6E, 0xB8, 0x07, 0xE8, 0xED, 0xA5, 0xC7, 0xB1,
// 0x7C, 0x43, 0x93, 0xD0, 0x79, 0x5F, 0x0F, 0xAE, 0x15, 0x5F }, // verisign "commercial" - '97
//
// { 0xB1, 0x9D, 0xD0, 0x96, 0xDC, 0xD4, 0xE3, 0xE0, 0xFD, 0x67,
// 0x68, 0x85, 0x50, 0x5A, 0x67, 0x2C, 0x43, 0x8D, 0x4E, 0x9C }, // verisign "individual" - '97
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } // term
};
//+---------------------------------------------------------------------------
//
// Function: PurgeExpiringCertsFromStores
//
// Synopsis: blech!
//
//----------------------------------------------------------------------------
HRESULT PurgeExpiringCertsFromStores ()
{
DWORD cRemove;
DWORD cStores;
HCERTSTORE hStore = NULL;
HKEY hKey = NULL;
char *pszStores[] = { "SPC", "ROOT", "CU_ROOT", NULL };
//
// HACKHACK! no crypt32 UI about the root store.
//
if (RegCreateHKCUKeyExU(HKEY_CURRENT_USER, ROOT_STORE_REGPATH,
0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
{
hKey = NULL;
}
cStores = 0;
while (pszStores[cStores])
{
if (strcmp(pszStores[cStores], "CU_ROOT") == 0)
{
if (hKey)
hStore = CertOpenStore(CERT_STORE_PROV_REG, 0, NULL, 0, (LPVOID)hKey);
else
hStore = NULL;
}
else
{
hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL,
CERT_SYSTEM_STORE_LOCAL_MACHINE |
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
pszStores[cStores]);
}
if (hStore)
{
cRemove = 0;
while (CertRemoveList[cRemove][0] != 0x00)
{
if (hStore)
{
RemoveCert(hStore, &CertRemoveList[cRemove][0]);
}
cRemove++;
}
CertCloseStore(hStore, 0);
}
cStores++;
}
if (hKey)
RegCloseKey(hKey);
return( S_OK );
}
PCCERT_CONTEXT FindCertificateInOtherStore(
IN HCERTSTORE hOtherStore,
IN PCCERT_CONTEXT pCert
)
{
BYTE rgbHash[SHA1_HASH_LENGTH];
CRYPT_DATA_BLOB HashBlob;
HashBlob.pbData = rgbHash;
HashBlob.cbData = SHA1_HASH_LENGTH;
if (!CertGetCertificateContextProperty(
pCert,
CERT_SHA1_HASH_PROP_ID,
rgbHash,
&HashBlob.cbData
) || SHA1_HASH_LENGTH != HashBlob.cbData)
return NULL;
return CertFindCertificateInStore(
hOtherStore,
0, // dwCertEncodingType
0, // dwFindFlags
CERT_FIND_SHA1_HASH,
(const void *) &HashBlob,
NULL //pPrevCertContext
);
}
BOOL IsCertificateInOtherStore(
IN HCERTSTORE hOtherStore,
IN PCCERT_CONTEXT pCert
)
{
PCCERT_CONTEXT pOtherCert;
if (pOtherCert = FindCertificateInOtherStore(hOtherStore, pCert)) {
CertFreeCertificateContext(pOtherCert);
return TRUE;
} else
return FALSE;
}
void DeleteCertificateFromOtherStore(
IN HCERTSTORE hOtherStore,
IN PCCERT_CONTEXT pCert
)
{
PCCERT_CONTEXT pOtherCert;
if (pOtherCert = FindCertificateInOtherStore(hOtherStore, pCert))
CertDeleteCertificateFromStore(pOtherCert);
}
//+-------------------------------------------------------------------------
// Read a SignedData message consisting of certificates and
// CRLs from memory and copy to the specified cert store.
//
// Except for the SPC being loaded from memory, identical to SpcReadSpcFile.
//
// For hLMStore != NULL: if the certificate or CRL already exists in the
// LocalMachine store don't add it. Also if it exists in hCertstore,
// delete it.
//--------------------------------------------------------------------------
HRESULT
SpcReadSpcFromMemory(
IN BYTE *pbData,
IN DWORD cbData,
IN HCERTSTORE hCertStore,
IN DWORD dwMsgAndCertEncodingType,
IN DWORD dwFlags,
IN OPTIONAL HCERTSTORE hLMStore
)
{
HRESULT hr = S_OK;
HCERTSTORE hSpcStore = NULL;
CRYPT_DATA_BLOB sSpcBlob;
HCRYPTPROV hCryptProv = NULL;
PCCERT_CONTEXT pCert = NULL;
PCCRL_CONTEXT pCrl = NULL;
if (!(hCertStore))
{
goto InvalidArg;
}
// Set the blob data.
sSpcBlob.pbData = pbData;
sSpcBlob.cbData = cbData;
// Open up the spc store
hSpcStore = CertOpenStore(CERT_STORE_PROV_SERIALIZED, //CERT_STORE_PROV_PKCS7,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
hCryptProv,
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
&sSpcBlob);
if (!hSpcStore)
{
goto CertStoreError;
}
// Copy in the certificates from the caller.
while (pCert = CertEnumCertificatesInStore(hSpcStore, pCert))
{
if (hLMStore && IsCertificateInOtherStore(hLMStore, pCert))
// Certificate exists in LocalMachine. Delete it from
// CurrentUser if it already exists there.
DeleteCertificateFromOtherStore(hCertStore, pCert);
else
CertAddCertificateContextToStore(hCertStore,
pCert,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL);
}
while (pCrl = CertEnumCRLsInStore(hSpcStore, pCrl))
{
CertAddCRLContextToStore(hCertStore,
pCrl,
CERT_STORE_ADD_NEWER,
NULL);
if (hLMStore) {
// Check if newer or same CRL exists in the hLMStore
PCCRL_CONTEXT pLMCrl;
pLMCrl = CertFindCRLInStore(
hLMStore,
pCrl->dwCertEncodingType,
0, // dwFindFlags
CRL_FIND_EXISTING,
(const void *) pCrl,
NULL // pPrevCrlContext
);
if (NULL != pLMCrl) {
PCCRL_CONTEXT pCUCrl;
pCUCrl = CertFindCRLInStore(
hCertStore,
pCrl->dwCertEncodingType,
0, // dwFindFlags
CRL_FIND_EXISTING,
(const void *) pCrl,
NULL // pPrevCrlContext
);
if (NULL != pCUCrl) {
if (0 <= CompareFileTime(
&pLMCrl->pCrlInfo->ThisUpdate,
&pCUCrl->pCrlInfo->ThisUpdate
))
CertDeleteCRLFromStore(pCUCrl);
else
CertFreeCRLContext(pCUCrl);
}
CertFreeCRLContext(pLMCrl);
}
}
}
CommonReturn:
if (hSpcStore)
{
CertCloseStore(hSpcStore, 0);
}
return(hr);
ErrorReturn:
SetLastError((DWORD)hr);
goto CommonReturn;
SET_HRESULT_EX(DBG_SS, InvalidArg, E_INVALIDARG);
SET_HRESULT_EX(DBG_SS, CertStoreError, GetLastError());
}
// For nonNULL pszLMStoreName, doesn't add certificates if already in
// pszLMStoreName store.
HRESULT AddCertificates2(
IN LPCSTR pszStoreName,
IN OPTIONAL LPCSTR pszLMStoreName,
IN DWORD dwOpenStoreFlags,
IN LPCSTR pszResourceName,
IN LPCSTR pszResourceType
)
{
HRESULT hr = S_OK;
HCERTSTORE hCertStore = NULL;
HCERTSTORE hLMStore = NULL;
LPBYTE pb = NULL;
DWORD cb;
HRSRC hrsrc;
hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY_A,
0, // dwEncodingType
NULL, // hCryptProv
dwOpenStoreFlags |
CERT_SYSTEM_STORE_UNPROTECTED_FLAG,
(const void *) pszStoreName
);
if (!(hCertStore))
{
return(GetLastError());
}
if (NULL != pszLMStoreName)
{
hLMStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY_A,
0, // dwEncodingType
NULL, // hCryptProv
CERT_SYSTEM_STORE_LOCAL_MACHINE |
CERT_STORE_READONLY_FLAG |
CERT_SYSTEM_STORE_UNPROTECTED_FLAG,
(const void *) pszLMStoreName
);
}
hrsrc = FindResourceA(hModule, pszResourceName, pszResourceType);
if ( hrsrc != NULL )
{
HGLOBAL hglobRes;
hglobRes = LoadResource(hModule, hrsrc);
if ( hglobRes != NULL )
{
ULONG cbRes;
BYTE* pbRes;
cbRes = SizeofResource(hModule, hrsrc);
pbRes = (BYTE *)LockResource(hglobRes);
hr = SpcReadSpcFromMemory( pbRes,
cbRes,
hCertStore,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
0,
hLMStore);
UnlockResource(hglobRes);
FreeResource(hglobRes);
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
if ( hCertStore != NULL )
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
if ( hLMStore != NULL )
{
CertCloseStore(hLMStore, CERT_CLOSE_STORE_FORCE_FLAG);
}
return( hr );
}
// For non-LocalMachine store, doesn't add certificates if already in
// corresponding LocalMachine store.
HRESULT AddCertificates(
IN LPCSTR pszStoreName,
IN DWORD dwOpenStoreFlags,
IN LPCSTR pszResourceName,
IN LPCSTR pszResourceType
)
{
LPCSTR pszLMStoreName;
if (CERT_SYSTEM_STORE_LOCAL_MACHINE !=
(dwOpenStoreFlags & CERT_SYSTEM_STORE_LOCATION_MASK))
pszLMStoreName = pszStoreName;
else
pszLMStoreName = NULL;
return AddCertificates2(
pszStoreName,
pszLMStoreName,
dwOpenStoreFlags,
pszResourceName,
pszResourceType
);
}
HRESULT AddCurrentUserCACertificates()
{
return AddCertificates(
"CA",
CERT_SYSTEM_STORE_CURRENT_USER,
MAKEINTRESOURCE(IDR_CAS),
"CAS"
);
}
HRESULT AddLocalMachineCACertificates()
{
return AddCertificates(
"CA",
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_CAS),
"CAS"
);
}
HRESULT AddCurrentUserDisallowedCertificates()
{
return AddCertificates(
"Disallowed",
CERT_SYSTEM_STORE_CURRENT_USER,
MAKEINTRESOURCE(IDR_DISALLOW),
"DISALLOW"
);
}
HRESULT AddLocalMachineDisallowedCertificates()
{
return AddCertificates(
"Disallowed",
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_DISALLOW),
"DISALLOW"
);
}
HRESULT AddCurrentUserRootCertificates()
{
HRESULT hr;
HRESULT hr2;
hr = AddCertificates(
"Root",
CERT_SYSTEM_STORE_CURRENT_USER,
MAKEINTRESOURCE(IDR_ROOTS),
"ROOTS"
);
hr2 = AddCertificates2(
"Root",
"AuthRoot", // check if already in LM AuthRoot store
CERT_SYSTEM_STORE_CURRENT_USER,
MAKEINTRESOURCE(IDR_AUTHROOTS),
"AUTHROOTS"
);
if (hr == ERROR_SUCCESS)
hr = hr2;
return hr;
}
HRESULT AddLocalMachineRootCertificates()
{
HRESULT hr;
HRESULT hr2;
HRESULT hr3;
HRESULT hr4;
hr = AddCertificates(
"AuthRoot",
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_AUTHROOTS),
"AUTHROOTS"
);
// Remove all the AuthRoots from the "Root" store
hr2 = AddCertificates2(
"Root",
"AuthRoot", // check if already in LM AuthRoot store
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_AUTHROOTS),
"AUTHROOTS"
);
hr3 = AddCertificates(
"Root",
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_ROOTS),
"ROOTS"
);
// Remove all the Roots from the "AuthRoot" store
hr4 = AddCertificates2(
"AuthRoot",
"Root", // check if already in LM Root store
CERT_SYSTEM_STORE_LOCAL_MACHINE,
MAKEINTRESOURCE(IDR_ROOTS),
"ROOTS"
);
if (hr == ERROR_SUCCESS)
hr = hr2;
if (hr == ERROR_SUCCESS)
hr = hr3;
if (hr == ERROR_SUCCESS)
hr = hr4;
return hr;
}
void CreateKey(
IN HKEY hKey,
IN LPCWSTR pwszSubKey
)
{
LONG err;
DWORD dwDisposition;
HKEY hSubKey;
if (ERROR_SUCCESS != (err = RegCreateKeyExU(
hKey,
pwszSubKey,
0, // dwReserved
NULL, // lpClass
REG_OPTION_NON_VOLATILE,
MAXIMUM_ALLOWED,
NULL, // lpSecurityAttributes
&hSubKey,
&dwDisposition))) {
#if DBG
DbgPrintf(DBG_SS_CRYPT32,
"RegCreateKeyEx(%S) returned error: %d 0x%x\n",
pwszSubKey, err, err);
#endif
} else {
RegCloseKey(hSubKey);
}
}
// Loop through the certificates in the "My" store and get their
// KeyIdentifier property. If the certificate also has a KEY_PROV_INFO,
// then, this will cause its KeyIdentifier to be created.
void UpdateMyKeyIdentifiers(
IN DWORD dwOpenStoreFlags
)
{
HCERTSTORE hStore;
if (hStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_A,
0, // dwEncodingType
NULL, // hCryptProv
dwOpenStoreFlags | CERT_STORE_ENUM_ARCHIVED_FLAG,
(const void *) "My"
)) {
PCCERT_CONTEXT pCert = NULL;
while (pCert = CertEnumCertificatesInStore(hStore, pCert)) {
DWORD cbData = 0;
// Dummy get to force the KeyIdentifer property to be created
// if it doesn't already exist.
CertGetCertificateContextProperty(
pCert,
CERT_KEY_IDENTIFIER_PROP_ID,
NULL, // pvData
&cbData
);
}
CertCloseStore(hStore, 0);
}
}
//---------------------------------------------------------------------------
// Set Software Publisher State Key Value
//
//---------------------------------------------------------------------------
BOOL SetSoftPubKey(DWORD dwMask, BOOL fOn)
{
DWORD dwState=0;
DWORD dwDisposition=0;
DWORD dwType=0;
DWORD cbData=0;
LPWSTR wszState=REGNAME_WINTRUST_POLICY_FLAGS;
BOOL fResult=FALSE;
HKEY hKey=NULL;
// Set the State in the registry
if (ERROR_SUCCESS != RegCreateKeyExU(
HKEY_CURRENT_USER,
REGPATH_WINTRUST_POLICY_FLAGS,
0, // dwReserved
NULL, // lpszClass
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL, // lpSecurityAttributes
&hKey,
&dwDisposition))
goto RegErr;
dwState = 0;
cbData = sizeof(dwState);
if(ERROR_SUCCESS != RegQueryValueExU
( hKey,
wszState,
NULL, // lpReserved
&dwType,
(BYTE *) &dwState,
&cbData
))
goto RegErr;
if ((dwType != REG_DWORD) && (dwType != REG_BINARY))
goto UnexpectedErr;
switch(dwMask)
{
case WTPF_IGNOREREVOCATIONONTS:
case WTPF_IGNOREREVOKATION:
case WTPF_IGNOREEXPIRATION:
// Revocation and expiration are a double negative so the bit set
// means revocation and expriation checking is off.
fOn = !fOn;
break;
default:
break;
};
if (fOn)
dwState |= dwMask;
else
dwState &= ~dwMask;
if(ERROR_SUCCESS != RegSetValueExU(
hKey,
wszState,
0, // dwReserved
REG_DWORD,
(BYTE *) &dwState,
sizeof(dwState)
))
goto SetValueErr;
fResult=TRUE;
CommonReturn:
if(hKey)
RegCloseKey(hKey);
return fResult;
ErrorReturn:
goto CommonReturn;
TRACE_ERROR(RegErr);
SET_ERROR(UnexpectedErr, E_UNEXPECTED);
TRACE_ERROR(SetValueErr);
}
//+---------------------------------------------------------------------------
//
// Function: GetNextRegToken
//
// Synopsis:
// Find the next token with space as the deliminator
//----------------------------------------------------------------------------
LPWSTR GetNextRegToken(LPWSTR pwsz, LPWSTR pwszPreToken, BOOL *pfEnd)
{
LPWSTR pwszStart=NULL;
LPWSTR pwszSearch=NULL;
if(NULL == pwsz)
return NULL;
if(TRUE == (*pfEnd))
return NULL;
pwszStart=pwsz;
if(pwszPreToken)
pwszStart=pwszPreToken + wcslen(pwszPreToken) + 1;
//skip the spaces
while((*pwszStart)==L' ')
pwszStart++;
//check for NULL
if(*pwszStart==L'\0')
return NULL;
pwszSearch=pwszStart;
while(((*pwszSearch) != L'\0') && ((*pwszSearch) !=L' ') )
pwszSearch++;
if(*pwszSearch == L'\0')
{
*pfEnd=TRUE;
return pwszStart;
}
*pwszSearch=L'\0';
*pfEnd=FALSE;
return pwszStart;
}
//+---------------------------------------------------------------------------
//
// Function: InitRegistryValue
//
// Synopsis: This function replace SetReg.exe. The expected
// command line would be: 1 TRUE 3 FALSE 9 TRUE 4 FALSE ....
//
//----------------------------------------------------------------------------
HRESULT InitRegistryValue(LPWSTR pwszCommand)
{
HRESULT hr= E_FAIL;
DWORD SoftPubFlags[] =
{
WTPF_TRUSTTEST | WTPF_TESTCANBEVALID,
WTPF_IGNOREEXPIRATION,
WTPF_IGNOREREVOKATION,
WTPF_OFFLINEOK_IND,
WTPF_OFFLINEOK_COM,
WTPF_OFFLINEOKNBU_IND,
WTPF_OFFLINEOKNBU_COM,
WTPF_VERIFY_V1_OFF,
WTPF_IGNOREREVOCATIONONTS,
WTPF_ALLOWONLYPERTRUST
};
LPWSTR pwszNextToken=NULL;
int iIndex=-1;
BOOL fOn=FALSE;
int cFlags=sizeof(SoftPubFlags)/sizeof(SoftPubFlags[0]);
DWORD cParam=0;
LPWSTR pwszCopy=NULL;
BOOL fPassThrough=FALSE;
//make a copy of the command line since we will change it
pwszCopy=(LPWSTR)LocalAlloc(LPTR, (1+wcslen(pwszCommand)) * sizeof(WCHAR));
if(NULL== pwszCopy)
goto MemoryErr;
wcscpy(pwszCopy, pwszCommand);
while(pwszNextToken=GetNextRegToken(pwszCopy, pwszNextToken, &fPassThrough))
{
if(-1 == iIndex)
{
iIndex=_wtoi(pwszNextToken);
if((iIndex <= 0) || (iIndex > cFlags))
goto InvalidArgErr;
cParam++;
}
else
{
if(0 == _wcsicmp(pwszNextToken, L"true"))
fOn=TRUE;
else
{
if(0 == _wcsicmp(pwszNextToken, L"false"))
fOn=FALSE;
else
goto InvalidArgErr;
}
cParam++;
//set the registry value
if(!SetSoftPubKey(SoftPubFlags[iIndex-1],
fOn))
{
hr=INITPKI_HRESULT_FROM_WIN32(GetLastError());
goto SetKeyErr;
}
//reset the value for dwIndex
iIndex=-1;
}
}
//we have to have even number of parameters
if( (0 != (cParam %2)) || (0 == cParam))
goto InvalidArgErr;
hr=S_OK;
CommonReturn:
if(pwszCopy)
LocalFree((HLOCAL)pwszCopy);
return hr;
ErrorReturn:
goto CommonReturn;
SET_ERROR(InvalidArgErr, E_INVALIDARG);
SET_ERROR_VAR(SetKeyErr, hr);
SET_ERROR(MemoryErr, E_OUTOFMEMORY);
}
//+---------------------------------------------------------------------------
//
// Function: DllMain
//
// Synopsis:
//
//----------------------------------------------------------------------------
BOOL WINAPI DllMain(HMODULE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch ( fdwReason )
{
case DLL_PROCESS_ATTACH:
hModule = hInstDLL;
break;
}
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: DllInstall
//
// Synopsis: dll installation entry point
//
//----------------------------------------------------------------------------
STDAPI DllInstall (BOOL fRegister, LPCSTR pszCommand)
{
HRESULT hr = S_OK;
HRESULT hr2;
LPWSTR pwszCommand=NULL;
if ( fRegister == FALSE )
{
return( E_NOTIMPL );
}
switch ( *pszCommand )
{
//letter S stands for setreg input parameters
//the command line should look like following:
//S 1 TRUE 2 FALSE 3 FALSE ...
//pszCommand is ACTUALLY LPWSTR for BOTH
//NT5, NT4 and Win95.
case 'S':
case 's':
pwszCommand=(LPWSTR)pszCommand;
if(wcslen(pwszCommand) <= 2)
{
hr=E_INVALIDARG;
}
else
{
hr=InitRegistryValue((LPWSTR)(&(pwszCommand[1])));
}
break;
case 'M':
case 'm':
MoveCertificates( TRUE );
PurgeExpiringCertsFromStores();
break;
case 'U':
case 'u':
_AdjustPolicyFlags(psPolicySettings);
PurgeExpiringCertsFromStores();
// Ensure we have a registry entry for the Group Policy
// SystemCertificates. On NT 4.0 or Win98, we emulate NT 5.0 GPT
// notification by doing a RegNotifyChangeKeyValue on this
// registry key.
CreateKey(HKEY_CURRENT_USER, GROUP_POLICY_STORE_REGPATH);
// Before adding to CurrentUser, will check if the root or CA
// already exists in LocalMachine. If it exists in
// LocalMachine and also exists in CurrentUser, will delete it
// from CurrentUser instead of adding.
hr = AddCurrentUserRootCertificates();
hr2 = AddCurrentUserCACertificates();
if (hr == ERROR_SUCCESS)
hr = hr2;
hr2 = AddCurrentUserDisallowedCertificates();
if (hr == ERROR_SUCCESS)
hr = hr2;
// Protect the CurrentUser roots and purge any existing
// protected CurrentUser roots also in LocalMachine
//
// Note, once the roots are protected, all subsequent adds are
// done by a special service executing with System privileges.
// This special service does secure attention sequence (SAS) UI
// before doing the add.
//
// Note, subsequent purges are exempt from UI. ie, this function
// doesn't do any SAS UI.
I_CertProtectFunction(
CERT_PROT_PURGE_LM_ROOTS_FUNC_ID,
0, // dwFlags
NULL, // pwszIn
NULL, // pbIn
0, // cbIn
NULL, // ppbOut
NULL // pcbOut
);
UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_CURRENT_USER);
break;
case 'B':
case 'b':
case 'R':
case 'r':
case 'A':
case 'a':
// Initialize HKLM registry locations used by PKI to
// only give Everyone KEY_READ access. Also gives the
// IEDirtyFlags registry key KEY_SET_VALUE access for
// Everyone.
InitializeHKLMAcls();
// Ensure we have a registry entry for the IEDirtyFlags
// This key should have already been created
// by InitializeHKLMAcls() for NT. Ensure its also there
// for Win95 and Win98
CreateKey(HKEY_LOCAL_MACHINE, CERT_IE_DIRTY_FLAGS_REGPATH);
MoveCertificates(TRUE);
PurgeExpiringCertsFromStores();
// Ensure we have a registry entry for the Group Policy
// SystemCertificates. On NT 4.0 or Win98, we emulate NT 5.0 GPT
// notification by doing a RegNotifyChangeKeyValue on this
// registry key.
CreateKey(HKEY_LOCAL_MACHINE, GROUP_POLICY_STORE_REGPATH);
CreateKey(HKEY_CURRENT_USER, GROUP_POLICY_STORE_REGPATH);
// Ensure we have existing predefined stores for the LocalMachine
// Enterprise system stores. These stores are periodically updated
// from the DS by a system service. RegNotifyChangeKeyValue is
// used to signal clients about Enterprise store changes.
RegisterEnterpriseStores();
// Our goal is to get the roots and CAs into LocalMachine.
// Note previously, they were only copied to CurrentUser.
AddLocalMachineRootCertificates();
AddLocalMachineCACertificates();
AddLocalMachineDisallowedCertificates();
// If the above adds to LocalMachine failed, then, add
// to CurrentUser.
//
// Before adding to CurrentUser, will check if the root or CA
// already exists in LocalMachine. If it exists in
// LocalMachine and also exists in CurrentUser, will delete it
// from CurrentUser instead of adding.
hr = AddCurrentUserRootCertificates();
hr2 = AddCurrentUserCACertificates();
if (hr == ERROR_SUCCESS)
hr = hr2;
hr2 = AddCurrentUserDisallowedCertificates();
if (hr == ERROR_SUCCESS)
hr = hr2;
// Protect the CurrentUser roots and purge any existing
// protected CurrentUser roots also in LocalMachine
//
// Note, once the roots are protected, all subsequent adds are
// done by a special service executing with System privileges.
// This special service does secure attention sequence (SAS) UI
// before doing the add.
//
// Note, subsequent purges are exempt from UI. ie, this function
// doesn't do any SAS UI.
I_CertProtectFunction(
CERT_PROT_PURGE_LM_ROOTS_FUNC_ID,
0, // dwFlags
NULL, // pwszIn
NULL, // pbIn
0, // cbIn
NULL, // ppbOut
NULL // pcbOut
);
UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_CURRENT_USER);
UpdateMyKeyIdentifiers(CERT_SYSTEM_STORE_LOCAL_MACHINE);
CleanupRegistry();
hr2 = RegisterCryptoDlls(TRUE);
if (hr == ERROR_SUCCESS)
hr = hr2;
if (!I_CryptCatAdminMigrateToNewCatDB())
{
hr2 = HRESULT_FROM_WIN32(GetLastError());
}
else
{
hr2 = ERROR_SUCCESS;
}
if (hr == ERROR_SUCCESS)
hr = hr2;
break;
case 'C':
case 'c':
// Win9x migration post setup cleanup. Remove any migrated
// roots that exist in the AuthRoot store.
AddLocalMachineRootCertificates();
AddCurrentUserRootCertificates();
break;
case 'Z':
case 'z':
//
// This is for componentization install
//
pwszCommand=(LPWSTR)pszCommand;
if (_wcsicmp(pwszCommand, L"z CoreCertificateServices") == 0)
{
InitializeHKLMAcls();
AddLocalMachineRootCertificates();
AddLocalMachineCACertificates();
AddLocalMachineDisallowedCertificates();
if (!_LoadAndRegister("wintrust.dll", FALSE) ||
!_LoadAndRegister("mssign32.dll", FALSE) ||
!_LoadAndRegister("xenroll.dll", FALSE) ||
!_AdjustPolicyFlags(psPolicySettings))
{
hr = S_FALSE;
}
RegisterWinlogonExtension("crypt32chain", "crypt32.dll",
"ChainWlxLogoffEvent");
RegisterWinlogonExtension("cryptnet", "cryptnet.dll",
"CryptnetWlxLogoffEvent");
RegisterCrypt32EventSource();
}
else if (_wcsicmp(pwszCommand, L"z CertificateUIServices") == 0)
{
if (!_LoadAndRegister("cryptui.dll", FALSE))
{
hr = S_FALSE;
}
}
else if (_wcsicmp(pwszCommand, L"z CryptographicNetworkServices") == 0)
{
if (!_LoadAndRegister("cryptnet.dll", FALSE))
{
hr = S_FALSE;
}
}
else if (_wcsicmp(pwszCommand, L"z CertificateUIExtensions") == 0)
{
if (!_LoadAndRegister("cryptext.dll", FALSE))
{
hr = S_FALSE;
}
}
else
{
hr = E_INVALIDARG;
}
break;
default:
hr = E_INVALIDARG;
}
return( hr );
}
STDAPI DllRegisterServer(void)
{
return(DllInstall(TRUE, "A"));
}
STDAPI DllUnregisterServer(void)
{
return(UnregisterCryptoDlls());
}
BOOL WINAPI InitializePKI(void)
{
if (RegisterCryptoDlls(TRUE) != S_OK)
{
return(FALSE);
}
return(TRUE);
}