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.
2069 lines
55 KiB
2069 lines
55 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1999
|
|
//
|
|
// File: signcode.cpp
|
|
//
|
|
// Contents: The signcode console tool
|
|
//
|
|
// History: July-1st-1997 Xiaohs Created
|
|
//----------------------------------------------------------------------------
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <assert.h>
|
|
#include <wincrypt.h>
|
|
|
|
#include <signer.h>
|
|
#include "mssip.h"
|
|
#include "resource.h"
|
|
#include "unicode.h"
|
|
#include "signhlp.h"
|
|
#include "pvkhlpr.h"
|
|
#include "toolutl.h"
|
|
#include "javaAttr.h"
|
|
#include "cryptui.h"
|
|
|
|
|
|
#define ACTION_SIGN 0x01
|
|
#define ACTION_STAMP 0x02
|
|
#define ACTION_REQUEST 0x04
|
|
#define ACTION_RESPONSE 0x08
|
|
|
|
#define STORE_DEFAULT_NAME_MAX 40
|
|
#define SHA1_LENGTH 20
|
|
|
|
|
|
// Global data for parsing the input parameters
|
|
DWORD dwAction = 0;
|
|
DWORD dwExpectedError = 0;
|
|
|
|
BOOL fSigning = TRUE;
|
|
BOOL fTesting = FALSE;
|
|
BOOL fStoreTechnology=TRUE;
|
|
|
|
BOOL fUndocumented = FALSE;
|
|
|
|
LPWSTR pwszFile = NULL;
|
|
LPWSTR pwszCapiProvider=NULL;
|
|
LPWSTR pwszProviderType=NULL;
|
|
LPWSTR pwszPvkFile = NULL;
|
|
LPWSTR pwszKeyContainer= NULL;
|
|
LPWSTR pwszOpusName = NULL;
|
|
LPWSTR pwszOpusInfo = NULL;
|
|
LPWSTR pwszAlgorithm = NULL;
|
|
LPWSTR pwszAuthority = NULL;
|
|
LPWSTR pwszSpcFile = NULL;
|
|
LPWSTR pwszCertFile =NULL;
|
|
LPWSTR pwszCommonName =NULL;
|
|
LPWSTR pwszStoreName= NULL;
|
|
LPWSTR pwszStoreLocation=NULL;
|
|
LPWSTR pwszStorePolicy= NULL;
|
|
LPWSTR pwszHttpTime = NULL;
|
|
LPWSTR pwszRequestFile =NULL;
|
|
LPWSTR pwszResponseFile =NULL;
|
|
LPWSTR pwszWait=NULL;
|
|
LPWSTR pwszRepeat=NULL;
|
|
LPWSTR pwszKeySpec=NULL;
|
|
LPWSTR pwszSignerIndex=NULL;
|
|
LPWSTR pwszSha1Hash = NULL;
|
|
|
|
BYTE *g_pbHash=NULL;
|
|
DWORD g_cbHash=0;
|
|
|
|
|
|
|
|
DWORD dwCertEncodingType=X509_ASN_ENCODING;
|
|
DWORD dwStoreEncodingType=X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
|
|
DWORD dwWait=0;
|
|
DWORD dwRepeat=1;
|
|
DWORD dwProviderType = PROV_RSA_FULL;
|
|
BOOL fCommercial = FALSE;
|
|
BOOL fIndividual = FALSE;
|
|
DWORD dwKeySpec=0;
|
|
DWORD dwSignerIndex=0;
|
|
|
|
|
|
|
|
LPWSTR *prgwszDllName=NULL;
|
|
LPWSTR *prgwszDllParam=NULL;
|
|
DWORD dwDllIndex=0;
|
|
DWORD dwParamIndex=0;
|
|
|
|
|
|
//default:
|
|
//Assume the store is on CERT_SYSTEM_STORE_CURRENT_USER
|
|
DWORD dwStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
|
|
DWORD dwStorePolicy=SIGNER_CERT_POLICY_SPC;
|
|
WCHAR wszMyStore[STORE_DEFAULT_NAME_MAX];
|
|
//Use MD5 as the default hashing algorithm
|
|
ALG_ID dwAlgorithmOid = CALG_MD5;
|
|
|
|
//Global Data for loading the string
|
|
#define OPTION_SWITCH_SIZE 5
|
|
#define WSTR_LENGTH_MAX 30
|
|
|
|
WCHAR wszCaption[WSTR_LENGTH_MAX];
|
|
WCHAR wszNULL[WSTR_LENGTH_MAX];
|
|
WCHAR wszPlus[WSTR_LENGTH_MAX];
|
|
|
|
|
|
HMODULE hModule=NULL;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// function prototypes
|
|
HRESULT InitDllParameter(PCRYPT_ATTRIBUTES pAuthAttr,
|
|
PCRYPT_ATTRIBUTES pUnauthAttr,
|
|
PCRYPT_ATTRIBUTES *ppAuthAttr,
|
|
PCRYPT_ATTRIBUTES *ppUnauthAttr);
|
|
|
|
void ReleaseDllParameter(PCRYPT_ATTRIBUTES * ppAuthAttr,
|
|
PCRYPT_ATTRIBUTES * ppUnauthAttr);
|
|
|
|
HRESULT SetUpSubjectInfo(SIGNER_SUBJECT_INFO *pSubjectInfo,
|
|
SIGNER_FILE_INFO *pFileInfo);
|
|
|
|
HRESULT SetUpParameter(SIGNER_SUBJECT_INFO *pSubjectInfo,
|
|
SIGNER_FILE_INFO *pFileInfo,
|
|
SIGNER_SIGNATURE_INFO *pSignatureInfo,
|
|
SIGNER_ATTR_AUTHCODE *pAttrAuthcode,
|
|
SIGNER_PROVIDER_INFO *pProviderInfo,
|
|
SIGNER_CERT_STORE_INFO *pCertStoreInfo,
|
|
SIGNER_CERT *pSignerCert,
|
|
CRYPT_ATTRIBUTES *pAuthenticated,
|
|
CRYPT_ATTRIBUTES *pUnauthenticated,
|
|
HCERTSTORE *phCertStore);
|
|
|
|
|
|
PCCERT_CONTEXT GetSigningCert(HCERTSTORE *phCertStore, BOOL *pfMore);
|
|
|
|
|
|
HRESULT GetCertHashFromFile(LPWSTR pwszCertFile,
|
|
BYTE **pHash,
|
|
DWORD *pcbHash,
|
|
BOOL *pfMore);
|
|
//--------------------------------------------------------------------------
|
|
// Get the hModule hanlder and init two DLLMain.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
BOOL InitModule()
|
|
{
|
|
if(!(hModule=GetModuleHandle(NULL)))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
//
|
|
// Help command
|
|
//--------------------------------------------------------------------------------
|
|
void Usage()
|
|
{
|
|
IDSwprintf(hModule,IDS_SYNTAX);
|
|
IDSwprintf(hModule,IDS_OPTIONS);
|
|
IDSwprintf(hModule,IDS_OPTION_SPC_DESC);
|
|
|
|
IDSwprintf(hModule,IDS_OPTION_V_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_K_DESC);
|
|
|
|
IDSwprintf(hModule,IDS_OPTION_N_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_I_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_P_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_Y_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_KY_DESC);
|
|
IDS_IDS_IDSwprintf(hModule, IDS_OPTION_KY_VALUES, IDS_OPTION_KY_SIG,
|
|
IDS_OPTION_KY_EXC);
|
|
IDSwprintf(hModule,IDS_OPTION_AUTH_DESC);
|
|
IDS_IDS_IDSwprintf(hModule,IDS_OPTION_AUTH_VALUE, IDS_AUTHORITY_ID,
|
|
IDS_AUTHORITY_CM);
|
|
IDS_IDSwprintf(hModule,IDS_OPTION_AUTH_VALUE1, IDS_AUTHORITY_DEFAULT);
|
|
IDSwprintf(hModule,IDS_OPTION_A_DESC);
|
|
IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_A_MD5,
|
|
IDS_A_SHA, IDS_A_MD5);
|
|
|
|
IDSwprintf(hModule,IDS_OPTION_T_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_TR_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_TW_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_J_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_JP_DESC);
|
|
|
|
IDSwprintf(hModule,IDS_OPTION_C_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_S_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_R_DESC);
|
|
IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_R_LM, IDS_R_CU,IDS_R_CU);
|
|
IDSwprintf(hModule,IDS_OPTION_SP_DESC);
|
|
IDSwprintf(hModule,IDS_OPTION_SP_DESC1);
|
|
IDS_IDS_IDS_IDSwprintf(hModule,IDS_OPTION_MORE_VALUE, IDS_OPTION_SP_CHAIN,
|
|
IDS_OPTION_SP_SPCSTORE, IDS_OPTION_SP_SPCSTORE);
|
|
IDSwprintf(hModule, IDS_OPTION_CN_DESC);
|
|
IDSwprintf(hModule, IDS_OPTION_SHA1_DESC);
|
|
|
|
IDSwprintf(hModule,IDS_OPTION_X_DESC);
|
|
|
|
|
|
|
|
IDSwprintf(hModule,IDS_ENFLN);
|
|
IDSwprintf(hModule, IDS_MORE_INFO_1);
|
|
IDSwprintf(hModule, IDS_MORE_INFO_2);
|
|
IDSwprintf(hModule, IDS_MORE_INFO_3);
|
|
}
|
|
|
|
void UndocumentedUsage()
|
|
{
|
|
IDSwprintf(hModule,IDS_SYNTAX);
|
|
IDSwprintf(hModule,IDS_OPTIONS);
|
|
|
|
IDSwprintf(hModule, IDS_OPTION_H_DESC);
|
|
IDSwprintf(hModule, IDS_OPTION_TQ_DESC);
|
|
IDSwprintf(hModule, IDS_OPTION_TS_DESC);
|
|
IDSwprintf(hModule, IDS_OPTION_INDEX_DESC);
|
|
|
|
//mark this is undocumented
|
|
fUndocumented=TRUE;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// Print out error msg based on the HRESULT
|
|
//--------------------------------------------------------------------------------
|
|
BOOL PrintBasedOnHResult(HRESULT hr)
|
|
{
|
|
BOOL fKnownResult=TRUE;
|
|
|
|
switch(hr)
|
|
{
|
|
//0x80070002 is the HRESULT_FROM_WIN32(GetLastError()) when CreateFile failed
|
|
case 0x80070002:
|
|
IDSwprintf(hModule,IDS_ERR_INPUT_INVALID);
|
|
break;
|
|
case HRESULT_FROM_WIN32(ERROR_INVALID_DATA):
|
|
IDSwprintf(hModule,IDS_ERR_RESPONSE_INVALID);
|
|
break;
|
|
case HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION):
|
|
IDSwprintf(hModule, IDS_ERR_INVALID_ADDRESS);
|
|
break;
|
|
case CRYPT_E_NO_MATCH:
|
|
IDSwprintf(hModule,IDS_ERR_NOMATCH);
|
|
break;
|
|
case TYPE_E_TYPEMISMATCH:
|
|
IDSwprintf(hModule,IDS_ERR_AUTH);
|
|
break;
|
|
case CRYPT_E_FILERESIZED:
|
|
IDSwprintf(hModule,IDS_ERR_RESIZE);
|
|
break;
|
|
case TRUST_E_TIME_STAMP:
|
|
IDSwprintf(hModule, IDS_ERR_TS_CERT_INVALID);
|
|
break;
|
|
case CRYPT_E_NO_DECRYPT_CERT:
|
|
IDSwprintf(hModule, IDS_ERR_NO_CERT, pwszStoreName);
|
|
break;
|
|
case CRYPT_E_DELETED_PREV:
|
|
IDSwprintf(hModule, IDS_ERR_TOO_MANY_CERT, pwszStoreName);
|
|
break;
|
|
case CRYPT_E_NO_PROVIDER:
|
|
IDSwprintf(hModule, IDS_ERR_NO_PROVIDER);
|
|
break;
|
|
case CERT_E_CHAINING:
|
|
IDSwprintf(hModule, IDS_ERR_NO_CHAINING);
|
|
break;
|
|
case CERT_E_EXPIRED:
|
|
IDSwprintf(hModule, IDS_ERR_EXPRIED);
|
|
break;
|
|
default:
|
|
fKnownResult=FALSE;
|
|
}
|
|
return fKnownResult;
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// Convert an array of wchars to a BLOB
|
|
//--------------------------------------------------------------------------------
|
|
HRESULT WSZtoBLOB(LPWSTR pwsz, BYTE **ppbByte, DWORD *pcbByte)
|
|
{
|
|
HRESULT hr=E_FAIL;
|
|
DWORD dwIndex=0;
|
|
ULONG ulHalfByte=0;
|
|
DWORD dw1st=0;
|
|
DWORD dw2nd=0;
|
|
|
|
if((!pwsz) || (!ppbByte) || (!pcbByte))
|
|
return E_INVALIDARG;
|
|
|
|
*ppbByte=NULL;
|
|
*pcbByte=0;
|
|
|
|
//make sure the pwsz consists of 20 characters
|
|
if(wcslen(pwsz)!= 2*SHA1_LENGTH)
|
|
return E_FAIL;
|
|
|
|
//memory allocation
|
|
*ppbByte=(BYTE *)ToolUtlAlloc(SHA1_LENGTH);
|
|
if(NULL==(*ppbByte))
|
|
return E_INVALIDARG;
|
|
|
|
memset(*ppbByte, 0, SHA1_LENGTH);
|
|
|
|
//go through two characters (one byte) at a time
|
|
for(dwIndex=0; dwIndex<SHA1_LENGTH; dwIndex++)
|
|
{
|
|
dw1st=dwIndex * 2;
|
|
dw2nd=dwIndex * 2 +1;
|
|
|
|
//1st character
|
|
if(((int)(pwsz[dw1st])-(int)(L'0')) <=9 &&
|
|
((int)(pwsz[dw1st])-(int)(L'0')) >=0)
|
|
{
|
|
|
|
ulHalfByte=(ULONG)((ULONG)(pwsz[dw1st])-(ULONG)(L'0'));
|
|
}
|
|
else
|
|
{
|
|
if(((int)(towupper(pwsz[dw1st]))-(int)(L'A')) >=0 &&
|
|
((int)(towupper(pwsz[dw1st]))-(int)(L'A')) <=5 )
|
|
ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw1st]))-(ULONG)(L'A'));
|
|
else
|
|
{
|
|
hr=E_INVALIDARG;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
//copy the 1st character
|
|
(*ppbByte)[dwIndex]=(BYTE)ulHalfByte;
|
|
|
|
//left shift 4 bits
|
|
(*ppbByte)[dwIndex]= (*ppbByte)[dwIndex] <<4;
|
|
|
|
//2nd character
|
|
if(((int)(pwsz[dw2nd])-(int)(L'0')) <=9 &&
|
|
((int)(pwsz[dw2nd])-(int)(L'0')) >=0)
|
|
{
|
|
|
|
ulHalfByte=(ULONG)((ULONG)(pwsz[dw2nd])-(ULONG)(L'0'));
|
|
}
|
|
else
|
|
{
|
|
if(((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) >=0 &&
|
|
((int)(towupper(pwsz[dw2nd]))-(int)(L'A')) <=5 )
|
|
ulHalfByte=10+(ULONG)((ULONG)(towupper(pwsz[dw2nd]))-(ULONG)(L'A'));
|
|
else
|
|
{
|
|
hr=E_INVALIDARG;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
//ORed the second character
|
|
(*ppbByte)[dwIndex]=(*ppbByte)[dwIndex] | ((BYTE)ulHalfByte);
|
|
|
|
}
|
|
|
|
|
|
hr=S_OK;
|
|
|
|
CLEANUP:
|
|
|
|
if(hr!=S_OK)
|
|
{
|
|
if(*ppbByte)
|
|
ToolUtlFree(*ppbByte);
|
|
|
|
*ppbByte=NULL;
|
|
}
|
|
else
|
|
*pcbByte=SHA1_LENGTH;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
//make sure the input parameters make sense for signing
|
|
//--------------------------------------------------------------------------------
|
|
BOOL CheckSignParam()
|
|
{
|
|
//make sure pwszPvkFile and pwszKeyContainer name are not set at the same time
|
|
if(pwszPvkFile && pwszKeyContainer)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_BOTH_PVK);
|
|
return FALSE;
|
|
}
|
|
|
|
//make sure spc/pvk information and store related information can not be set
|
|
//at the same time
|
|
if(pwszSpcFile || pwszPvkFile || pwszKeyContainer || pwszProviderType ||
|
|
pwszCapiProvider ||pwszKeySpec)
|
|
{
|
|
fStoreTechnology=FALSE;
|
|
|
|
if(pwszStoreName || pwszCertFile || pwszStoreName || pwszStorePolicy ||
|
|
pwszStoreLocation || pwszCommonName || pwszSha1Hash)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_BOTH_SPC);
|
|
return FALSE;
|
|
}
|
|
|
|
//now that we are not using certStore, spc file has to be set
|
|
if(!pwszSpcFile)
|
|
{
|
|
IDSwprintf(hModule, IDS_ERR_NO_SPC);
|
|
return FALSE;
|
|
}
|
|
|
|
//either PVKFile or KeyContainer has to be set
|
|
if(pwszPvkFile == NULL && pwszKeyContainer ==NULL)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_PVK);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//pwszCommonName, pwszCertFile and pwszSha1Hash can not be set at the same time
|
|
if(pwszCertFile)
|
|
{
|
|
if(pwszCommonName || pwszSha1Hash)
|
|
{
|
|
IDSwprintf(hModule, IDS_ERR_BOTH_CN_SHA1);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if(pwszCommonName && pwszSha1Hash)
|
|
{
|
|
IDSwprintf(hModule, IDS_ERR_BOTH_CN_SHA1);
|
|
return FALSE;
|
|
}
|
|
|
|
//if pwszStoreLocation is set, then the storeName as to be set
|
|
if(pwszStoreLocation && (pwszStoreName==NULL))
|
|
{
|
|
IDSwprintf(hModule, IDS_STORE_LOCATION_NAME);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
//make sure the user has passed in a valid set of parameters
|
|
//--------------------------------------------------------------------------------
|
|
BOOL CheckParameter()
|
|
{
|
|
BOOL fValid=FALSE;
|
|
|
|
//has to set the file name
|
|
if(!pwszFile)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_FILE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if(fSigning==TRUE)
|
|
{
|
|
dwAction |= ACTION_SIGN;
|
|
|
|
//make sure the input parameters make sense
|
|
if(!CheckSignParam())
|
|
return FALSE;
|
|
}
|
|
|
|
if(pwszResponseFile)
|
|
{
|
|
dwAction |= ACTION_RESPONSE;
|
|
}
|
|
|
|
if(pwszHttpTime)
|
|
{
|
|
dwAction |= ACTION_STAMP;
|
|
|
|
|
|
//make sure that we have http:// in the address
|
|
if(wcslen(pwszHttpTime)<=7)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_ADDR_INVALID);
|
|
return FALSE;
|
|
}
|
|
|
|
if(IDSwcsnicmp(hModule, pwszHttpTime, IDS_HTTP,7)!=0)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_HTTP);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if(pwszRequestFile)
|
|
{
|
|
dwAction |= ACTION_REQUEST;
|
|
|
|
}
|
|
|
|
//make sure timestamping and applying response do not go together
|
|
if((dwAction & ACTION_RESPONSE) && (dwAction & ACTION_STAMP))
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_TIME_RESPONSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//make sure apply response can not be done after a new signature
|
|
if((dwAction & ACTION_SIGN) && (dwAction & ACTION_RESPONSE))
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_SIGN_RESPONSE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
//determine the algorithm OID
|
|
if(pwszAlgorithm)
|
|
{
|
|
if(IDSwcsicmp(hModule, pwszAlgorithm, IDS_A_MD5) == 0)
|
|
dwAlgorithmOid = CALG_MD5;
|
|
else
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszAlgorithm, IDS_A_SHA) == 0)
|
|
dwAlgorithmOid = CALG_SHA1;
|
|
else
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_ALGO);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//determing the store location
|
|
if(pwszStoreLocation)
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszStoreLocation, IDS_R_CU) == 0)
|
|
dwStoreFlag = CERT_SYSTEM_STORE_CURRENT_USER;
|
|
else
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszStoreLocation, IDS_R_LM) == 0)
|
|
dwStoreFlag = CERT_SYSTEM_STORE_LOCAL_MACHINE;
|
|
else
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_REG);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//determing the store policy
|
|
if(pwszStorePolicy)
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszStorePolicy, IDS_OPTION_SP_CHAIN) == 0)
|
|
dwStorePolicy=SIGNER_CERT_POLICY_CHAIN;
|
|
else
|
|
{
|
|
if(IDSwcsicmp(hModule, pwszStorePolicy, IDS_OPTION_SP_SPCSTORE) == 0)
|
|
dwStorePolicy=SIGNER_CERT_POLICY_SPC;
|
|
else
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_POLICY);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//determine the signing authority, either individual or commercial
|
|
if(pwszAuthority)
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszAuthority, IDS_AUTHORITY_ID) == 0)
|
|
fIndividual = TRUE;
|
|
else
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszAuthority, IDS_AUTHORITY_CM) == 0)
|
|
fCommercial = TRUE;
|
|
else
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_NO_AUTH);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//determine the key specificatioin
|
|
if(pwszKeySpec)
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszKeySpec, IDS_OPTION_KY_SIG) == 0)
|
|
dwKeySpec = AT_SIGNATURE;
|
|
else
|
|
{
|
|
if(IDSwcsicmp(hModule,pwszKeySpec, IDS_OPTION_KY_EXC) == 0)
|
|
dwKeySpec = AT_KEYEXCHANGE;
|
|
else
|
|
dwKeySpec=_wtol(pwszKeySpec);
|
|
}
|
|
|
|
}
|
|
|
|
//get the hash
|
|
if(pwszSha1Hash)
|
|
{
|
|
if(S_OK != WSZtoBLOB(pwszSha1Hash, &g_pbHash, &g_cbHash))
|
|
{
|
|
//sha1 hash is invalid
|
|
IDSwprintf(hModule, IDS_ERR_SHA1_HASH);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
//determine the provider Type
|
|
if(pwszProviderType)
|
|
dwProviderType = _wtoi(pwszProviderType);
|
|
|
|
//get the # of timestamp trial and the # of seconds of delay between
|
|
//each trial
|
|
if(pwszWait)
|
|
dwWait = _wtoi(pwszWait);
|
|
|
|
if(pwszRepeat)
|
|
dwRepeat = _wtoi(pwszRepeat);
|
|
|
|
//determine the default store name
|
|
if(!pwszStoreName)
|
|
pwszStoreName=wszMyStore;
|
|
|
|
//determin the signerIndex. Default to 0
|
|
if(pwszSignerIndex)
|
|
dwSignerIndex=_wtol(pwszSignerIndex);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// Set the parameters. They can only be set once
|
|
//--------------------------------------------------------------------------------
|
|
BOOL SetParam(WCHAR **ppwszParam, WCHAR *pwszValue)
|
|
{
|
|
if(*ppwszParam!=NULL)
|
|
{
|
|
IDSwprintf(hModule,IDS_ERR_TOO_MANY_PARAM);
|
|
return FALSE;
|
|
}
|
|
|
|
*ppwszParam=pwszValue;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// Parse arguements
|
|
//--------------------------------------------------------------------------------
|
|
BOOL
|
|
ParseSwitch (int *pArgc,
|
|
WCHAR **pArgv[])
|
|
{
|
|
WCHAR* param = **pArgv;
|
|
|
|
//move pass '/' or '-'
|
|
param++;
|
|
|
|
if (IDSwcsicmp(hModule, param, IDS_OPTION_H) == 0)
|
|
{
|
|
fTesting = TRUE;
|
|
if (!(param[1]))
|
|
{
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
param = **pArgv;
|
|
dwExpectedError = wcstoul(¶m[0], NULL, 16);
|
|
}
|
|
else
|
|
{
|
|
dwExpectedError = wcstoul(¶m[1], NULL, 16);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else if(IDSwcsicmp(hModule, param, IDS_OPTION_SPC)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
return SetParam(&pwszSpcFile, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule, param, IDS_OPTION_C)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
return SetParam(&pwszCertFile, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_S)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszStoreName, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_R)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszStoreLocation, **pArgv);
|
|
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_SP)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszStorePolicy, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_CN)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszCommonName, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_SHA1)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszSha1Hash, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_V)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszPvkFile, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_K)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszKeyContainer, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_N)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszOpusName, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_I)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszOpusInfo, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_P)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszCapiProvider, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_Y)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszProviderType, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_KY)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszKeySpec, **pArgv);
|
|
}
|
|
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_AUTH)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszAuthority, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_A)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszAlgorithm, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_X)==0) {
|
|
fSigning=FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_T)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszHttpTime, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_TW)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszWait,**pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_TR)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszRepeat,**pArgv);
|
|
}
|
|
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_J)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
prgwszDllName[dwDllIndex]=**pArgv;
|
|
|
|
//mark its corresponding parameter as NULL
|
|
dwParamIndex=dwDllIndex;
|
|
prgwszDllParam[dwParamIndex]=NULL;
|
|
|
|
dwDllIndex++;
|
|
|
|
return TRUE;
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_JP)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
//make sure there is only one or less parameter per dll
|
|
if(dwParamIndex+1!=dwDllIndex)
|
|
return FALSE;
|
|
|
|
prgwszDllParam[dwParamIndex]=**pArgv;
|
|
|
|
dwParamIndex++;
|
|
|
|
return TRUE;
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_TS)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszResponseFile, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_TQ)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszRequestFile, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_INDEX)==0) {
|
|
if (!--(*pArgc))
|
|
return FALSE;
|
|
|
|
(*pArgv)++;
|
|
|
|
return SetParam(&pwszSignerIndex, **pArgv);
|
|
}
|
|
else if(IDSwcsicmp(hModule,param, IDS_OPTION_TEST)==0) {
|
|
|
|
UndocumentedUsage();
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
//
|
|
// wmain
|
|
//
|
|
//--------------------------------------------------------------------------------
|
|
extern "C" int __cdecl wmain(int argc, WCHAR ** wargv)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
int idsAction=IDS_ACTION_SIGNCODE;
|
|
|
|
BYTE *pbStampResponse=NULL;
|
|
DWORD cbStampResponse=0;
|
|
BYTE *pbStampRequest=NULL;
|
|
DWORD cbStampRequest=0;
|
|
HANDLE hFile=NULL;
|
|
DWORD dwWriteBytes=0;
|
|
|
|
|
|
WCHAR *pwChar;
|
|
WCHAR wszSwitch1[OPTION_SWITCH_SIZE];
|
|
WCHAR wszSwitch2[OPTION_SWITCH_SIZE];
|
|
|
|
CRYPT_ATTRIBUTES AuthAttr;
|
|
CRYPT_ATTRIBUTES UnauthAttr;
|
|
PCRYPT_ATTRIBUTES *ppAuthAttr=NULL;
|
|
PCRYPT_ATTRIBUTES *ppUnauthAttr=NULL;
|
|
DWORD dwIndex=0;
|
|
DWORD dwMilliSeconds=0;
|
|
|
|
SIGNER_SUBJECT_INFO subjectInfo;
|
|
SIGNER_FILE_INFO fileInfo;
|
|
SIGNER_SIGNATURE_INFO signatureInfo;
|
|
SIGNER_ATTR_AUTHCODE attrAuthcode;
|
|
SIGNER_PROVIDER_INFO providerInfo;
|
|
SIGNER_CERT_STORE_INFO certStoreInfo;
|
|
SIGNER_CERT signerCert;
|
|
HCERTSTORE hCertStore=NULL;
|
|
|
|
CRYPTUI_WIZ_DIGITAL_SIGN_INFO DigitalSignInfo;
|
|
|
|
//call the UI version of the signcode
|
|
if(1==argc)
|
|
{
|
|
|
|
//memset
|
|
memset(&DigitalSignInfo, 0, sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO));
|
|
DigitalSignInfo.dwSize=sizeof(CRYPTUI_WIZ_DIGITAL_SIGN_INFO);
|
|
|
|
//call the signing wizard, which provides
|
|
//the confirmation result.
|
|
if(CryptUIWizDigitalSign(0,
|
|
NULL,
|
|
NULL,
|
|
&DigitalSignInfo,
|
|
NULL))
|
|
return 0;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
|
|
//get the module handle
|
|
if(!InitModule())
|
|
return -1;
|
|
|
|
//load the strings necessary for parsing the parameters
|
|
if( !LoadStringU(hModule, IDS_SWITCH1, wszSwitch1, OPTION_SWITCH_SIZE)
|
|
||!LoadStringU(hModule, IDS_SWITCH2, wszSwitch2, OPTION_SWITCH_SIZE)
|
|
||!LoadStringU(hModule, IDS_CAPITION, wszCaption, WSTR_LENGTH_MAX)
|
|
||!LoadStringU(hModule, IDS_PLUS, wszPlus, WSTR_LENGTH_MAX)
|
|
||!LoadStringU(hModule, IDS_MY, wszMyStore, STORE_DEFAULT_NAME_MAX)
|
|
)
|
|
return -1;
|
|
|
|
//load wszNULL
|
|
LoadStringU(hModule, IDS_NULL, wszNULL, WSTR_LENGTH_MAX);
|
|
|
|
if ( argc <= 1 )
|
|
{
|
|
Usage ();
|
|
return -1;
|
|
}
|
|
|
|
//allocate memory for prgwszDllName and prgwszDllParam
|
|
prgwszDllName=(LPWSTR *)ToolUtlAlloc(sizeof(LPWSTR)*argc);
|
|
prgwszDllParam=(LPWSTR *)ToolUtlAlloc(sizeof(LPWSTR)*argc);
|
|
dwDllIndex=0;
|
|
dwParamIndex=0;
|
|
|
|
if(!prgwszDllName || !prgwszDllParam)
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//memset
|
|
memset(prgwszDllName, 0, sizeof(LPWSTR)*argc);
|
|
memset(prgwszDllParam, 0, sizeof(LPWSTR)*argc);
|
|
memset(&AuthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
|
|
memset(&UnauthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
|
|
|
|
|
|
//parse the parameters
|
|
while (--argc)
|
|
{
|
|
pwChar = *++wargv;
|
|
if (*pwChar == *wszSwitch1 || *pwChar == *wszSwitch2)
|
|
{
|
|
//parse the options
|
|
if(!ParseSwitch (&argc, &wargv))
|
|
{
|
|
if(FALSE==fUndocumented)
|
|
Usage();
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//parse the file name
|
|
if(!SetParam(&pwszFile, pwChar))
|
|
{
|
|
Usage();
|
|
hr=E_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//Determine the parameter sets passed in by the user
|
|
if(!CheckParameter())
|
|
{
|
|
Usage();
|
|
hr=E_INVALIDARG;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//memory allocation for the dlls
|
|
if(dwDllIndex)
|
|
{
|
|
ppAuthAttr=(PCRYPT_ATTRIBUTES *)ToolUtlAlloc(sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
|
|
ppUnauthAttr=(PCRYPT_ATTRIBUTES *)ToolUtlAlloc(sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
|
|
|
|
if(!ppAuthAttr || !ppUnauthAttr)
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
memset(ppAuthAttr, 0,sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
|
|
memset(ppUnauthAttr, 0,sizeof(PCRYPT_ATTRIBUTES)*dwDllIndex);
|
|
}
|
|
|
|
|
|
//init the dll parameters, call the GetAttr entry points of the dlls
|
|
if(dwDllIndex)
|
|
{
|
|
if(S_OK!=(hr=InitDllParameter(&AuthAttr, &UnauthAttr,
|
|
ppAuthAttr, ppUnauthAttr)))
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//Perform the requested action one at a time
|
|
if(dwAction & ACTION_SIGN)
|
|
{
|
|
idsAction=IDS_ACTION_SIGN;
|
|
|
|
//set up the parameters for signing
|
|
if(S_OK != (hr=SetUpParameter(&subjectInfo, &fileInfo, &signatureInfo,
|
|
&attrAuthcode, &providerInfo,
|
|
&certStoreInfo, &signerCert,&AuthAttr,
|
|
&UnauthAttr, &hCertStore)))
|
|
goto CLEANUP;
|
|
|
|
|
|
hr=SignerSign(&subjectInfo,
|
|
&signerCert,
|
|
&signatureInfo,
|
|
fStoreTechnology ? NULL : &providerInfo,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_SIGN;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
#if (0) //DSIE: Bug 236022
|
|
//warn the user that the file is not timeStamped
|
|
if (!(dwAction & ACTION_STAMP) && !(dwAction & ACTION_RESPONSE) && !(fTesting))
|
|
IDSwprintf(hModule,IDS_WARNING);
|
|
#endif
|
|
//free the certificate context
|
|
if(certStoreInfo.pSigningCert)
|
|
CertFreeCertificateContext(certStoreInfo.pSigningCert);
|
|
|
|
//close the cert store which includes the signing certificate
|
|
if(hCertStore)
|
|
CertCloseStore(hCertStore, 0);
|
|
|
|
}
|
|
|
|
if(dwAction & ACTION_STAMP)
|
|
{
|
|
//timestamp the code
|
|
dwMilliSeconds=dwWait*1000;
|
|
|
|
//set up subject information
|
|
if((dwAction & ACTION_SIGN) ==0)
|
|
{
|
|
if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
|
|
goto CLEANUP;
|
|
}
|
|
|
|
|
|
//perform the # of trials
|
|
for(dwIndex=0; dwIndex<dwRepeat; dwIndex++)
|
|
{
|
|
|
|
hr=SignerTimeStamp(&subjectInfo,pwszHttpTime,NULL,NULL);
|
|
|
|
if(hr==S_OK)
|
|
break;
|
|
|
|
//wait per timestamp request
|
|
if(dwWait!=0)
|
|
Sleep(dwMilliSeconds);
|
|
}
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_TIMESTAMP;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
}
|
|
|
|
if(dwAction & ACTION_RESPONSE)
|
|
{
|
|
|
|
hr=RetrieveBLOBFromFile(pwszResponseFile,&cbStampResponse,
|
|
&pbStampResponse);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_RESPONSE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//set up subject information
|
|
if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
|
|
goto CLEANUP;
|
|
|
|
hr=SignerAddTimeStampResponse(&subjectInfo,
|
|
pbStampResponse,
|
|
cbStampResponse,
|
|
NULL);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_RESPONSE;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
if(dwAction & ACTION_REQUEST)
|
|
{
|
|
cbStampRequest=0;
|
|
|
|
//set up subject information
|
|
if(S_OK!=(hr=SetUpSubjectInfo(&subjectInfo, &fileInfo)))
|
|
goto CLEANUP;
|
|
|
|
|
|
hr=SignerCreateTimeStampRequest(
|
|
&subjectInfo,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&cbStampRequest);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_REQUEST;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
pbStampRequest=(BYTE *)ToolUtlAlloc(cbStampRequest);
|
|
|
|
if(!pbStampRequest)
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
idsAction=IDS_ACTION_REQUEST;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
hr=SignerCreateTimeStampRequest(
|
|
&subjectInfo,
|
|
NULL,
|
|
NULL,
|
|
pbStampRequest,
|
|
&cbStampRequest);
|
|
|
|
if ( hr != S_OK)
|
|
{
|
|
idsAction=IDS_ACTION_REQUEST;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//put the stamp request into a file
|
|
if((hFile = CreateFileU(pwszRequestFile,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL)) == INVALID_HANDLE_VALUE)
|
|
{
|
|
hr=SignError();
|
|
idsAction=IDS_ACTION_REQUEST;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
|
|
|
|
if(WriteFile(hFile,
|
|
pbStampRequest,
|
|
cbStampRequest,
|
|
&dwWriteBytes,
|
|
NULL) == FALSE ||
|
|
dwWriteBytes != cbStampRequest)
|
|
{
|
|
hr=SignError();
|
|
idsAction=IDS_ACTION_REQUEST;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CLEANUP:
|
|
|
|
if (fTesting)
|
|
{
|
|
if (hr == (HRESULT)dwExpectedError)
|
|
IDSwprintf(hModule,IDS_TEST_SUCCEEDED, hr);
|
|
else
|
|
IDSwprintf(hModule,IDS_TEST_FAILED, dwExpectedError, hr);
|
|
}
|
|
else
|
|
{
|
|
if(hr==S_OK)
|
|
{
|
|
IDSwprintf(hModule,IDS_SUCCEEDED);
|
|
|
|
//we need to tell user the returned index of signature/timestamp
|
|
if(pwszSignerIndex)
|
|
IDSwprintf(hModule, IDS_SIGNER_INDEX, *(subjectInfo.pdwIndex));
|
|
}
|
|
else
|
|
{
|
|
//first try to print out dedebug info
|
|
if(!PrintBasedOnHResult(hr))
|
|
{
|
|
|
|
//print out addtional info for timestamping
|
|
if(idsAction==IDS_ACTION_TIMESTAMP)
|
|
{
|
|
/*if(dwIndex!=1)
|
|
IDSwprintf(hModule,IDS_TIMESTAMP_TIMES_DELAY, dwIndex+1,dwWait); */
|
|
|
|
//file needs to be signed in order to timestamp it
|
|
if((dwAction & ACTION_SIGN) ==0)
|
|
//file may needs to be resigned
|
|
IDSwprintf(hModule,IDS_RESIGN);
|
|
}
|
|
}
|
|
|
|
//then print out general information
|
|
IDS_IDS_DW_DWwprintf(hModule,IDS_ERROR, idsAction, hr, hr);
|
|
|
|
}
|
|
}
|
|
|
|
if(hFile)
|
|
CloseHandle(hFile);
|
|
|
|
//release the authenticated attributes
|
|
ReleaseDllParameter(ppAuthAttr, ppUnauthAttr);
|
|
|
|
//release prgwszDllName
|
|
if(prgwszDllName)
|
|
ToolUtlFree(prgwszDllName);
|
|
|
|
//release prgwszDllParam
|
|
if(prgwszDllParam)
|
|
ToolUtlFree(prgwszDllParam);
|
|
|
|
//release pAuthAttr
|
|
if(AuthAttr.rgAttr)
|
|
ToolUtlFree(AuthAttr.rgAttr);
|
|
|
|
if(UnauthAttr.rgAttr)
|
|
ToolUtlFree(UnauthAttr.rgAttr);
|
|
|
|
//free ppAuthAttr and ppUnauthAttr
|
|
if(ppAuthAttr)
|
|
ToolUtlFree(ppAuthAttr);
|
|
|
|
if(ppUnauthAttr)
|
|
ToolUtlFree(ppUnauthAttr);
|
|
|
|
|
|
if(pbStampResponse)
|
|
UnmapViewOfFile(pbStampResponse);
|
|
|
|
if(pbStampRequest)
|
|
ToolUtlFree(pbStampRequest);
|
|
|
|
|
|
if(g_pbHash)
|
|
ToolUtlFree(g_pbHash);
|
|
|
|
|
|
if(hr==S_OK)
|
|
return 0;
|
|
else
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Get the hash from a cert file
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT GetCertHashFromFile(LPWSTR pwszCertFile,
|
|
BYTE **ppHash,
|
|
DWORD *pcbHash,
|
|
BOOL *pfMore)
|
|
{
|
|
HRESULT hr=S_OK;
|
|
HCERTSTORE hCertStore=NULL;
|
|
PCCERT_CONTEXT pSigningCert=NULL;
|
|
PCCERT_CONTEXT pPreCert=NULL;
|
|
PCCERT_CONTEXT pDupCert=NULL;
|
|
DWORD dwCount=0;
|
|
|
|
if(!ppHash || !pcbHash || !pfMore)
|
|
return E_INVALIDARG;
|
|
|
|
//init
|
|
*pcbHash=0;
|
|
*ppHash=NULL;
|
|
*pfMore=FALSE;
|
|
|
|
//open a cert store
|
|
hCertStore=CertOpenStore(CERT_STORE_PROV_FILENAME_W,
|
|
dwStoreEncodingType,
|
|
NULL,
|
|
0,
|
|
pwszCertFile);
|
|
|
|
if(hCertStore==NULL)
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
while(pDupCert=CertEnumCertificatesInStore(hCertStore,
|
|
pPreCert))
|
|
{
|
|
dwCount++;
|
|
|
|
if(dwCount > 1)
|
|
{
|
|
CertFreeCertificateContext(pDupCert);
|
|
pDupCert=NULL;
|
|
CertFreeCertificateContext(pSigningCert);
|
|
pSigningCert=NULL;
|
|
|
|
*pfMore=TRUE;
|
|
hr=S_FALSE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
pPreCert=pDupCert;
|
|
|
|
pSigningCert=CertDuplicateCertificateContext(pDupCert);
|
|
|
|
}
|
|
|
|
if(pSigningCert==NULL)
|
|
{
|
|
hr=CRYPT_E_NO_DECRYPT_CERT;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//get the hash
|
|
if(!CertGetCertificateContextProperty(pSigningCert,
|
|
CERT_SHA1_HASH_PROP_ID,
|
|
NULL,
|
|
pcbHash))
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
*ppHash=(BYTE *)ToolUtlAlloc(*pcbHash);
|
|
if(!(*ppHash))
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if(!CertGetCertificateContextProperty(pSigningCert,
|
|
CERT_SHA1_HASH_PROP_ID,
|
|
*ppHash,
|
|
pcbHash))
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if(pSigningCert)
|
|
CertFreeCertificateContext(pSigningCert);
|
|
|
|
if(hCertStore)
|
|
CertCloseStore(hCertStore, 0);
|
|
|
|
if(hr!=S_OK)
|
|
{
|
|
if(*ppHash)
|
|
{
|
|
ToolUtlFree(*ppHash);
|
|
*ppHash=NULL;
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Get the signing certificate
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
PCCERT_CONTEXT GetSigningCert(HCERTSTORE *phCertStore, BOOL *pfMore)
|
|
{
|
|
PCCERT_CONTEXT pSigningCert=NULL;
|
|
PCCERT_CONTEXT pPreCert=NULL;
|
|
PCCERT_CONTEXT pDupCert=NULL;
|
|
BYTE *pHash=NULL;
|
|
DWORD cbHash;
|
|
HCERTSTORE hCertStore=NULL;
|
|
CRYPT_HASH_BLOB HashBlob;
|
|
DWORD dwCount=0;
|
|
|
|
//init the output
|
|
if(!phCertStore || !pfMore)
|
|
return NULL;
|
|
|
|
*phCertStore=NULL;
|
|
*pfMore=FALSE;
|
|
|
|
//open a cert store
|
|
hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
|
|
dwStoreEncodingType,
|
|
NULL,
|
|
dwStoreFlag |CERT_STORE_READONLY_FLAG,
|
|
pwszStoreName);
|
|
|
|
if(!hCertStore)
|
|
return NULL;
|
|
|
|
|
|
//get the hash of the certificate. Find the cert based on
|
|
//pwszCertFile
|
|
if(pwszCertFile)
|
|
{
|
|
if(S_OK != GetCertHashFromFile(pwszCertFile, &pHash, &cbHash, pfMore))
|
|
goto CLEANUP;
|
|
|
|
HashBlob.cbData=cbHash;
|
|
HashBlob.pbData=pHash;
|
|
|
|
pSigningCert=CertFindCertificateInStore(hCertStore,
|
|
dwCertEncodingType,
|
|
0,
|
|
CERT_FIND_SHA1_HASH,
|
|
&HashBlob,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
//find the certificate with the common name
|
|
if(pwszCommonName)
|
|
{
|
|
while(pDupCert=CertFindCertificateInStore(hCertStore,
|
|
dwCertEncodingType,
|
|
0,
|
|
CERT_FIND_SUBJECT_STR_W,
|
|
pwszCommonName,
|
|
pPreCert))
|
|
{
|
|
dwCount++;
|
|
|
|
if(dwCount > 1)
|
|
{
|
|
CertFreeCertificateContext(pDupCert);
|
|
pDupCert=NULL;
|
|
CertFreeCertificateContext(pSigningCert);
|
|
pSigningCert=NULL;
|
|
|
|
*pfMore=TRUE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
pPreCert=pDupCert;
|
|
|
|
pSigningCert=CertDuplicateCertificateContext(pDupCert);
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//find the certificate based on the hash
|
|
if(g_pbHash)
|
|
{
|
|
|
|
HashBlob.cbData=g_cbHash;
|
|
HashBlob.pbData=g_pbHash;
|
|
|
|
pSigningCert=CertFindCertificateInStore(hCertStore,
|
|
dwCertEncodingType,
|
|
0,
|
|
CERT_FIND_SHA1_HASH,
|
|
&HashBlob,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
//no searching criteria, find the only cert in the store
|
|
while(pDupCert=CertEnumCertificatesInStore(hCertStore,
|
|
pPreCert))
|
|
{
|
|
dwCount++;
|
|
|
|
if(dwCount > 1)
|
|
{
|
|
CertFreeCertificateContext(pDupCert);
|
|
pDupCert=NULL;
|
|
CertFreeCertificateContext(pSigningCert);
|
|
pSigningCert=NULL;
|
|
|
|
*pfMore=TRUE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
pPreCert=pDupCert;
|
|
|
|
pSigningCert=CertDuplicateCertificateContext(pDupCert);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
CLEANUP:
|
|
|
|
if(pHash)
|
|
ToolUtlFree(pHash);
|
|
|
|
if(pSigningCert)
|
|
{
|
|
*phCertStore=hCertStore;
|
|
}
|
|
else
|
|
{
|
|
//free the hCertStore
|
|
CertCloseStore(hCertStore, 0);
|
|
}
|
|
|
|
return pSigningCert;
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Set up the subject info
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT SetUpSubjectInfo(SIGNER_SUBJECT_INFO *pSubjectInfo,
|
|
SIGNER_FILE_INFO *pFileInfo)
|
|
{
|
|
if(!pSubjectInfo || !pFileInfo)
|
|
return E_INVALIDARG;
|
|
|
|
//init
|
|
memset(pSubjectInfo, 0, sizeof(SIGNER_SUBJECT_INFO));
|
|
memset(pFileInfo, 0, sizeof(SIGNER_FILE_INFO));
|
|
|
|
//init cbSize
|
|
pSubjectInfo->cbSize=sizeof(SIGNER_SUBJECT_INFO);
|
|
pFileInfo->cbSize=sizeof(SIGNER_FILE_INFO);
|
|
|
|
//init pSubjectInfo
|
|
pSubjectInfo->pdwIndex=&dwSignerIndex;
|
|
pSubjectInfo->dwSubjectChoice=SIGNER_SUBJECT_FILE;
|
|
pSubjectInfo->pSignerFileInfo=pFileInfo;
|
|
pFileInfo->pwszFileName=pwszFile;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Set up the signing parameters
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT SetUpParameter(SIGNER_SUBJECT_INFO *pSubjectInfo,
|
|
SIGNER_FILE_INFO *pFileInfo,
|
|
SIGNER_SIGNATURE_INFO *pSignatureInfo,
|
|
SIGNER_ATTR_AUTHCODE *pAttrAuthcode,
|
|
SIGNER_PROVIDER_INFO *pProviderInfo,
|
|
SIGNER_CERT_STORE_INFO *pCertStoreInfo,
|
|
SIGNER_CERT *pSignerCert,
|
|
CRYPT_ATTRIBUTES *pAuthenticated,
|
|
CRYPT_ATTRIBUTES *pUnauthenticated,
|
|
HCERTSTORE *phCertStore
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
PCCERT_CONTEXT pCertContext=NULL;
|
|
BOOL fMore=FALSE;
|
|
|
|
|
|
if(S_OK!=(hr=SetUpSubjectInfo(pSubjectInfo, pFileInfo)))
|
|
return hr;
|
|
|
|
|
|
if(!pSignatureInfo || !pAttrAuthcode || !pProviderInfo ||
|
|
!pCertStoreInfo || !pSignerCert)
|
|
return E_INVALIDARG;
|
|
|
|
//init
|
|
memset(pSignatureInfo, 0, sizeof(SIGNER_SIGNATURE_INFO));
|
|
memset(pAttrAuthcode, 0, sizeof(SIGNER_ATTR_AUTHCODE));
|
|
memset(pProviderInfo, 0, sizeof(SIGNER_PROVIDER_INFO));
|
|
memset(pCertStoreInfo, 0, sizeof(SIGNER_CERT_STORE_INFO));
|
|
memset(pSignerCert, 0, sizeof(SIGNER_CERT));
|
|
|
|
|
|
//init cbSize
|
|
pSignatureInfo->cbSize=sizeof(SIGNER_SIGNATURE_INFO);
|
|
pAttrAuthcode->cbSize=sizeof(SIGNER_ATTR_AUTHCODE);
|
|
pProviderInfo->cbSize=sizeof(SIGNER_PROVIDER_INFO);
|
|
pCertStoreInfo->cbSize=sizeof(SIGNER_CERT_STORE_INFO);
|
|
pSignerCert->cbSize=sizeof(SIGNER_CERT);
|
|
|
|
|
|
//init pAttrAuthcode
|
|
pAttrAuthcode->fCommercial=fCommercial;
|
|
pAttrAuthcode->fIndividual=fIndividual;
|
|
pAttrAuthcode->pwszName=pwszOpusName;
|
|
pAttrAuthcode->pwszInfo=pwszOpusInfo;
|
|
|
|
//init pSignatureInfo
|
|
pSignatureInfo->algidHash=dwAlgorithmOid;
|
|
pSignatureInfo->dwAttrChoice=SIGNER_AUTHCODE_ATTR;
|
|
pSignatureInfo->pAttrAuthcode=pAttrAuthcode;
|
|
pSignatureInfo->psAuthenticated=pAuthenticated;
|
|
pSignatureInfo->psUnauthenticated=pUnauthenticated;
|
|
|
|
//init pProviderInfo only if we are using non-cerStore tech
|
|
if(fStoreTechnology!=TRUE)
|
|
{
|
|
pProviderInfo->pwszProviderName=pwszCapiProvider;
|
|
pProviderInfo->dwProviderType=dwProviderType;
|
|
pProviderInfo->dwKeySpec=dwKeySpec;
|
|
if(pwszPvkFile)
|
|
{
|
|
pProviderInfo->dwPvkChoice=PVK_TYPE_FILE_NAME;
|
|
pProviderInfo->pwszPvkFileName=pwszPvkFile;
|
|
}
|
|
else
|
|
{
|
|
pProviderInfo->dwPvkChoice=PVK_TYPE_KEYCONTAINER;
|
|
pProviderInfo->pwszKeyContainer=pwszKeyContainer;
|
|
}
|
|
}
|
|
|
|
//init pSignerCert
|
|
if(fStoreTechnology)
|
|
{
|
|
//get the signing cert context
|
|
pCertContext=GetSigningCert(phCertStore,&fMore );
|
|
if(!pCertContext)
|
|
{
|
|
if(fMore==FALSE)
|
|
return CRYPT_E_NO_DECRYPT_CERT;
|
|
else
|
|
return CRYPT_E_DELETED_PREV;
|
|
}
|
|
|
|
pSignerCert->dwCertChoice=SIGNER_CERT_STORE;
|
|
pSignerCert->pCertStoreInfo=pCertStoreInfo;
|
|
//init pCertStoreInfo
|
|
pCertStoreInfo->pSigningCert=pCertContext;
|
|
pCertStoreInfo->dwCertPolicy=dwStorePolicy;
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
pSignerCert->dwCertChoice=SIGNER_CERT_SPC_FILE;
|
|
pSignerCert->pwszSpcFile=pwszSpcFile;
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
//get the attributes from the dlls
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
HRESULT InitDllParameter(PCRYPT_ATTRIBUTES pAuthAttr,
|
|
PCRYPT_ATTRIBUTES pUnauthAttr,
|
|
PCRYPT_ATTRIBUTES *ppAuthAttr,
|
|
PCRYPT_ATTRIBUTES *ppUnauthAttr)
|
|
{
|
|
DWORD dwIndex=0;
|
|
DWORD dwIndex2=0;
|
|
DWORD dwAttrIndex=0;
|
|
HRESULT hr=E_FAIL;
|
|
HINSTANCE hAuthInst=NULL;
|
|
LPSTR pszName=NULL;
|
|
FARPROC pProc=NULL;
|
|
PCRYPT_ATTRIBUTES pDllAuthAttr=NULL;
|
|
PCRYPT_ATTRIBUTES pDllUnauthAttr=NULL;
|
|
DWORD dwAuthAttrSum=0;
|
|
DWORD dwUnauthAttrSum=0;
|
|
|
|
if(dwDllIndex==0)
|
|
return S_OK;
|
|
|
|
|
|
if(!ppAuthAttr || !ppUnauthAttr ||!pAuthAttr || !pUnauthAttr)
|
|
return E_INVALIDARG;
|
|
|
|
|
|
//process each dll
|
|
for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
|
|
{
|
|
//get the char version of the dll name
|
|
if((prgwszDllName[dwIndex] == NULL) ||
|
|
(S_OK!=(hr=WSZtoSZ(prgwszDllName[dwIndex], &pszName))))
|
|
goto CLEANUP;
|
|
|
|
//load the libriary
|
|
hAuthInst=LoadLibrary(pszName);
|
|
|
|
if(!hAuthInst)
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//init
|
|
if(!(pProc=GetProcAddress(hAuthInst, "InitAttr")))
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if(S_OK!=(hr=((pInitAttr)pProc)(prgwszDllParam[dwIndex])))
|
|
goto CLEANUP;
|
|
|
|
//get the attributes for either GetAttr or GetAttrEx
|
|
if(!(pProc=GetProcAddress(hAuthInst, "GetAttrEx")))
|
|
{
|
|
if(!(pProc=GetProcAddress(hAuthInst, "GetAttr")))
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if(S_OK!=(hr=((pGetAttr)pProc)(&pDllAuthAttr, &pDllUnauthAttr)))
|
|
goto CLEANUP;
|
|
|
|
}
|
|
else
|
|
{
|
|
if(S_OK!=(hr=((pGetAttrEx)pProc)(0,
|
|
pwszFile,
|
|
prgwszDllParam[dwIndex],
|
|
&pDllAuthAttr,
|
|
&pDllUnauthAttr)))
|
|
goto CLEANUP;
|
|
}
|
|
|
|
|
|
//make sure valid return
|
|
if(!pDllAuthAttr || !pDllUnauthAttr)
|
|
{
|
|
hr=E_UNEXPECTED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//add the sum pf authenticated
|
|
if(pDllAuthAttr->cAttr)
|
|
dwAuthAttrSum+=pDllAuthAttr->cAttr;
|
|
|
|
ppAuthAttr[dwIndex]=pDllAuthAttr;
|
|
|
|
|
|
//add the sume of unauthenticated
|
|
if(pDllUnauthAttr->cAttr)
|
|
dwUnauthAttrSum+=pDllUnauthAttr->cAttr;
|
|
|
|
ppUnauthAttr[dwIndex]=pDllUnauthAttr;
|
|
|
|
//exit
|
|
if(!(pProc=GetProcAddress(hAuthInst, "ExitAttr")))
|
|
{
|
|
hr=SignError();
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if(S_OK!=(hr=((pExitAttr)pProc)()))
|
|
goto CLEANUP;
|
|
|
|
//free library
|
|
FreeLibrary(hAuthInst);
|
|
hAuthInst=NULL;
|
|
|
|
//free memory
|
|
ToolUtlFree(pszName);
|
|
pszName=NULL;
|
|
}
|
|
|
|
|
|
//build up authenticated attribute
|
|
if(dwAuthAttrSum)
|
|
{
|
|
pAuthAttr->cAttr=dwAuthAttrSum;
|
|
pAuthAttr->rgAttr=(PCRYPT_ATTRIBUTE)ToolUtlAlloc(sizeof(CRYPT_ATTRIBUTE)*
|
|
pAuthAttr->cAttr);
|
|
|
|
if(!(pAuthAttr->rgAttr) )
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//build up autheticated attributes
|
|
dwAttrIndex=0;
|
|
for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
|
|
{
|
|
for(dwIndex2=0;dwIndex2<ppAuthAttr[dwIndex]->cAttr; dwIndex2++)
|
|
{
|
|
pAuthAttr->rgAttr[dwAttrIndex]= ppAuthAttr[dwIndex]->rgAttr[dwIndex2];
|
|
dwAttrIndex++;
|
|
}
|
|
|
|
}
|
|
|
|
//make sure dwAttrIndex==pAuthAttr->cAttr
|
|
if(dwAttrIndex!=pAuthAttr->cAttr)
|
|
{
|
|
hr=E_UNEXPECTED;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memset(pAuthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
|
|
}
|
|
|
|
|
|
//build up unauthenticated attribute
|
|
if(dwUnauthAttrSum)
|
|
{
|
|
|
|
pUnauthAttr->cAttr=dwUnauthAttrSum;
|
|
|
|
pUnauthAttr->rgAttr=(PCRYPT_ATTRIBUTE)ToolUtlAlloc(sizeof(CRYPT_ATTRIBUTE)*
|
|
pUnauthAttr->cAttr);
|
|
|
|
if(!(pUnauthAttr->rgAttr))
|
|
{
|
|
hr=E_OUTOFMEMORY;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
|
|
|
|
//build up the unauthenticated attributes
|
|
dwAttrIndex=0;
|
|
for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
|
|
{
|
|
for(dwIndex2=0; dwIndex2<ppUnauthAttr[dwIndex]->cAttr; dwIndex2++)
|
|
{
|
|
pUnauthAttr->rgAttr[dwAttrIndex]=ppUnauthAttr[dwIndex]->rgAttr[dwIndex2];
|
|
dwAttrIndex++;
|
|
}
|
|
}
|
|
|
|
if(dwAttrIndex != pUnauthAttr->cAttr)
|
|
{
|
|
hr=E_UNEXPECTED;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memset(pUnauthAttr, 0, sizeof(CRYPT_ATTRIBUTES));
|
|
}
|
|
|
|
hr=S_OK;
|
|
|
|
CLEANUP:
|
|
|
|
if(hAuthInst)
|
|
FreeLibrary(hAuthInst);
|
|
|
|
if(pszName)
|
|
ToolUtlFree(pszName);
|
|
|
|
//free up memory when hr!=S_OK
|
|
if(hr!=S_OK)
|
|
{
|
|
if(pAuthAttr->rgAttr)
|
|
{
|
|
ToolUtlFree(pAuthAttr->rgAttr);
|
|
pAuthAttr->rgAttr=NULL;
|
|
}
|
|
|
|
if(pUnauthAttr->rgAttr)
|
|
{
|
|
ToolUtlFree(pUnauthAttr->rgAttr);
|
|
pUnauthAttr->rgAttr=NULL;
|
|
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
// Release the attributes by calling the dlls's ReleaseAttr entry point
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
void ReleaseDllParameter(PCRYPT_ATTRIBUTES * ppAuthAttr,
|
|
PCRYPT_ATTRIBUTES * ppUnauthAttr)
|
|
{
|
|
DWORD dwIndex=0;
|
|
HRESULT hr=E_FAIL;
|
|
HINSTANCE hAuthInst=NULL;
|
|
LPSTR pszName=NULL;
|
|
FARPROC pProc=NULL;
|
|
|
|
if((dwDllIndex==0) ||(!ppAuthAttr) || (!ppUnauthAttr))
|
|
return;
|
|
|
|
|
|
//process each dll
|
|
for(dwIndex=0; dwIndex<dwDllIndex; dwIndex++)
|
|
{
|
|
//free library
|
|
if(hAuthInst)
|
|
{
|
|
FreeLibrary(hAuthInst);
|
|
hAuthInst=NULL;
|
|
}
|
|
|
|
//free memory
|
|
if(pszName)
|
|
{
|
|
ToolUtlFree(pszName);
|
|
pszName=NULL;
|
|
}
|
|
|
|
|
|
//get the char version of the dll name
|
|
if((prgwszDllName[dwIndex]==NULL) ||
|
|
(S_OK!=(hr=WSZtoSZ(prgwszDllName[dwIndex], &pszName))))
|
|
continue;
|
|
|
|
//load the libriary
|
|
hAuthInst=LoadLibrary(pszName);
|
|
|
|
if(!hAuthInst)
|
|
continue;
|
|
|
|
//init
|
|
if(!(pProc=GetProcAddress(hAuthInst, "InitAttr")))
|
|
continue;
|
|
|
|
if(S_OK!=(hr=((pInitAttr)pProc)(prgwszDllParam[dwIndex])))
|
|
continue;
|
|
|
|
//release the attributes
|
|
if(!(pProc=GetProcAddress(hAuthInst, "ReleaseAttr")))
|
|
continue;
|
|
|
|
if(S_OK!=(hr=((pReleaseAttr)pProc)(
|
|
ppAuthAttr[dwIndex], ppUnauthAttr[dwIndex])))
|
|
continue;
|
|
|
|
//exit
|
|
if(!(pProc=GetProcAddress(hAuthInst, "ExitAttr")))
|
|
continue;
|
|
|
|
((pExitAttr)pProc)();
|
|
}
|
|
|
|
|
|
//cleanup
|
|
if(hAuthInst)
|
|
{
|
|
FreeLibrary(hAuthInst);
|
|
hAuthInst=NULL;
|
|
}
|
|
|
|
//free memory
|
|
if(pszName)
|
|
{
|
|
ToolUtlFree(pszName);
|
|
pszName=NULL;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|