windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/mssip32/mssip32.cpp
2020-09-26 16:20:57 +08:00

714 lines
18 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: mssip32.cpp
//
// Contents: Microsoft SIP Provider
//
// History: 14-Feb-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "sipobj.hxx"
#include "sipobjpe.hxx"
#include "sipobjjv.hxx"
#include "sipobjcb.hxx"
#include "sipobjfl.hxx"
#include "sipobjct.hxx"
#include "sipobjss.hxx"
#include "crypthlp.h"
#include "sha.h"
#include "md5.h"
#define MY_NAME L"WINTRUST.DLL"
SIPObject_ *mssip_CreateSubjectObject(const GUID *chk);
//
// the entries in SubjectsGuid MUST be in the same
// relative position and coalate with those in the
// SubjectsID.
//
static const GUID SubjectsGuid[] =
{
CRYPT_SUBJTYPE_PE_IMAGE,
CRYPT_SUBJTYPE_JAVACLASS_IMAGE,
CRYPT_SUBJTYPE_CABINET_IMAGE,
CRYPT_SUBJTYPE_FLAT_IMAGE,
CRYPT_SUBJTYPE_CATALOG_IMAGE,
CRYPT_SUBJTYPE_CTL_IMAGE
};
// CRYPT_SUBJTYPE_SS_IMAGE
static const UINT SubjectsID[] =
{
MSSIP_ID_PE,
MSSIP_ID_JAVA,
MSSIP_ID_CAB,
MSSIP_ID_FLAT,
MSSIP_ID_CATALOG,
MSSIP_ID_CTL,
MSSIP_ID_NONE // MUST be at the end!
};
// MSSIP_ID_SS,
BOOL WINAPI CryptSIPGetSignedDataMsg( IN SIP_SUBJECTINFO *pSubjectInfo,
OUT DWORD *dwEncodingType,
IN DWORD dwIndex,
IN OUT DWORD *pdwDataLen,
OUT BYTE *pbData)
{
DWORD dwLastError=0;
if (!(pSubjectInfo) || !(pdwDataLen) || !(dwEncodingType))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
SIPObject_ *pSubjectObj;
if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
if (!(pSubjectObj))
{
if (!(pbData))
{
*pdwDataLen = 0;
}
return(FALSE);
}
pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
BOOL bRet;
bRet = pSubjectObj->GetSignedDataMsg(pSubjectInfo,
dwIndex,pdwDataLen,pbData,dwEncodingType);
dwLastError=GetLastError();
delete pSubjectObj;
SetLastError(dwLastError);
return(bRet);
}
BOOL WINAPI CryptSIPPutSignedDataMsg( IN SIP_SUBJECTINFO *pSubjectInfo,
IN DWORD dwEncodingType,
OUT DWORD *pdwIndex,
IN DWORD dwDataLen,
IN BYTE *pbData)
{
if (!(pSubjectInfo) ||
(dwDataLen < 1) ||
!(pdwIndex) ||
!(pbData))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
SIPObject_ *pSubjectObj;
if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
if (!(pSubjectObj))
{
return(FALSE);
}
pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
BOOL bRet;
bRet = pSubjectObj->PutSignedDataMsg(pSubjectInfo,
pdwIndex,dwDataLen,pbData,dwEncodingType);
delete pSubjectObj;
return(bRet);
}
BOOL WINAPI CryptSIPRemoveSignedDataMsg( IN SIP_SUBJECTINFO *pSubjectInfo,
IN DWORD dwIndex)
{
if (!(pSubjectInfo))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
SIPObject_ *pSubjectObj;
if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
if (!(pSubjectObj))
{
return(FALSE);
}
pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
BOOL bRet;
bRet = pSubjectObj->RemoveSignedDataMsg(pSubjectInfo,dwIndex);
delete pSubjectObj;
return(bRet);
}
BOOL WINAPI CryptSIPCreateIndirectData( IN SIP_SUBJECTINFO *pSubjectInfo,
IN OUT DWORD *pdwDataLen,
OUT SIP_INDIRECT_DATA *psData)
{
if (!(pSubjectInfo) || !(pdwDataLen))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
SIPObject_ *pSubjectObj;
if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
if (!(pSubjectObj))
{
if (!(psData))
{
*pdwDataLen = 0;
}
return(FALSE);
}
//
// ALWAYS set the latest version when we are creating the
// indirect data content!
//
pSubjectInfo->dwIntVersion = WIN_CERT_REVISION_2_0;
pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
BOOL bRet;
bRet = pSubjectObj->CreateIndirectData(pSubjectInfo,pdwDataLen,psData);
delete pSubjectObj;
return(bRet);
}
BOOL WINAPI CryptSIPVerifyIndirectData( IN SIP_SUBJECTINFO *pSubjectInfo,
IN SIP_INDIRECT_DATA *psData)
{
if (!(pSubjectInfo))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
SIPObject_ *pSubjectObj;
if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
if (!(pSubjectObj))
{
return(FALSE);
}
//
// if we are a catalog member, set the version number to whatever
// was set when the catalog file was created...
//
if ((WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwUnionChoice)) &&
(pSubjectInfo->dwUnionChoice == MSSIP_ADDINFO_CATMEMBER) &&
(pSubjectInfo->psCatMember))
{
if (pSubjectInfo->psCatMember->cbStruct == sizeof(MS_ADDINFO_CATALOGMEMBER))
{
if ((pSubjectInfo->psCatMember->pMember) &&
(pSubjectInfo->psCatMember->pMember->cbStruct == sizeof(CRYPTCATMEMBER)))
{
pSubjectInfo->dwIntVersion = pSubjectInfo->psCatMember->pMember->dwCertVersion;
}
}
}
pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
if (pSubjectObj->get_CertVersion() < WIN_CERT_REVISION_2_0)
{
DWORD dwCAPIFlags;
CryptSIPGetRegWorkingFlags(&dwCAPIFlags);
if (dwCAPIFlags & WTPF_VERIFY_V1_OFF)
{
delete pSubjectObj;
SetLastError((DWORD)CRYPT_E_SECURITY_SETTINGS);
return(FALSE);
}
}
BOOL bRet;
bRet = pSubjectObj->VerifyIndirectData(pSubjectInfo, psData);
delete pSubjectObj;
return(bRet);
}
//////////////////////////////////////////////////////////////////////////////////////
//
// internal utility functions
//------------------------------------------------------------------------------------
//
SIPObject_ *mssip_CreateSubjectObject(const GUID *chk)
{
UINT idx;
SIPObject_ *pSO;
pSO = NULL;
idx = 0;
while (SubjectsID[idx] != MSSIP_ID_NONE)
{
if (SubjectsGuid[idx] == *chk)
{
switch (SubjectsID[idx])
{
case MSSIP_ID_PE:
pSO = (SIPObject_ *)new SIPObjectPE_(SubjectsID[idx]);
break;
case MSSIP_ID_JAVA:
pSO = (SIPObject_ *)new SIPObjectJAVA_(SubjectsID[idx]);
break;
case MSSIP_ID_CAB:
pSO = (SIPObject_ *)new SIPObjectCAB_(SubjectsID[idx]);
break;
case MSSIP_ID_FLAT:
pSO = (SIPObject_ *)new SIPObjectFlat_(SubjectsID[idx]);
break;
case MSSIP_ID_CTL: // currently, the same logic as catalog files!
case MSSIP_ID_CATALOG:
pSO = (SIPObject_ *)new SIPObjectCatalog_(SubjectsID[idx]);
break;
/* case MSSIP_ID_SS:
pSO = (SIPObject_ *)new SIPObjectSS_(SubjectsID[idx]);
break; */
case MSSIP_V1ID_PE:
case MSSIP_V1ID_PE_EX:
default:
SetLastError((DWORD)TRUST_E_SUBJECT_FORM_UNKNOWN);
return(NULL);
}
if (!(pSO))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
break;
}
idx++;
}
if (!(pSO))
{
SetLastError((DWORD)TRUST_E_SUBJECT_FORM_UNKNOWN);
}
return(pSO);
}
BOOL WINAPI DigestFileData( IN HSPCDIGESTDATA hDigestData,
IN const BYTE *pbData,
IN DWORD cbData)
{
BOOL fRet;
PDIGEST_DATA pDigestData;
fRet = TRUE;
pDigestData = (PDIGEST_DATA)hDigestData;
if (cbData > HASH_CACHE_LEN)
{
if (pDigestData->cbCache > 0)
{
fRet = SipHashData(pDigestData, pDigestData->pbCache, pDigestData->cbCache);
pDigestData->cbCache = 0;
if (!(fRet))
{
return(FALSE);
}
}
fRet = SipHashData(pDigestData, (BYTE *)pbData, cbData);
}
else
{
while (cbData > 0)
{
DWORD cbCopy;
cbCopy = min(HASH_CACHE_LEN - pDigestData->cbCache, cbData);
memcpy(&pDigestData->pbCache[pDigestData->cbCache], pbData,
cbCopy);
cbData -= cbCopy;
pbData += cbCopy;
pDigestData->cbCache += cbCopy;
if (pDigestData->cbCache == HASH_CACHE_LEN)
{
pDigestData->cbCache = 0;
if (!(fRet = SipHashData(pDigestData, pDigestData->pbCache, HASH_CACHE_LEN)))
{
break;
}
}
}
}
return(fRet);
}
BOOL SipCreateHash(HCRYPTPROV hProv, DIGEST_DATA *psDigestData)
{
BOOL fRet;
fRet = TRUE;
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
MD5Init((MD5_CTX *)psDigestData->pvSHA1orMD5Ctx);
break;
case CALG_SHA1:
A_SHAInit((A_SHA_CTX *)psDigestData->pvSHA1orMD5Ctx);
break;
default:
if (!(hProv))
{
hProv = I_CryptGetDefaultCryptProv(0); // get the default and DONT RELEASE IT!!!!
}
fRet = CryptCreateHash(hProv, psDigestData->dwAlgId, NULL, 0, &psDigestData->hHash);
break;
}
return(fRet);
}
BOOL SipHashData(DIGEST_DATA *psDigestData, BYTE *pbData, DWORD cbData)
{
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
MD5Update((MD5_CTX *)psDigestData->pvSHA1orMD5Ctx, pbData, cbData);
return(TRUE);
case CALG_SHA1:
A_SHAUpdate((A_SHA_CTX *)psDigestData->pvSHA1orMD5Ctx, pbData, cbData);
return(TRUE);
}
return(CryptHashData(psDigestData->hHash, pbData, cbData, 0));
}
BYTE *SipGetHashValue(DIGEST_DATA *psDigestData, DWORD *pcbHash)
{
BYTE *pbRet;
pbRet = NULL;
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
*pcbHash = MD5DIGESTLEN;
break;
case CALG_SHA1:
*pcbHash = A_SHA_DIGEST_LEN;
break;
default:
*pcbHash = 0;
CryptGetHashParam(psDigestData->hHash, HP_HASHVAL, NULL, pcbHash,0);
}
if (*pcbHash < 1)
{
goto HashLengthError;
}
if (!(pbRet = new BYTE[*pcbHash]))
{
goto MemoryError;
}
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
MD5_CTX *pMD5;
pMD5 = (MD5_CTX *)psDigestData->pvSHA1orMD5Ctx;
MD5Final(pMD5);
memcpy(pbRet, pMD5->digest, MD5DIGESTLEN);
psDigestData->pvSHA1orMD5Ctx = NULL;
break;
case CALG_SHA1:
A_SHAFinal((A_SHA_CTX *)psDigestData->pvSHA1orMD5Ctx, pbRet);
psDigestData->pvSHA1orMD5Ctx = NULL;
break;
default:
if (CryptGetHashParam(psDigestData->hHash, HP_HASHVAL, pbRet, pcbHash, 0))
{
goto HashParamError;
}
break;
}
CommonReturn:
return(pbRet);
ErrorReturn:
DELETE_OBJECT(pbRet);
goto CommonReturn;
SET_ERROR_VAR_EX(DBG_SS, MemoryError, ERROR_NOT_ENOUGH_MEMORY);
SET_ERROR_VAR_EX(DBG_SS, HashLengthError, GetLastError());
SET_ERROR_VAR_EX(DBG_SS, HashParamError, GetLastError());
}
void SipDestroyHash(DIGEST_DATA *psDigestData)
{
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
if (psDigestData->pvSHA1orMD5Ctx)
{
MD5Final((MD5_CTX *)psDigestData->pvSHA1orMD5Ctx);
}
break;
case CALG_SHA1:
if (psDigestData->pvSHA1orMD5Ctx)
{
BYTE bRet[A_SHA_DIGEST_LEN];
A_SHAFinal((A_SHA_CTX *)psDigestData->pvSHA1orMD5Ctx, &bRet[0]);
}
break;
default:
CryptDestroyHash(psDigestData->hHash);
break;
}
}
//////////////////////////////////////////////////////////////////////////////////////
//
// standard DLL exports ...
//------------------------------------------------------------------------------------
//
BOOL WINAPI mssip32DllMain(HANDLE hInstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
return(TRUE);
}
STDAPI mssip32DllRegisterServer(void)
{
BOOL fRet;
GUID gFlat = CRYPT_SUBJTYPE_FLAT_IMAGE;
GUID gPe = CRYPT_SUBJTYPE_PE_IMAGE;
GUID gCb = CRYPT_SUBJTYPE_CABINET_IMAGE;
GUID gJv = CRYPT_SUBJTYPE_JAVACLASS_IMAGE;
GUID gCat = CRYPT_SUBJTYPE_CATALOG_IMAGE;
GUID gCTL = CRYPT_SUBJTYPE_CTL_IMAGE;
GUID gSS = CRYPT_SUBJTYPE_SS_IMAGE;
SIP_ADD_NEWPROVIDER sProv;
fRet = TRUE;
memset(&sProv, 0x00, sizeof(SIP_ADD_NEWPROVIDER));
sProv.cbStruct = sizeof(SIP_ADD_NEWPROVIDER);
sProv.pwszDLLFileName = MY_NAME;
sProv.pwszGetFuncName = L"CryptSIPGetSignedDataMsg";
sProv.pwszPutFuncName = L"CryptSIPPutSignedDataMsg";
sProv.pwszCreateFuncName = L"CryptSIPCreateIndirectData";
sProv.pwszVerifyFuncName = L"CryptSIPVerifyIndirectData";
sProv.pwszRemoveFuncName = L"CryptSIPRemoveSignedDataMsg";
sProv.pgSubject = &gFlat;
fRet &= CryptSIPAddProvider(&sProv);
sProv.pgSubject = &gCb;
sProv.pwszMagicNumber = L"MSCF";
fRet &= CryptSIPAddProvider(&sProv);
sProv.pgSubject = &gPe;
sProv.pwszMagicNumber = L"0x00004550";
fRet &= CryptSIPAddProvider(&sProv);
sProv.pgSubject = &gJv;
sProv.pwszMagicNumber = L"0xcafebabe";
fRet &= CryptSIPAddProvider(&sProv);
sProv.pgSubject = &gCat;
fRet &= CryptSIPAddProvider(&sProv);
sProv.pgSubject = &gCTL;
fRet &= CryptSIPAddProvider(&sProv);
//
// structured storage is last becuase it
// has an "is" function...
//
/* sProv.pgSubject = &gSS;
sProv.pwszIsFunctionNameFmt2 = L"IsStructuredStorageFile";
fRet &= CryptSIPAddProvider(&sProv); */
CryptSIPRemoveProvider(&gSS);
return(fRet ? S_OK : S_FALSE);
}
STDAPI mssip32DllUnregisterServer(void)
{
GUID gFlat = CRYPT_SUBJTYPE_FLAT_IMAGE;
GUID gPe = CRYPT_SUBJTYPE_PE_IMAGE;
GUID gCb = CRYPT_SUBJTYPE_CABINET_IMAGE;
GUID gJv = CRYPT_SUBJTYPE_JAVACLASS_IMAGE;
GUID gCat = CRYPT_SUBJTYPE_CATALOG_IMAGE;
GUID gCTL = CRYPT_SUBJTYPE_CTL_IMAGE;
GUID gSS = CRYPT_SUBJTYPE_SS_IMAGE;
CryptSIPRemoveProvider(&gFlat);
CryptSIPRemoveProvider(&gPe);
CryptSIPRemoveProvider(&gCb);
CryptSIPRemoveProvider(&gJv);
CryptSIPRemoveProvider(&gCat);
CryptSIPRemoveProvider(&gCTL);
CryptSIPRemoveProvider(&gSS);
return(S_OK);
}
void CryptSIPGetRegWorkingFlags(DWORD *pdwState)
{
WintrustGetRegPolicyFlags(pdwState);
}
//
// support for Auth2 release
//
typedef struct _SIP_INFORMATION
{
DWORD cbSize; // sizeof(SIP_INFORMATION)
DWORD cgSubjects; // number of guids in array
const GUID *pgSubjects; // array of supported guids/subjects
} SIP_INFORMATION, *PSIP_INFORMATION;
BOOL CryptSIPGetInfo(IN OUT SIP_INFORMATION *pSIPInit)
{
UINT i;
i = 0;
pSIPInit->cbSize = sizeof(SIP_INFORMATION);
while (SubjectsID[i] != MSSIP_ID_NONE)
{
i++;
}
pSIPInit->cgSubjects = i;
pSIPInit->pgSubjects = &SubjectsGuid[0];
return(TRUE);
}