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.
 
 
 
 
 
 

331 lines
9.3 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1996
//
// File: updroots.cpp
//
// Contents: Updates LocalMachine roots. Pre-whistler, HKLM "Root" store.
// Otherwise, HKLM "AuthRoot" store.
//
// See Usage() for list of options.
//
//
// Functions: main
//
// History: 30-Aug-00 philh created
//
//--------------------------------------------------------------------------
#include <windows.h>
#include "wincrypt.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <time.h>
#define SHA1_HASH_LEN 20
//+-------------------------------------------------------------------------
// crypt32.dll Whistler version numbers
//
// Doesn't need to be the official Whistler release #. Any build # after
// the "AuthRoot" store was added.
//--------------------------------------------------------------------------
#define WHISTLER_CRYPT32_DLL_VER_MS (( 5 << 16) | 131 )
#define WHISTLER_CRYPT32_DLL_VER_LS (( 2257 << 16) | 1 )
BOOL fLocalMachine = FALSE;
void PrintLastError(LPCSTR pszMsg)
{
DWORD dwErr = GetLastError();
char buf[512];
sprintf(buf, "%s failed => 0x%x (%d) \n", pszMsg, dwErr, dwErr);
MessageBoxA(
NULL, // hWnd
buf,
"UpdRoots",
MB_OK | MB_ICONERROR | MB_TASKMODAL
);
}
void PrintMsg(LPCSTR pszMsg)
{
MessageBoxA(
NULL, // hWnd
pszMsg,
"UpdRoots",
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL
);
}
static void Usage(void)
{
MessageBoxA(
NULL, // hWnd
"Usage: UpdRoots [options] <SrcStoreFilename>\n"
"Options are:\n"
"-h -\tThis message\n"
"-d -\tDelete (default is to add)\n"
"-l -\tLocal Machine (default is Third Party)\n"
"\n",
"UpdRoots",
MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL
);
}
PCCERT_CONTEXT FindCertificateInOtherStore(
IN HCERTSTORE hOtherStore,
IN PCCERT_CONTEXT pCert
)
{
BYTE rgbHash[SHA1_HASH_LEN];
CRYPT_DATA_BLOB HashBlob;
HashBlob.pbData = rgbHash;
HashBlob.cbData = SHA1_HASH_LEN;
if (!CertGetCertificateContextProperty(
pCert,
CERT_SHA1_HASH_PROP_ID,
rgbHash,
&HashBlob.cbData
) || SHA1_HASH_LEN != HashBlob.cbData)
return NULL;
return CertFindCertificateInStore(
hOtherStore,
0, // dwCertEncodingType
0, // dwFindFlags
CERT_FIND_SHA1_HASH,
(const void *) &HashBlob,
NULL //pPrevCertContext
);
}
BOOL DeleteCertificateFromOtherStore(
IN HCERTSTORE hOtherStore,
IN PCCERT_CONTEXT pCert
)
{
BOOL fResult;
PCCERT_CONTEXT pOtherCert;
if (pOtherCert = FindCertificateInOtherStore(hOtherStore, pCert))
fResult = CertDeleteCertificateFromStore(pOtherCert);
else
fResult = TRUE;
return fResult;
}
typedef BOOL (WINAPI *PFN_CRYPT_GET_FILE_VERSION)(
IN LPCWSTR pwszFilename,
OUT DWORD *pdwFileVersionMS, /* e.g. 0x00030075 = "3.75" */
OUT DWORD *pdwFileVersionLS /* e.g. 0x00000031 = "0.31" */
);
#define NO_LOGICAL_STORE_VERSION 0
#define LOGICAL_STORE_VERSION 1
#define AUTH_STORE_VERSION 2
// Note, I_CryptGetFileVersion and logical stores, not supported in all
// versions of crypt32.dll
//
// Returns one of the above defined version constants
DWORD GetCrypt32Version()
{
DWORD dwVersion;
DWORD dwFileVersionMS;
DWORD dwFileVersionLS;
HMODULE hModule;
PFN_CRYPT_GET_FILE_VERSION pfnCryptGetFileVersion;
hModule = GetModuleHandleA("crypt32.dll");
if (NULL == hModule)
return NO_LOGICAL_STORE_VERSION;
if (NULL == GetProcAddress(hModule, "CertEnumPhysicalStore"))
return NO_LOGICAL_STORE_VERSION;
if (fLocalMachine)
return LOGICAL_STORE_VERSION;
pfnCryptGetFileVersion = (PFN_CRYPT_GET_FILE_VERSION) GetProcAddress(
hModule, "I_CryptGetFileVersion");
if (NULL == pfnCryptGetFileVersion)
return LOGICAL_STORE_VERSION;
dwVersion = LOGICAL_STORE_VERSION;
if (pfnCryptGetFileVersion(
L"crypt32.dll",
&dwFileVersionMS,
&dwFileVersionLS)) {
if (WHISTLER_CRYPT32_DLL_VER_MS < dwFileVersionMS)
dwVersion = AUTH_STORE_VERSION;
else if (WHISTLER_CRYPT32_DLL_VER_MS == dwFileVersionMS &&
WHISTLER_CRYPT32_DLL_VER_LS <= dwFileVersionLS)
dwVersion = AUTH_STORE_VERSION;
}
return dwVersion;
}
int _cdecl main(int argc, char * argv[])
{
BOOL fResult;
int ReturnStatus = 0;
LPSTR pszSrcStoreFilename = NULL; // not allocated
HANDLE hSrcStore = NULL;
HANDLE hRootStore = NULL;
BOOL fDelete = FALSE;
DWORD dwVersion;
PCCERT_CONTEXT pSrcCert;
while (--argc>0)
{
if (**++argv == '-')
{
switch(argv[0][1])
{
case 'd':
fDelete = TRUE;
break;
case 'l':
fLocalMachine = TRUE;
break;
case 'h':
default:
goto BadUsage;
}
} else {
if (pszSrcStoreFilename == NULL)
pszSrcStoreFilename = argv[0];
else {
PrintMsg("too many store filenames\n");
goto BadUsage;
}
}
}
if (NULL == pszSrcStoreFilename) {
PrintMsg("missing store filename\n");
goto BadUsage;
}
// Attempt to open the source store
hSrcStore = CertOpenStore(
CERT_STORE_PROV_FILENAME_A,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0, // hCryptProv
CERT_STORE_READONLY_FLAG,
(const void *) pszSrcStoreFilename
);
if (NULL == hSrcStore) {
PrintLastError("Open SrcStore");
goto ErrorReturn;
}
// Attempt to open the destination root store. For Whistler and beyond its
// the HKLM "AuthRoot" store. Pre-Whistler its the HKLM "Root" store.
// Also, earlier versions of crypt32 didn't support logical stores.
// For -l option, force it to be the HKLM "Root" store.
dwVersion = GetCrypt32Version();
if (NO_LOGICAL_STORE_VERSION == dwVersion) {
// Need to open the registry to bypass the add root message boxes
HKEY hKey = NULL;
LONG lErr;
if (ERROR_SUCCESS != (lErr = RegOpenKeyExA(
HKEY_CURRENT_USER,
"Software\\Microsoft\\SystemCertificates\\Root",
0, // dwReserved
KEY_ALL_ACCESS,
&hKey))) {
SetLastError(lErr);
PrintLastError("RegOpenKeyExA(root)\n");
goto ErrorReturn;
}
hRootStore = CertOpenStore(
CERT_STORE_PROV_REG,
0, // dwEncodingType
0, // hCryptProv
0, // dwFlags
(const void *) hKey
);
RegCloseKey(hKey);
} else {
LPCSTR pszRootStoreName;
if (AUTH_STORE_VERSION == dwVersion)
pszRootStoreName = "AuthRoot";
else
pszRootStoreName = "Root";
hRootStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY_A,
0, // dwEncodingType
0, // hCryptProv
CERT_SYSTEM_STORE_LOCAL_MACHINE,
(const void *) pszRootStoreName
);
}
if (NULL == hRootStore) {
PrintLastError("Open RootStore");
goto ErrorReturn;
}
// Iterate through all the certificates in the source store. Add or delete
// from the root store.
fResult = TRUE;
pSrcCert = NULL;
while (pSrcCert = CertEnumCertificatesInStore(hSrcStore, pSrcCert)) {
if (fDelete) {
if (!DeleteCertificateFromOtherStore(hRootStore, pSrcCert)) {
fResult = FALSE;
PrintLastError("DeleteCert");
}
} else {
// Note, earlier versions of crypt32.dll didn't support
// CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES
if (!CertAddCertificateContextToStore(
hRootStore,
pSrcCert,
CERT_STORE_ADD_REPLACE_EXISTING,
NULL)) {
fResult = FALSE;
PrintLastError("AddCert");
}
}
}
if (!fResult)
goto ErrorReturn;
ReturnStatus = 0;
CommonReturn:
if (hSrcStore)
CertCloseStore(hSrcStore, 0);
if (hRootStore)
CertCloseStore(hRootStore, 0);
return ReturnStatus;
BadUsage:
Usage();
ErrorReturn:
ReturnStatus = -1;
goto CommonReturn;
}