NT4/private/windows/base/advapi/digsig/softpub/sip.cpp
2020-09-30 17:12:29 +02:00

1039 lines
30 KiB
C++

//
// sip.cpp
//
// Subject Interface Package interface to trust functionality
//
#include "stdpch.h"
#include "common.h"
///////////////////////////////////////////////////////////////////////
//
// When adding a new subject type, add a local for it below,
// bump SUPPORTED_SUBJECTS, and add a line of code to initialize
// the next element in the SubjectForms array in WinTrustSipInitialize
// below. Also update the mapping routines found below
//
#define SUPPORTED_SUBJECTS 6
const GUID guidSubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
const GUID guidSubjectJavaClass = WIN_TRUST_SUBJTYPE_JAVA_CLASS;
const GUID guidSubjectCabFile = WIN_TRUST_SUBJTYPE_CABINET;
const GUID guidSubjectPeImageEx = WIN_TRUST_SUBJTYPE_PE_IMAGEEX;
const GUID guidSubjectJavaClassEx = WIN_TRUST_SUBJTYPE_JAVA_CLASSEX;
const GUID guidSubjectCabFileEx = WIN_TRUST_SUBJTYPE_CABINETEX;
///////////////////////////////////////////////////////////////////////
//
// Structure describing an individual SIP.
//
// This structure is passed back to WinTrust from a Subject Interface Package
// initialization call.
//
//typedef struct _WINTRUST_SIP_INFO {
// DWORD dwRevision;
// LPWINTRUST_SIP_DISPATCH_TABLE lpServices;
// DWORD dwSubjectTypeCount;
// GUID * lpSubjectTypeArray;
//} WINTRUST_SIP_INFO, *LPWINTRUST_SIP_INFO;
//
///////////////////////////////////////////////////////////////////////
//
// Supporting routines
//
///////////////////////////////////////////////////////////////////////
ULONG SubjTypeFromSubjectGuid(const GUID* pguid)
//
// Map a subject type that we know about into its corresponding
// subject form small integer that we can switch on
//
{
if (*pguid == guidSubjectPeImage
|| *pguid == guidSubjectJavaClass
|| *pguid == guidSubjectCabFile)
return SUBJTYPE_FILE;
if (*pguid == guidSubjectPeImageEx
|| *pguid == guidSubjectJavaClassEx
|| *pguid == guidSubjectCabFileEx)
return SUBJTYPE_FILEANDDISPLAY;
return SUBJTYPE_NONE;
}
//////////////////////////////////////////////////////////////
#define NARROW(wsz,sz) \
int __cch = lstrlenW(wsz) + 1; \
int __cb = __cch * sizeof(WCHAR); \
LPSTR sz = (LPSTR)_alloca(__cb); \
if (sz) WideCharToMultiByte(CP_ACP,0,wsz,-1,sz,__cb,NULL,NULL)
//////////////////////////////////////////////////////////////
//
HANDLE OpenFile(LPCWSTR wszFile)
//
// Open a file in the appropriate permissions / mode for doing
// our SIP work thereon
//
{
NARROW(wszFile, sz);
if (sz)
{
HANDLE hFile = CreateFile( sz,
GENERIC_READ, // bugbug may use something more restricted.
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
return hFile;
}
else
return INVALID_HANDLE_VALUE;
}
//////////////////////////////////////////////////////////////
LPWSTR OrBarHack(LPWSTR wszFile)
//
// Answers the display name; modifies the argument to zero
// terminate the file name
//
{
LPWSTR wszDisplay = wszFile;
WCHAR* pwch = wszFile;
while ( *pwch != 0 && *pwch != '|' )
++pwch;
if (*pwch!= 0)
{
// file-name is followed by display-name
*pwch = 0;
wszDisplay = pwch+1;
}
return wszDisplay;
}
//////////////////////////////////////////////////////////////
HRESULT FileHandleFromSubject(
//
// Return a file handle for accessing the given subject
//
IN LPWIN_TRUST_SIP_SUBJECT lpSubject, // pointer to subject info
OUT HANDLE* phFile, // returned file handle
OUT BOOL* pfClose // whether caller should close it or not
)
{
HRESULT hr = S_OK;
*phFile = INVALID_HANDLE_VALUE;
*pfClose = FALSE;
switch (SubjTypeFromSubjectGuid(lpSubject->SubjectType))
{
case SUBJTYPE_FILE:
{
WIN_TRUST_SUBJECT_FILE* pformFile = (WIN_TRUST_SUBJECT_FILE*)lpSubject->Subject;
if (pformFile->hFile != INVALID_HANDLE_VALUE)
{
*phFile = pformFile->hFile;
*pfClose = FALSE;
}
else
{
//
// Accomodate the '|' file name / display name hack
//
int cch = lstrlenW(pformFile->lpPath) + 1;
int cb = cch * sizeof(WCHAR);
LPWSTR wszPath = (LPWSTR)_alloca(cb);
if (wszPath)
{
memcpy(wszPath, pformFile->lpPath, cb);
OrBarHack(wszPath);
*phFile = OpenFile(pformFile->lpPath);
*pfClose = TRUE;
if (*phFile == INVALID_HANDLE_VALUE)
hr = HError();
}
else
hr = E_OUTOFMEMORY;
}
}
break;
case SUBJTYPE_FILEANDDISPLAY:
{
WIN_TRUST_SUBJECT_FILE_AND_DISPLAY* pformFile = (WIN_TRUST_SUBJECT_FILE_AND_DISPLAY*)lpSubject->Subject;
if (pformFile->hFile != INVALID_HANDLE_VALUE)
{
*phFile = pformFile->hFile;
*pfClose = FALSE;
}
else
{
*phFile = OpenFile(pformFile->lpPath);
*pfClose = TRUE;
if (*phFile == INVALID_HANDLE_VALUE)
hr = HError();
}
}
break;
default:
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
return hr;
}
///////////////////////////////////////////////////////////////////////
HRESULT
GetCabSignerForSubject(
//
// Return a ISignable that does cabs for the given subjet
// REVIEW: In the future, we'd likely want to enhance this
// to allow for other than CAB files to be fetched
//
IN LPWIN_TRUST_SIP_SUBJECT lpSubject, // pointer to subject info
OUT ISignableDocument** ppSignable
)
{
HRESULT hr = S_OK;
ISignableDocument* pSignable = NULL;
if ((pdigsig->CreateCABSigner)(NULL, IID_ISignableDocument, (LPVOID*)&pSignable))
{
IPersistFile* pPerFile;
hr = pSignable->QueryInterface(IID_IPersistFile, (LPVOID*)&pPerFile);
if (hr == S_OK)
{
switch (SubjTypeFromSubjectGuid(lpSubject->SubjectType))
{
case SUBJTYPE_FILE:
{
WIN_TRUST_SUBJECT_FILE* pformFile = (WIN_TRUST_SUBJECT_FILE*)lpSubject->Subject;
//
// Accomodate the '|' file name / display name hack
//
int cch = lstrlenW(pformFile->lpPath) + 1;
int cb = cch * sizeof(WCHAR);
LPWSTR wszPath = (LPWSTR)_alloca(cb);
if (wszPath)
{
memcpy(wszPath, pformFile->lpPath, cb);
OrBarHack(wszPath);
//
// Do the load
//
hr = pPerFile->Load(wszPath, 0);
}
else
hr = E_OUTOFMEMORY;
}
break;
case SUBJTYPE_FILEANDDISPLAY:
{
WIN_TRUST_SUBJECT_FILE_AND_DISPLAY* pformFile = (WIN_TRUST_SUBJECT_FILE_AND_DISPLAY*)lpSubject->Subject;
//
// Do the load
//
hr = pPerFile->Load(pformFile->lpPath, 0);
}
break;
default:
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
pPerFile->Release();
}
if (hr != S_OK)
{
pSignable->Release();
pSignable = NULL;
}
}
else
hr = HError();
*ppSignable = pSignable;
return hr;
}
///////////////////////////////////////////////////////////////////////
//
// Validate the content info of a subject. ONLY validate the content
// info itself; do not then go on to validate the signature on the
// SignedData.
//
///////////////////////////////////////////////////////////////////////
BOOL
SubjectCheckContentInfo(
IN LPWIN_TRUST_SIP_SUBJECT lpSubject, // pointer to subject info
IN LPWIN_CERTIFICATE lpSignedData // PKCS #7 Signed Data
)
{
HRESULT hr = S_OK;
const GUID guidSubjectType = *lpSubject->SubjectType;
IPkcs7SignedData* pkcs7 = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fClose = FALSE;
//
// Initialize a PCKS#7 from the passed certificate
//
if ((pdigsig->CreatePkcs7SignedData)(NULL,IID_IPkcs7SignedData,(LPVOID*)&pkcs7))
{
IPersistMemBlob* pPerBlob;
hr = pkcs7->QueryInterface(IID_IPersistMemBlob, (LPVOID*)&pPerBlob);
if (hr==S_OK)
{
BLOB b;
b.cbSize = lpSignedData->dwLength - OFFSETOF(WIN_CERTIFICATE,bCertificate);
b.pBlobData = (BYTE*)&lpSignedData->bCertificate;
hr = pPerBlob->Load(&b);
pPerBlob->Release();
}
}
else
hr = HError();
//
// Check the content info
//
if (hr==S_OK)
{
if (guidSubjectType == guidSubjectPeImage || guidSubjectType == guidSubjectPeImageEx)
{
//
// PE Images
//
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
//
// Find out what part of the image file is actually signed and verify
// that in fact that matches
//
hr = pkcs7->VerifyImageFile(0, hFile, NULL, NULL, 0);
}
}
else if (guidSubjectType == guidSubjectJavaClass || guidSubjectType == guidSubjectJavaClassEx)
{
//
// Java files
//
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
hr = pkcs7->VerifyJavaClassFile(hFile, NULL, NULL, 0);
}
else if (guidSubjectType == guidSubjectCabFile || guidSubjectType == guidSubjectCabFileEx)
{
//
// CAB files
//
ISignableDocument* pSignable;
hr = GetCabSignerForSubject(lpSubject, &pSignable);
if (hr==S_OK)
{
hr = pkcs7->VerifySignableDocument(pSignable, NULL, 0);
pSignable->Release();
}
}
else
{
//
// Something we don't know
//
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
}
else
hr = HError();
//
// Clean up
//
if (pkcs7)
pkcs7->Release();
if (fClose)
CloseHandle(hFile);
SetLastError(hr);
return hr == S_OK;
}
///////////////////////////////////////////////////////////////////////
HRESULT SevenFromJavaFile(HANDLE hFile, IPkcs7SignedData** ppseven)
//
// Return the #7 inside this file, if any
//
{
HRESULT hr = S_OK;
IPkcs7SignedData* pseven = NULL;
if ((pdigsig->CreatePkcs7SignedData)(NULL, IID_IPkcs7SignedData, (LPVOID*)&pseven))
{
hr = pseven->LoadFromJavaClassFile(hFile, NULL);
}
else
hr = HError();
if (hr==S_OK)
*ppseven = pseven;
else
{
*ppseven = NULL;
if (pseven) pseven->Release();
}
return hr;
}
///////////////////////////////////////////////////////////////////////
//
// Enumerate the certificates in the subject
//
///////////////////////////////////////////////////////////////////////
BOOL
SubjectEnumCertificates(
IN LPWIN_TRUST_SIP_SUBJECT lpSubject, // pointer to subject info
IN DWORD dwTypeFilter, // 0 or WIN_CERT_TYPE_xxx
OUT LPDWORD lpCertificateCount,
IN OUT LPDWORD lpIndices, // Rcvs WIN_CERT_TYPE_
IN DWORD cIndicies
)
{
HRESULT hr = S_OK;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fClose = FALSE;
const GUID guidSubjectType = *lpSubject->SubjectType;
///////////////////////////////////////////////////////////////////
//
// PE Images
//
if (guidSubjectType == guidSubjectPeImage || guidSubjectType == guidSubjectPeImageEx)
{
ULONG cCertFound = 0;
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
int index = 0;
int iCert = 0;
do {
WIN_CERTIFICATE hdr;
if ((pimagehlp->ImageGetCertificateHeader)(hFile, iCert, &hdr))
{
if (dwTypeFilter == 0 || hdr.wCertificateType == dwTypeFilter)
{
cCertFound++;
if (cIndicies > 0)
{
lpIndices[index] = iCert;
index++;
cIndicies--;
}
}
}
else
break;
iCert++;
} while(TRUE);
}
*lpCertificateCount = cCertFound;
}
///////////////////////////////////////////////////////////////////
//
// Java class files
//
// Java class files either have zero or one certificates, and the
// one certificate, if present, is always a SignedData.
//
else if (guidSubjectType == guidSubjectJavaClass)
{
ULONG cCertFound = 0;
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
//
// SLOW.... wish we had a way to avoid the repeated loading...
//
IPkcs7SignedData* pseven;
hr = SevenFromJavaFile(hFile, &pseven);
if (hr==S_OK)
{
//
// There is a signature present
//
if (dwTypeFilter == 0 || dwTypeFilter == WIN_CERT_TYPE_PKCS_SIGNED_DATA)
{
cCertFound++;
if (cIndicies > 0)
{
lpIndices[0] = 0;
}
}
pseven->Release();
}
else
{
//
// Nothing there
//
hr = S_OK;
}
}
*lpCertificateCount = cCertFound;
}
///////////////////////////////////////////////////////////////////
//
// CAB files
//
// CAB files have zero or one certificates, just like Java files
//
else if (guidSubjectType == guidSubjectCabFile)
{
int cCertFound = 0;
ISignableDocument* pSignable = NULL;
hr = GetCabSignerForSubject(lpSubject, &pSignable);
if (hr==S_OK)
{
BLOB b;
hr = pSignable->LoadSignature(&b);
if (hr==S_OK)
{
//
// There is a signature present (it's ALWAYS a #7 for signables)
//
if (dwTypeFilter == 0 || dwTypeFilter == WIN_CERT_TYPE_PKCS_SIGNED_DATA)
{
cCertFound++;
if (cIndicies > 0)
{
lpIndices[0] = 0;
}
}
CoTaskMemFree(b.pBlobData);
}
else
{
//
// Nothing there
//
hr = S_OK;
}
pSignable->Release();
}
*lpCertificateCount = cCertFound;
}
///////////////////////////////////////////////////////////////////
//
// Unknown
//
else
{
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
if (fClose)
CloseHandle(hFile);
if (hr!=S_OK)
SetLastError(hr);
return hr == S_OK ? TRUE : FALSE;
}
///////////////////////////////////////////////////////////////////////
HRESULT WinCertHeaderFromBlob(BLOB& b, WORD wType, LPWIN_CERTIFICATE pCert)
//
// Fill in the header information of a to-be-constructed WIN_CERTIFICATE
//
{
ASSERT(pCert);
if (pCert)
{
ULONG cbNeeded = OFFSETOF(WIN_CERTIFICATE,bCertificate) + b.cbSize;
pCert->dwLength = cbNeeded;
pCert->wRevision = WIN_CERT_REVISION_1_0;
pCert->wCertificateType = wType;
return S_OK;
}
else
return E_INVALIDARG;
}
HRESULT WinCertFromBlob(BLOB& b, WORD wType, LPWIN_CERTIFICATE pCert, LPDWORD pcbNeeded)
//
// Return the BLOB as a WIN_CERTIFICATE, if there is enough room
//
{
HRESULT hr = S_OK;
ULONG cbNeeded = OFFSETOF(WIN_CERTIFICATE,bCertificate) + b.cbSize;
if (pCert && cbNeeded <= *pcbNeeded)
{
pCert->dwLength = cbNeeded;
pCert->wRevision = WIN_CERT_REVISION_1_0;
pCert->wCertificateType = wType;
memcpy(&pCert->bCertificate[0], b.pBlobData, b.cbSize);
}
else
hr = ERROR_INSUFFICIENT_BUFFER;
*pcbNeeded = cbNeeded;
return hr;
}
///////////////////////////////////////////////////////////////////////
//
// Get the nth certificate from the subject
//
///////////////////////////////////////////////////////////////////////
BOOL
SubjectGetCertificate(
IN LPWIN_TRUST_SIP_SUBJECT lpSubject,
IN DWORD iCert,
OUT LPWIN_CERTIFICATE pCert,
IN OUT LPDWORD pcbNeeded
)
{
HRESULT hr = S_OK;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fClose = FALSE;
const GUID guidSubjectType = *lpSubject->SubjectType;
///////////////////////////////////////////////////////////////////
//
// PE Images
//
if (guidSubjectType == guidSubjectPeImage || guidSubjectType == guidSubjectPeImageEx)
{
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
if ((pimagehlp->ImageGetCertificateData)(hFile, iCert, pCert, pcbNeeded))
{
}
else
hr = HError();
}
}
///////////////////////////////////////////////////////////////////
//
// Java class files
//
// Java class files either have zero or one certificates, and the
// one certificate, if present, is always a SignedData.
//
else if (guidSubjectType == guidSubjectJavaClass || guidSubjectType == guidSubjectJavaClassEx)
{
if (iCert != 0)
hr = E_INVALIDARG;
else
{
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
//
// SLOW.... wish we had a way to avoid the repeated loading...
//
IPkcs7SignedData* pseven;
hr = SevenFromJavaFile(hFile, &pseven);
if (hr==S_OK)
{
//
// A cert is there. Croft up a WINCERT
//
IPersistMemBlob* pPerMem;
hr = pseven->QueryInterface(IID_IPersistMemBlob, (LPVOID*)&pPerMem);
if (hr==S_OK)
{
BLOB b;
hr = pPerMem->Save(&b, FALSE);
if (hr==S_OK)
{
hr = WinCertFromBlob(b, WIN_CERT_TYPE_PKCS_SIGNED_DATA, pCert, pcbNeeded);
CoTaskMemFree(b.pBlobData);
}
pPerMem->Release();
}
pseven->Release();
}
else
{
//
// Nothing there
//
hr = E_INVALIDARG;
}
}
}
}
///////////////////////////////////////////////////////////////////
//
// CAB files
//
// CAB files have zero or one certificates, just like Java files
//
else if (guidSubjectType == guidSubjectCabFile || guidSubjectType == guidSubjectCabFileEx)
{
if (iCert != 0)
hr = E_INVALIDARG;
else
{
ISignableDocument* pSignable = NULL;
hr = GetCabSignerForSubject(lpSubject, &pSignable);
if (hr==S_OK)
{
BLOB b;
hr = pSignable->LoadSignature(&b);
if (hr==S_OK)
{
//
// There is a signature present (it's ALWAYS a #7 for signables)
//
hr = WinCertFromBlob(b, WIN_CERT_TYPE_PKCS_SIGNED_DATA, pCert, pcbNeeded);
CoTaskMemFree(b.pBlobData);
}
else
{
//
// Nothing there
//
hr = E_INVALIDARG;
}
pSignable->Release();
}
}
}
///////////////////////////////////////////////////////////////////
//
// Unknown
//
else
{
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
if (fClose)
CloseHandle(hFile);
if (hr!=S_OK)
SetLastError(hr);
return hr == S_OK ? TRUE : FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// Get the header of the nth certificate from the subject
//
///////////////////////////////////////////////////////////////////////
BOOL
SubjectGetCertHeader(
IN LPWIN_TRUST_SIP_SUBJECT lpSubject,
IN DWORD iCert,
OUT LPWIN_CERTIFICATE pCert
)
{
HRESULT hr = S_OK;
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fClose = FALSE;
const GUID guidSubjectType = *lpSubject->SubjectType;
///////////////////////////////////////////////////////////////////
//
// PE Images
//
if (guidSubjectType == guidSubjectPeImage || guidSubjectType == guidSubjectPeImageEx)
{
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
if ((pimagehlp->ImageGetCertificateHeader)(hFile, iCert, pCert))
{
}
else
hr = HError();
}
}
///////////////////////////////////////////////////////////////////
//
// Java class files
//
// Java class files either have zero or one certificates, and the
// one certificate, if present, is always a SignedData.
//
else if (guidSubjectType == guidSubjectJavaClass || guidSubjectType == guidSubjectJavaClassEx)
{
if (iCert != 0)
hr = E_INVALIDARG;
else
{
hr = FileHandleFromSubject(lpSubject, &hFile, &fClose);
if (hr==S_OK)
{
//
// SLOW.... wish we had a way to avoid the repeated loading...
//
IPkcs7SignedData* pseven;
hr = SevenFromJavaFile(hFile, &pseven);
if (hr==S_OK)
{
//
// A cert is there. Croft up a WINCERT header
//
IPersistMemBlob* pPerMem;
hr = pseven->QueryInterface(IID_IPersistMemBlob, (LPVOID*)&pPerMem);
if (hr==S_OK)
{
BLOB b;
hr = pPerMem->Save(&b, FALSE);
if (hr==S_OK)
{
hr = WinCertHeaderFromBlob(b, WIN_CERT_TYPE_PKCS_SIGNED_DATA, pCert);
CoTaskMemFree(b.pBlobData);
}
pPerMem->Release();
}
pseven->Release();
}
else
{
//
// Nothing there
//
hr = E_INVALIDARG;
}
}
}
}
///////////////////////////////////////////////////////////////////
//
// CAB files
//
// CAB files have zero or one certificates, just like Java files
//
else if (guidSubjectType == guidSubjectCabFile || guidSubjectType == guidSubjectCabFileEx)
{
if (iCert != 0)
hr = E_INVALIDARG;
else
{
ISignableDocument* pSignable = NULL;
hr = GetCabSignerForSubject(lpSubject, &pSignable);
if (hr==S_OK)
{
BLOB b;
hr = pSignable->LoadSignature(&b);
if (hr==S_OK)
{
//
// There is a signature present (it's ALWAYS a #7 for signables)
//
hr = WinCertHeaderFromBlob(b, WIN_CERT_TYPE_PKCS_SIGNED_DATA, pCert);
CoTaskMemFree(b.pBlobData);
}
else
{
//
// Nothing there
//
hr = E_INVALIDARG;
}
pSignable->Release();
}
}
}
///////////////////////////////////////////////////////////////////
//
// Unknown
//
else
{
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
}
if (fClose)
CloseHandle(hFile);
if (hr!=S_OK)
SetLastError(hr);
return hr == S_OK ? TRUE : FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// Get the name of the subject from the content info
//
// The purpose of this string is to show to the user as some
// human recognizable representation of the subject. The string
// is ONLY good for showing to the user.
//
///////////////////////////////////////////////////////////////////////
BOOL
SubjectGetName(
IN LPWIN_TRUST_SIP_SUBJECT lpSubject,
IN LPWIN_CERTIFICATE lpSignedData,
IN OUT LPWSTR wszBuffer,
IN OUT LPDWORD pcbNeeded
)
{
HRESULT hr = S_OK;
const GUID guidSubjectType = *lpSubject->SubjectType;
//
// For now, we only ever look in the subject form itself
// to get a display string. In the future, if the subject
// form doesn't have something reasonable, we might
// choose to look inside the #7 SignedData to see if
// it has something reasonable.
//
switch (SubjTypeFromSubjectGuid(&guidSubjectType))
{
case SUBJTYPE_FILE:
{
WIN_TRUST_SUBJECT_FILE* pformFile = (WIN_TRUST_SUBJECT_FILE*)lpSubject->Subject;
ULONG cch = lstrlenW(pformFile->lpPath) + 1;
ULONG cb = cch * sizeof(WCHAR);
LPWSTR wszPath = (LPWSTR)_alloca(cb);
if (wszPath)
{
memcpy(wszPath, pformFile->lpPath, cb);
LPWSTR wszDisplayName = OrBarHack(wszPath);
cch = lstrlenW(wszDisplayName) + 1;
cb = cch * sizeof(WCHAR);
if (wszBuffer && cb <= *pcbNeeded)
{
memcpy(wszBuffer, wszDisplayName, cb);
}
else
hr = ERROR_INSUFFICIENT_BUFFER;
*pcbNeeded = cb;
}
else
hr = E_OUTOFMEMORY;
}
break;
case SUBJTYPE_FILEANDDISPLAY:
{
WIN_TRUST_SUBJECT_FILE_AND_DISPLAY* pformFile = (WIN_TRUST_SUBJECT_FILE_AND_DISPLAY*)lpSubject->Subject;
ULONG cch = lstrlenW(pformFile->lpDisplayName) + 1;
ULONG cb = cch * sizeof(WCHAR);
if (wszBuffer && cb <= *pcbNeeded)
{
memcpy(wszBuffer, pformFile->lpDisplayName, cb);
}
else
hr = ERROR_INSUFFICIENT_BUFFER;
*pcbNeeded = cb;
}
break;
default:
hr = TRUST_E_SUBJECT_FORM_UNKNOWN;
break;
}
if (hr != S_OK)
SetLastError(hr);
return hr == S_OK ? TRUE : FALSE;
}
///////////////////////////////////////////////////////////////////////
//
// Initialization code
//
///////////////////////////////////////////////////////////////////////
WINTRUST_SIP_DISPATCH_TABLE rgpfnDispatchTable =
{
SubjectCheckContentInfo,
SubjectEnumCertificates,
SubjectGetCertificate,
SubjectGetCertHeader,
SubjectGetName
};
const GUID rgguidSubjectForms[] =
{
WIN_TRUST_SUBJTYPE_PE_IMAGE,
WIN_TRUST_SUBJTYPE_JAVA_CLASS,
WIN_TRUST_SUBJTYPE_CABINET,
WIN_TRUST_SUBJTYPE_PE_IMAGEEX,
WIN_TRUST_SUBJTYPE_JAVA_CLASSEX,
WIN_TRUST_SUBJTYPE_CABINETEX
};
const WINTRUST_SIP_INFO sipInfo =
{
1,
&rgpfnDispatchTable,
SUPPORTED_SUBJECTS,
(GUID*)&rgguidSubjectForms[0]
};
BOOL
WINAPI
WinTrustSipInitialize(
IN DWORD dwWinTrustRevision,
OUT LPWINTRUST_SIP_INFO *lpSipInfo
)
{
*lpSipInfo = (LPWINTRUST_SIP_INFO)&sipInfo;
return TRUE;
}