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.
 
 
 
 
 
 

508 lines
14 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: makectl.cpp
//
// Contents: Make a CTL
//
// See Usage() for list of options.
//
//
// Functions: wmain
//
// History: 17-June-97 xiaohs created
//
//--------------------------------------------------------------------------
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <unicode.h>
#include <wchar.h>
#include "wincrypt.h"
#include "mssip.h"
#include "softpub.h"
#include "resource.h"
#include "toolutl.h"
#include "cryptui.h" //the UI version of the tool
//--------------------------------------------------------------------------
//
// Global Data
//
//----------------------------------------------------------------------------
HMODULE hModule=NULL;
BYTE **g_rgpHash=NULL;
DWORD *g_rgcbHash=NULL;
DWORD g_dwCount=0;
DWORD g_dwMsgAndCertEncodingType=CRYPT_ASN_ENCODING | PKCS_7_ASN_ENCODING;
DWORD g_dwCertEncodingType=CRYPT_ASN_ENCODING;
//---------------------------------------------------------------------------
// Get the hModule hanlder and init two DLLMain.
//
//---------------------------------------------------------------------------
BOOL InitModule()
{
if(!(hModule=GetModuleHandle(NULL)))
return FALSE;
return TRUE;
}
static void Usage(void)
{
IDSwprintf(hModule, IDS_SYNTAX);
IDSwprintf(hModule, IDS_SYNTAX1);
IDSwprintf(hModule, IDS_OPTIONS);
IDSwprintf(hModule, IDS_OPTION_U_DESC);
IDSwprintf(hModule, IDS_OPTION_U_DESC1);
IDSwprintf(hModule, IDS_OPTION_U_DESC2);
IDSwprintf(hModule,IDS_OPTION_S_DESC);
IDSwprintf(hModule,IDS_OPTION_R_DESC);
IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE,IDS_R_CU,IDS_R_LM,IDS_R_CU);
}
//----------------------------------------------------------------------------
//
//Build the CTL_INFO struct and encode/sign it with no signer info
//----------------------------------------------------------------------------
HRESULT BuildAndEncodeCTL(DWORD dwMsgEncodingType, LPSTR szOid, DWORD dwCount, BYTE **rgpHash,
DWORD *rgcbHash, BYTE **ppbEncodedCTL, DWORD *pcbEncodedCTL)
{
HRESULT hr=E_FAIL;
CMSG_SIGNED_ENCODE_INFO sSignInfo;
CTL_INFO CTLInfo;
DWORD dwIndex=0;
if(dwCount==0 || !rgpHash || !ppbEncodedCTL || !pcbEncodedCTL)
return E_INVALIDARG;
//init
*ppbEncodedCTL=NULL;
*pcbEncodedCTL=0;
memset(&sSignInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
sSignInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
memset(&CTLInfo, 0, sizeof(CTL_INFO));
//set up CTL
CTLInfo.dwVersion=CTL_V1;
CTLInfo.SubjectUsage.cUsageIdentifier = 1;
CTLInfo.SubjectUsage.rgpszUsageIdentifier = (LPSTR *)&szOid;
GetSystemTimeAsFileTime(&(CTLInfo.ThisUpdate));
CTLInfo.SubjectAlgorithm.pszObjId=szOID_OIWSEC_sha1;
CTLInfo.cCTLEntry=dwCount;
CTLInfo.rgCTLEntry=(CTL_ENTRY *)ToolUtlAlloc(sizeof(CTL_ENTRY)*dwCount);
if(!(CTLInfo.rgCTLEntry))
{
hr=E_OUTOFMEMORY;
goto CLEANUP;
}
//memset
memset(CTLInfo.rgCTLEntry, 0, sizeof(CTL_ENTRY)*dwCount);
for(dwIndex=0; dwIndex<dwCount; dwIndex++)
{
CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.cbData=rgcbHash[dwIndex];
CTLInfo.rgCTLEntry[dwIndex].SubjectIdentifier.pbData=rgpHash[dwIndex];
}
//encode and sign the CTL
if(!CryptMsgEncodeAndSignCTL(dwMsgEncodingType,
&CTLInfo,
&sSignInfo,
0,
NULL,
pcbEncodedCTL))
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
//memory allocation
*ppbEncodedCTL=(BYTE *)ToolUtlAlloc(*pcbEncodedCTL);
if(!(*ppbEncodedCTL))
{
hr=E_OUTOFMEMORY;
goto CLEANUP;
}
if(!CryptMsgEncodeAndSignCTL(dwMsgEncodingType,
&CTLInfo,
&sSignInfo,
0,
*ppbEncodedCTL,
pcbEncodedCTL))
{
hr=HRESULT_FROM_WIN32(GetLastError());
goto CLEANUP;
}
hr=S_OK;
CLEANUP:
if(hr!=S_OK)
{
if(*ppbEncodedCTL)
{
ToolUtlFree(*ppbEncodedCTL);
*ppbEncodedCTL=NULL;
}
*pcbEncodedCTL=0;
}
if(CTLInfo.rgCTLEntry)
ToolUtlFree(CTLInfo.rgCTLEntry);
return hr;
}
//----------------------------------------------------------------------------
//
//Get the hash of the certificates from the store
//----------------------------------------------------------------------------
HRESULT GetCertFromStore(LPWSTR wszStoreName, BOOL fSystemStore, DWORD dwStoreFlag)
{
HCERTSTORE hStore=NULL;
HRESULT hr=E_FAIL;
PCCERT_CONTEXT pCertContext=NULL;
PCCERT_CONTEXT pCertPre=NULL;
BYTE *pbData=NULL;
DWORD cbData=0;
void *p = NULL;
//open the store
if(fSystemStore)
{
hStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
g_dwMsgAndCertEncodingType,
NULL,
dwStoreFlag | CERT_STORE_READONLY_FLAG,
wszStoreName);
}
else
{
//Serialized Store, PKCS#7, Encoded Cert
hStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
g_dwMsgAndCertEncodingType,
NULL,
0,
wszStoreName);
}
if(!hStore)
{
hr=GetLastError();
IDSwprintf(hModule, IDS_ERR_OPEN_STORE);
goto CLEANUP;
}
//now, we need to enum all the certs in the store
while(pCertContext=CertEnumCertificatesInStore(hStore, pCertPre))
{
//get the SHA1 hash of the certificate
if(!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID,NULL,&cbData))
{
hr=GetLastError();
IDSwprintf(hModule, IDS_ERR_HASH);
goto CLEANUP;
}
pbData=(BYTE *)ToolUtlAlloc(cbData);
if(!pbData)
{
hr=E_OUTOFMEMORY;
IDSwprintf(hModule, IDS_ERR_MEMORY);
goto CLEANUP;
}
//get the SHA1 hash of the certificate
if(!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID,pbData,&cbData))
{
hr=GetLastError();
IDSwprintf(hModule, IDS_ERR_HASH);
ToolUtlFree(pbData);
goto CLEANUP;
}
//add to our global list
g_dwCount++;
//re-alloc memory
p = (void *)g_rgpHash;
#pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
g_rgpHash=(BYTE **)realloc(g_rgpHash, sizeof(BYTE *)*g_dwCount);
if(!g_rgpHash)
{
g_rgpHash = (BYTE **)p;
hr=E_OUTOFMEMORY;
IDSwprintf(hModule, IDS_ERR_HASH);
ToolUtlFree(pbData);
goto CLEANUP;
}
p = (void *)g_rgcbHash;
#pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
g_rgcbHash=(DWORD *)realloc(g_rgcbHash, sizeof(DWORD)*g_dwCount);
if(!g_rgcbHash)
{
g_rgcbHash = (DWORD *)p;
hr=E_OUTOFMEMORY;
IDSwprintf(hModule, IDS_ERR_HASH);
ToolUtlFree(pbData);
goto CLEANUP;
}
g_rgpHash[g_dwCount-1]=pbData;
g_rgcbHash[g_dwCount-1]=cbData;
pCertPre=pCertContext;
}
hr=S_OK;
CLEANUP:
if(pCertContext)
CertFreeCertificateContext(pCertContext);
if(hStore)
CertCloseStore(hStore, 0);
return hr;
}
extern "C" int __cdecl wmain(int argc, WCHAR *wargv[])
{
int ReturnStatus=-1;
HRESULT hr=E_FAIL;
LPWSTR pwszOutputFilename=NULL;
DWORD dwIndex=0;
LPSTR szOid=szOID_PKIX_KP_CODE_SIGNING;
BOOL fAllocated=FALSE;
LPWSTR pwszOption=NULL;
BYTE *pbEncodedCTL=NULL;
DWORD cbEncodedCTL=0;
WCHAR wszSwitch1[10];
WCHAR wszSwitch2[10];
BOOL fSystemstore=FALSE;
LPWSTR wszStoreLocation=NULL;
DWORD dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
//we call the UI version of the makectl if no parameters are passed into
//the command line
if(1==argc)
{
//build the CTL file without signing process
//call the wizard which provides feedback
if(CryptUIWizBuildCTL(CRYPTUI_WIZ_BUILDCTL_SKIP_SIGNING,
NULL,
NULL,
NULL,
NULL,
NULL))
return 0;
else
return -1;
}
if(argc<3)
{
Usage();
return ReturnStatus;
}
if(!InitModule())
goto ErrorReturn;
//process the stores one at a time
for (dwIndex=1; dwIndex<(DWORD)(argc-1); dwIndex++)
{
//see if this is the options
if(IDSwcsnicmp(hModule, wargv[dwIndex], IDS_SWITCH1, 1)==0 ||
IDSwcsnicmp(hModule, wargv[dwIndex], IDS_SWITCH2, 1)==0)
{
pwszOption=wargv[dwIndex];
//get the OIDs
if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_U)==0)
{
dwIndex++;
if(dwIndex >= (DWORD)((argc-1)))
{
IDSwprintf(hModule,IDS_TOO_FEW_PARAM);
goto ErrorReturn;
}
if(!fAllocated)
{
if(S_OK != WSZtoSZ(wargv[dwIndex], &szOid))
goto ErrorReturn;
fAllocated=TRUE;
}
else
{
IDSwprintf(hModule,IDS_TOO_MANY_PARAM);
goto ErrorReturn;
}
}
//check for -s options
else if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_S)==0)
{
fSystemstore=TRUE;
}
//check for -r options
else if(IDSwcsicmp(hModule, &(pwszOption[1]),IDS_OPTION_R)==0)
{
dwIndex++;
if(dwIndex >= (DWORD)((argc-1)))
{
IDSwprintf(hModule,IDS_TOO_FEW_PARAM);
goto ErrorReturn;
}
if(NULL==wszStoreLocation)
{
wszStoreLocation=wargv[dwIndex];
if(IDSwcsicmp(hModule, wszStoreLocation, IDS_R_CU)==0)
dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
else
{
if(IDSwcsicmp(hModule,wszStoreLocation, IDS_R_LM)==0)
dwStoreFlag=CERT_SYSTEM_STORE_LOCAL_MACHINE;
else
{
IDSwprintf(hModule, IDS_INVALID_R);
goto ErrorReturn;
}
}
}
else
{
IDSwprintf(hModule,IDS_TOO_MANY_PARAM);
goto ErrorReturn;
}
}
else
{
//print out the Usage
Usage();
return ReturnStatus;
}
}
else
{
//build the cert hash from the store
if(S_OK !=(hr=GetCertFromStore(wargv[dwIndex], fSystemstore, dwStoreFlag)))
goto ErrorReturn;
//int for the next cycle
fSystemstore=FALSE;
wszStoreLocation=NULL;
dwStoreFlag=CERT_SYSTEM_STORE_CURRENT_USER;
hr=E_FAIL;
}
}
if(0==g_dwCount)
{
IDSwprintf(hModule, IDS_TOO_FEW_PARAM);
hr=E_FAIL;
goto ErrorReturn;
}
//set up the CTL_INFO structure
if(S_OK!=(hr=BuildAndEncodeCTL(g_dwMsgAndCertEncodingType, szOid, g_dwCount, g_rgpHash, g_rgcbHash, &pbEncodedCTL,
&cbEncodedCTL)))
{
IDSwprintf(hModule, IDS_ERR_ENCODE_CTL);
goto ErrorReturn;
}
//get the output file name
pwszOutputFilename = wargv[argc-1];
if(S_OK!=(hr=OpenAndWriteToFile(pwszOutputFilename, pbEncodedCTL, cbEncodedCTL)))
{
IDSwprintf(hModule, IDS_ERR_SAVE_CTL);
goto ErrorReturn;
}
//mark succeed
ReturnStatus = 0;
hr=S_OK;
IDSwprintf(hModule, IDS_SUCCEEDED);
goto CommonReturn;
ErrorReturn:
ReturnStatus = -1;
//print out an error msg
IDSwprintf(hModule, IDS_FAILED,hr,hr);
CommonReturn:
if(g_rgpHash)
{
for(dwIndex=0; dwIndex<g_dwCount; dwIndex++)
ToolUtlFree(g_rgpHash[dwIndex]);
ToolUtlFree(g_rgpHash);
}
if(fAllocated)
ToolUtlFree(szOid);
if(g_rgcbHash)
ToolUtlFree(g_rgcbHash);
if(pbEncodedCTL)
ToolUtlFree(pbEncodedCTL);
return ReturnStatus;
}