1204 lines
29 KiB
C++
1204 lines
29 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows NT Security
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1999
|
||
|
//
|
||
|
// File: iih.cpp
|
||
|
//
|
||
|
// Contents: ACUI Invoke Info Helper class implementation
|
||
|
//
|
||
|
// History: 10-May-97 kirtd Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
#include <stdpch.h>
|
||
|
|
||
|
#include "malloc.h"
|
||
|
#include "sgnerror.h"
|
||
|
//
|
||
|
// Personal trust database interface id
|
||
|
//
|
||
|
|
||
|
extern "C" const GUID IID_IPersonalTrustDB = IID_IPersonalTrustDB_Data;
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::CInvokeInfoHelper, public
|
||
|
//
|
||
|
// Synopsis: Constructor, initializes member variables from data found
|
||
|
// in the invoke info data structure
|
||
|
//
|
||
|
// Arguments: [pInvokeInfo] -- invoke info
|
||
|
// [rhr] -- result of construction
|
||
|
//
|
||
|
// Returns: (none)
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CInvokeInfoHelper::CInvokeInfoHelper (
|
||
|
PACUI_INVOKE_INFO pInvokeInfo,
|
||
|
HRESULT& rhr
|
||
|
)
|
||
|
: m_pInvokeInfo ( pInvokeInfo ),
|
||
|
m_pszSubject ( NULL ),
|
||
|
m_pszPublisher ( NULL ),
|
||
|
m_pszAdvancedLink ( NULL ),
|
||
|
m_pszControlWebPage ( NULL ),
|
||
|
m_pszCAWebPage ( NULL ),
|
||
|
m_pszPublisherCertIssuer ( NULL ),
|
||
|
m_pszErrorStatement ( NULL ),
|
||
|
m_pszCertTimestamp ( NULL ),
|
||
|
m_pszTestCertInChain ( NULL ),
|
||
|
m_fKnownPublisher ( FALSE ),
|
||
|
m_hModCVPA ( NULL ),
|
||
|
m_pfnCVPA ( NULL )
|
||
|
{
|
||
|
//
|
||
|
// Initialize the subject
|
||
|
//
|
||
|
|
||
|
rhr = InitSubject();
|
||
|
|
||
|
//
|
||
|
// if there's a test cert, format the text!
|
||
|
//
|
||
|
InitTestCertInChain();
|
||
|
|
||
|
//
|
||
|
// If we actually have a signature then ...
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// If we need an error statement, initialize it
|
||
|
//
|
||
|
|
||
|
if ( ( rhr == S_OK ) && ( pInvokeInfo->hrInvokeReason != S_OK ) )
|
||
|
{
|
||
|
rhr = InitErrorStatement();
|
||
|
}
|
||
|
|
||
|
if ( ( rhr == S_OK ) &&
|
||
|
( pInvokeInfo->hrInvokeReason != TRUST_E_NOSIGNATURE ) )
|
||
|
{
|
||
|
//
|
||
|
// Initialize the publisher
|
||
|
//
|
||
|
|
||
|
rhr = InitPublisher();
|
||
|
|
||
|
//
|
||
|
// If we have a known publisher, then we initialize the publisher
|
||
|
// cert issuer
|
||
|
//
|
||
|
|
||
|
if ( ( rhr == S_OK ) && ( m_fKnownPublisher == TRUE ) )
|
||
|
{
|
||
|
rhr = InitPublisherCertIssuer();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize the timestamp string
|
||
|
//
|
||
|
|
||
|
if ( rhr == S_OK )
|
||
|
{
|
||
|
rhr = InitCertTimestamp();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// initialize the "advanced link" text
|
||
|
//
|
||
|
InitAdvancedLink();
|
||
|
|
||
|
//
|
||
|
// initialize the Control's Web page link
|
||
|
//
|
||
|
InitControlWebPage();
|
||
|
|
||
|
//
|
||
|
// initialize the CA's Web page link
|
||
|
//
|
||
|
InitCAWebPage();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize the CertViewProperties entry point
|
||
|
//
|
||
|
|
||
|
if ( rhr == S_OK )
|
||
|
{
|
||
|
InitCertViewPropertiesEntryPoint();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::~CInvokeInfoHelper, public
|
||
|
//
|
||
|
// Synopsis: Destructor, frees up member variables
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: (none)
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CInvokeInfoHelper::~CInvokeInfoHelper ()
|
||
|
{
|
||
|
DELETE_OBJECT(m_pszSubject);
|
||
|
DELETE_OBJECT(m_pszPublisher);
|
||
|
DELETE_OBJECT(m_pszPublisherCertIssuer);
|
||
|
DELETE_OBJECT(m_pszAdvancedLink);
|
||
|
DELETE_OBJECT(m_pszControlWebPage);
|
||
|
DELETE_OBJECT(m_pszCAWebPage);
|
||
|
DELETE_OBJECT(m_pszTestCertInChain);
|
||
|
DELETE_OBJECT(m_pszCertTimestamp);
|
||
|
DELETE_OBJECT(m_pszErrorStatement);
|
||
|
|
||
|
if ( m_hModCVPA != NULL )
|
||
|
{
|
||
|
FreeLibrary(m_hModCVPA);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::AddPublisherToPersonalTrust, public
|
||
|
//
|
||
|
// Synopsis: adds the current publisher to the personal trust database
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: hr == S_OK, publisher added to personal trust database
|
||
|
// hr != S_OK, publisher NOT added to personal trust database
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::AddPublisherToPersonalTrust ()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
IPersonalTrustDB* pTrustDB = NULL;
|
||
|
|
||
|
//
|
||
|
// Get the personal trust database interface
|
||
|
//
|
||
|
|
||
|
hr = m_pInvokeInfo->pPersonalTrustDB->QueryInterface(
|
||
|
IID_IPersonalTrustDB,
|
||
|
(LPVOID *)&pTrustDB
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Add the publisher cert to the database
|
||
|
//
|
||
|
|
||
|
if ( hr == S_OK )
|
||
|
{
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_CERT *pCert;
|
||
|
|
||
|
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
|
||
|
{
|
||
|
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
|
||
|
{
|
||
|
hr = pTrustDB->AddTrustCert(
|
||
|
pCert->pCert,
|
||
|
0,
|
||
|
FALSE
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pTrustDB->Release();
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::GetUIControl, public
|
||
|
//
|
||
|
// Synopsis: gets the UI control
|
||
|
//
|
||
|
// Arguments: [ppUI] -- UI returned here
|
||
|
//
|
||
|
// Returns: S_OK for success, any other valid HRESULT otherwise
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::GetUIControl (IACUIControl** ppUI)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
IACUIControl* pUI = NULL;
|
||
|
|
||
|
//
|
||
|
// Get the right UI control
|
||
|
//
|
||
|
|
||
|
switch (m_pInvokeInfo->hrInvokeReason)
|
||
|
{
|
||
|
case S_OK:
|
||
|
pUI = new CVerifiedTrustUI(*this, hr);
|
||
|
break;
|
||
|
|
||
|
case CERT_E_EXPIRED:
|
||
|
case CERT_E_PURPOSE:
|
||
|
case CERT_E_WRONG_USAGE:
|
||
|
case CERT_E_CN_NO_MATCH:
|
||
|
case CERT_E_INVALID_NAME:
|
||
|
case CERT_E_INVALID_POLICY:
|
||
|
case CERT_E_REVOCATION_FAILURE:
|
||
|
case CRYPT_E_NO_REVOCATION_CHECK:
|
||
|
case CRYPT_E_REVOCATION_OFFLINE:
|
||
|
pUI = new CUnverifiedTrustUI(*this, hr);
|
||
|
break;
|
||
|
#if (0)
|
||
|
case CRYPT_E_FILE_ERROR:
|
||
|
case TRUST_E_PROVIDER_UNKNOWN:
|
||
|
case TRUST_E_SUBJECT_FORM_UNKNOWN:
|
||
|
case TRUST_E_NOSIGNATURE:
|
||
|
case CERT_E_CHAINING:
|
||
|
case CERT_E_UNTRUSTEDROOT:
|
||
|
case CERT_E_UNTRUSTEDTESTROOT:
|
||
|
#endif
|
||
|
default:
|
||
|
pUI = new CNoSignatureUI(*this, hr);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the out parameter and return value
|
||
|
//
|
||
|
|
||
|
if ( ( pUI != NULL ) && ( hr == S_OK ) )
|
||
|
{
|
||
|
*ppUI = pUI;
|
||
|
}
|
||
|
else if ( pUI == NULL )
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete pUI;
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::ReleaseUIControl, public
|
||
|
//
|
||
|
// Synopsis: frees the UI control
|
||
|
//
|
||
|
// Arguments: [pUI] -- UI control
|
||
|
//
|
||
|
// Returns: (none)
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CInvokeInfoHelper::ReleaseUIControl (IACUIControl* pUI)
|
||
|
{
|
||
|
delete pUI;
|
||
|
}
|
||
|
|
||
|
VOID CInvokeInfoHelper::InitControlWebPage ()
|
||
|
{
|
||
|
WCHAR *pwsz;
|
||
|
|
||
|
if (!(m_pInvokeInfo->pOpusInfo))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (!(m_pInvokeInfo->pOpusInfo->pMoreInfo))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pwsz = GetGoLink(m_pInvokeInfo->pOpusInfo->pMoreInfo);
|
||
|
|
||
|
if (!(pwsz))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_pszControlWebPage = new WCHAR[wcslen(pwsz) + 1];
|
||
|
|
||
|
if (m_pszControlWebPage != NULL)
|
||
|
{
|
||
|
wcscpy(m_pszControlWebPage, pwsz);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID CInvokeInfoHelper::InitCAWebPage ()
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// until IE submits.... don't do it!
|
||
|
//
|
||
|
|
||
|
return;
|
||
|
|
||
|
|
||
|
WCHAR *pwsz;
|
||
|
DWORD cb;
|
||
|
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_CERT *pCert;
|
||
|
SPC_SP_AGENCY_INFO *pAgencyInfo;
|
||
|
|
||
|
if (!(pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0)))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (!(pCert = WTHelperGetProvCertFromChain(pSgnr, 0))) // try the publisher's cert first!
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cb = 0;
|
||
|
WTHelperGetAgencyInfo(pCert->pCert, &cb, NULL);
|
||
|
|
||
|
if (cb < 1)
|
||
|
{
|
||
|
if (!(pCert = WTHelperGetProvCertFromChain(pSgnr, 1))) // try the issuer's next
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cb = 0;
|
||
|
WTHelperGetAgencyInfo(pCert->pCert, &cb, NULL);
|
||
|
|
||
|
if (cb < 1)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!(pAgencyInfo = (SPC_SP_AGENCY_INFO *)new BYTE[cb]))
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!(WTHelperGetAgencyInfo(pCert->pCert, &cb, pAgencyInfo)))
|
||
|
{
|
||
|
delete pAgencyInfo;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pwsz = GetGoLink(pAgencyInfo->pPolicyInformation);
|
||
|
|
||
|
m_pszCAWebPage = new WCHAR[wcslen(pwsz) + 1];
|
||
|
|
||
|
if (m_pszCAWebPage != NULL)
|
||
|
{
|
||
|
wcscpy(m_pszCAWebPage, pwsz);
|
||
|
}
|
||
|
|
||
|
delete pAgencyInfo;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitSubject, private
|
||
|
//
|
||
|
// Synopsis: Initialize m_pszSubject
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: hr == S_OK, initialize succeeded
|
||
|
// hr != S_OK, initialize failed
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::InitSubject ()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
LPCWSTR pwszSubject = NULL;
|
||
|
|
||
|
//
|
||
|
// Find out what we will use as the subject name
|
||
|
//
|
||
|
|
||
|
if ( ( m_pInvokeInfo->pOpusInfo != NULL ) &&
|
||
|
( m_pInvokeInfo->pOpusInfo->pwszProgramName != NULL ) )
|
||
|
{
|
||
|
pwszSubject = m_pInvokeInfo->pOpusInfo->pwszProgramName;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pwszSubject = m_pInvokeInfo->pwcsAltDisplayName;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// At this point we must have a valid subject name
|
||
|
//
|
||
|
|
||
|
assert( pwszSubject != NULL );
|
||
|
|
||
|
//
|
||
|
// Fill in the subject member by converting the one we found from
|
||
|
// UNICODE to MBS
|
||
|
//
|
||
|
|
||
|
m_pszSubject = new WCHAR[wcslen(pwszSubject) + 1];
|
||
|
|
||
|
if ( m_pszSubject != NULL )
|
||
|
{
|
||
|
wcscpy(m_pszSubject, pwszSubject);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CInvokeInfoHelper::InitTestCertInChain ()
|
||
|
{
|
||
|
WCHAR szTestCertInChain[MAX_LOADSTRING_BUFFER + 1];
|
||
|
|
||
|
if (IsTestCertInPublisherChain())
|
||
|
{
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
IDS_TESTCERTINCHAIN,
|
||
|
szTestCertInChain,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_pszTestCertInChain = new WCHAR[wcslen(szTestCertInChain) + 1];
|
||
|
if (m_pszTestCertInChain != NULL)
|
||
|
{
|
||
|
wcscpy(m_pszTestCertInChain, szTestCertInChain);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CInvokeInfoHelper::InitAdvancedLink ()
|
||
|
{
|
||
|
ULONG cbAL;
|
||
|
|
||
|
if ((ProviderData()) &&
|
||
|
(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(CRYPT_PROVIDER_FUNCTIONS, ProviderData()->psPfns->cbStruct, psUIpfns)) &&
|
||
|
(ProviderData()->psPfns->psUIpfns) &&
|
||
|
(ProviderData()->psPfns->psUIpfns->psUIData) &&
|
||
|
(ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText))
|
||
|
{
|
||
|
m_pszAdvancedLink = new WCHAR[wcslen(ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText) + 1];
|
||
|
|
||
|
if (m_pszAdvancedLink != NULL)
|
||
|
{
|
||
|
wcscpy(m_pszAdvancedLink, ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitPublisher, private
|
||
|
//
|
||
|
// Synopsis: Initialize m_pszPublisher
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: hr == S_OK, initialize succeeded
|
||
|
// hr != S_OK, initialize failed
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::InitPublisher ()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
ULONG cchPublisher;
|
||
|
LPWSTR pwszPublisher = NULL;
|
||
|
WCHAR szPublisher[MAX_LOADSTRING_BUFFER];
|
||
|
|
||
|
//
|
||
|
// Load the unknown publisher string
|
||
|
//
|
||
|
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
IDS_UNKNOWNPUBLISHER,
|
||
|
szPublisher,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Since the publisher is the subject of the signer certificate, we try to
|
||
|
// find the publisher name in the common name extensions of that cert
|
||
|
//
|
||
|
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_CERT *pCert;
|
||
|
|
||
|
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
|
||
|
{
|
||
|
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
|
||
|
{
|
||
|
|
||
|
|
||
|
cchPublisher = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
|
||
|
|
||
|
if (cchPublisher > 1)
|
||
|
{
|
||
|
pwszPublisher = new WCHAR[cchPublisher];
|
||
|
if ( pwszPublisher == NULL )
|
||
|
{
|
||
|
return (E_OUTOFMEMORY);
|
||
|
}
|
||
|
cchPublisher = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
|
||
|
pwszPublisher, cchPublisher);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// If we still don't have a publisher, use the unknown publisher string
|
||
|
//
|
||
|
|
||
|
if ( pwszPublisher == NULL )
|
||
|
{
|
||
|
m_fKnownPublisher = FALSE;
|
||
|
cchPublisher = wcslen(szPublisher) + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_fKnownPublisher = TRUE;
|
||
|
cchPublisher = wcslen(pwszPublisher) + 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Fill in the publisher member by converting from UNICODE to MBS
|
||
|
// or by copying the unknown publisher string
|
||
|
//
|
||
|
|
||
|
m_pszPublisher = new WCHAR[cchPublisher];
|
||
|
|
||
|
if ( m_pszPublisher != NULL )
|
||
|
{
|
||
|
if ( m_fKnownPublisher == FALSE )
|
||
|
{
|
||
|
wcscpy(m_pszPublisher, szPublisher);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wcscpy(m_pszPublisher, pwszPublisher);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
if ( pwszPublisher != NULL )
|
||
|
{
|
||
|
delete[] pwszPublisher;
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitPublisherCertIssuer, private
|
||
|
//
|
||
|
// Synopsis: Initialize m_pszPublisherCertIssuer
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: hr == S_OK, initialize succeeded
|
||
|
// hr != S_OK, initialize failed
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::InitPublisherCertIssuer ()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
ULONG cchCertIssuer;
|
||
|
LPWSTR pwszCertIssuer = NULL;
|
||
|
WCHAR szCertIssuer[MAX_LOADSTRING_BUFFER];
|
||
|
BOOL fKnownCertIssuer;
|
||
|
|
||
|
//
|
||
|
// Load the unknown cert issuer string
|
||
|
//
|
||
|
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
IDS_UNKNOWNPUBLISHERCERTISSUER,
|
||
|
szCertIssuer,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Since the publisher cert issuer is the issuer of the signer certificate,
|
||
|
// we try to find the name in the RDN attributes of the cert issuer
|
||
|
//
|
||
|
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_CERT *pCert;
|
||
|
|
||
|
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
|
||
|
{
|
||
|
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
|
||
|
{
|
||
|
cchCertIssuer = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL,
|
||
|
NULL, 0);
|
||
|
|
||
|
if (cchCertIssuer > 1)
|
||
|
{
|
||
|
pwszCertIssuer = new WCHAR[cchCertIssuer];
|
||
|
if ( pwszCertIssuer == NULL)
|
||
|
{
|
||
|
return (E_OUTOFMEMORY);
|
||
|
}
|
||
|
cchCertIssuer = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL,
|
||
|
pwszCertIssuer, cchCertIssuer);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we still don't have a name, we set the unknown issuer string
|
||
|
//
|
||
|
|
||
|
if ( pwszCertIssuer == NULL )
|
||
|
{
|
||
|
fKnownCertIssuer = FALSE;
|
||
|
cchCertIssuer = wcslen(szCertIssuer) + 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fKnownCertIssuer = TRUE;
|
||
|
cchCertIssuer = wcslen(pwszCertIssuer) + 1;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Fill in the publisher cert issuer member by converting from UNICODE
|
||
|
// to MBS or by copying the unknown issuer string
|
||
|
//
|
||
|
|
||
|
m_pszPublisherCertIssuer = new WCHAR[cchCertIssuer];
|
||
|
|
||
|
if ( m_pszPublisherCertIssuer != NULL )
|
||
|
{
|
||
|
if ( fKnownCertIssuer == FALSE )
|
||
|
{
|
||
|
wcscpy(m_pszPublisherCertIssuer, szCertIssuer);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
wcscpy(m_pszPublisherCertIssuer, pwszCertIssuer);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
|
||
|
if ( pwszCertIssuer != NULL )
|
||
|
{
|
||
|
delete[] pwszCertIssuer;
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitErrorStatement, private
|
||
|
//
|
||
|
// Synopsis: Initialize m_pszErrorStatement
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: hr == S_OK, initialize succeeded
|
||
|
// hr != S_OK, initialize failed
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::InitErrorStatement ()
|
||
|
{
|
||
|
return( ACUIMapErrorToString(
|
||
|
m_pInvokeInfo->hrInvokeReason,
|
||
|
&m_pszErrorStatement
|
||
|
) );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitCertTimestamp, public
|
||
|
//
|
||
|
// Synopsis: initialize the certificate timestamp string
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT
|
||
|
CInvokeInfoHelper::InitCertTimestamp ()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
WCHAR szCertTimestamp[MAX_LOADSTRING_BUFFER];
|
||
|
FILETIME ftTimestamp;
|
||
|
SYSTEMTIME stTimestamp;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get the time stamp
|
||
|
//
|
||
|
|
||
|
// TBDTBD: change to a loop!!!! pberkman
|
||
|
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_SGNR *pTimeSgnr;
|
||
|
|
||
|
if ((pTimeSgnr =
|
||
|
WTHelperGetProvSignerFromChain(ProviderData(), 0, TRUE, 0)) &&
|
||
|
(pTimeSgnr->dwSignerType & SGNR_TYPE_TIMESTAMP) &&
|
||
|
(pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0)))
|
||
|
{
|
||
|
// convert UTC to local
|
||
|
FileTimeToLocalFileTime(&pSgnr->sftVerifyAsOf, &ftTimestamp);
|
||
|
|
||
|
// make it system format
|
||
|
FileTimeToSystemTime(&ftTimestamp, &stTimestamp);
|
||
|
|
||
|
m_pszCertTimestamp = GetFormattedCertTimestamp(&stTimestamp);
|
||
|
|
||
|
if ( m_pszCertTimestamp == NULL )
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pszCertTimestamp = NULL;
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::InitCertViewPropertiesEntryPoint, public
|
||
|
//
|
||
|
// Synopsis: initialize the cert view properties entry point
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// Returns: (none)
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CInvokeInfoHelper::InitCertViewPropertiesEntryPoint ()
|
||
|
{
|
||
|
m_hModCVPA = LoadLibraryA(CVP_DLL);
|
||
|
|
||
|
if ( m_hModCVPA != NULL )
|
||
|
{
|
||
|
m_pfnCVPA = (pfnCertViewProperties)GetProcAddress(m_hModCVPA, CVP_FUNC_NAME);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::GetFormattedCertTimestamp, public
|
||
|
//
|
||
|
// Synopsis: gets the formatted cert timestamp string which will be
|
||
|
// allocated using the new operator
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
LPWSTR
|
||
|
CInvokeInfoHelper::GetFormattedCertTimestamp (LPSYSTEMTIME pst)
|
||
|
{
|
||
|
LPWSTR psz;
|
||
|
int cDate;
|
||
|
int cTime;
|
||
|
|
||
|
if ( ( cDate = GetDateFormatU(
|
||
|
LOCALE_USER_DEFAULT,
|
||
|
DATE_SHORTDATE,
|
||
|
pst,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0
|
||
|
) ) == 0 )
|
||
|
{
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
cDate--;
|
||
|
|
||
|
if ( ( cTime = GetTimeFormatU(
|
||
|
LOCALE_USER_DEFAULT,
|
||
|
TIME_NOSECONDS,
|
||
|
pst,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
0
|
||
|
) ) == 0 )
|
||
|
{
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
cTime--;
|
||
|
|
||
|
psz = new WCHAR [ cDate + cTime + 2 ];
|
||
|
if ( psz == NULL )
|
||
|
{
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
if ( GetDateFormatU(
|
||
|
LOCALE_USER_DEFAULT,
|
||
|
DATE_SHORTDATE,
|
||
|
pst,
|
||
|
NULL,
|
||
|
psz,
|
||
|
cDate + 1
|
||
|
) == 0 )
|
||
|
{
|
||
|
delete[] psz;
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
psz[cDate] = L' ';
|
||
|
|
||
|
if ( GetTimeFormatU(
|
||
|
LOCALE_USER_DEFAULT,
|
||
|
TIME_NOSECONDS,
|
||
|
pst,
|
||
|
NULL,
|
||
|
&psz[cDate+1],
|
||
|
cTime + 1
|
||
|
) == 0 )
|
||
|
{
|
||
|
delete[] psz;
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
return( psz );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CInvokeInfoHelper::IsTestCertInChain, public
|
||
|
//
|
||
|
// Synopsis: is there a test cert in the publisher's chain
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
CInvokeInfoHelper::IsTestCertInPublisherChain ()
|
||
|
{
|
||
|
ULONG cCount;
|
||
|
|
||
|
CRYPT_PROVIDER_SGNR *pSgnr;
|
||
|
CRYPT_PROVIDER_CERT *pCert;
|
||
|
|
||
|
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
|
||
|
{
|
||
|
for (cCount = 0; cCount < pSgnr->csCertChain; cCount++)
|
||
|
{
|
||
|
if (pCert = WTHelperGetProvCertFromChain(pSgnr, cCount))
|
||
|
{
|
||
|
if (pCert->fTestCert)
|
||
|
{
|
||
|
return(TRUE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ACUIMapErrorToString
|
||
|
//
|
||
|
// Synopsis: maps error to string
|
||
|
//
|
||
|
// Arguments: [hr] -- error
|
||
|
// [ppsz] -- error string goes here
|
||
|
//
|
||
|
// Returns: S_OK if successful, any valid HRESULT otherwise
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HRESULT ACUIMapErrorToString (HRESULT hr, LPWSTR* ppsz)
|
||
|
{
|
||
|
UINT ResourceId = 0;
|
||
|
WCHAR psz[MAX_LOADSTRING_BUFFER];
|
||
|
|
||
|
//
|
||
|
// See if it maps to some non system error code
|
||
|
//
|
||
|
|
||
|
switch (hr)
|
||
|
{
|
||
|
|
||
|
case TRUST_E_SYSTEM_ERROR:
|
||
|
case ERROR_NOT_ENOUGH_MEMORY:
|
||
|
case ERROR_INVALID_PARAMETER:
|
||
|
//
|
||
|
// leave the resourceid zero... these will be mapped to
|
||
|
// IDS_SPC_UNKNOWN and the error code displayed.
|
||
|
//
|
||
|
break;
|
||
|
|
||
|
case CRYPT_E_FILE_ERROR:
|
||
|
ResourceId = IDS_FILE_NOT_FOUND;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_PROVIDER_UNKNOWN:
|
||
|
ResourceId = IDS_SPC_PROVIDER;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_SUBJECT_FORM_UNKNOWN:
|
||
|
ResourceId = IDS_SPC_SUBJECT;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_NOSIGNATURE:
|
||
|
ResourceId = IDS_SPC_NO_SIGNATURE;
|
||
|
break;
|
||
|
|
||
|
case CRYPT_E_BAD_MSG:
|
||
|
ResourceId = IDS_SPC_BAD_SIGNATURE;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_BAD_DIGEST:
|
||
|
ResourceId = IDS_SPC_BAD_FILE_DIGEST;
|
||
|
break;
|
||
|
|
||
|
case CRYPT_E_NO_SIGNER:
|
||
|
ResourceId = IDS_SPC_NO_VALID_SIGNER;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_NO_SIGNER_CERT:
|
||
|
ResourceId = IDS_SPC_SIGNER_CERT;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_COUNTER_SIGNER:
|
||
|
ResourceId = IDS_SPC_VALID_COUNTERSIGNER;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_EXPIRED:
|
||
|
ResourceId = IDS_SPC_CERT_EXPIRED;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_CERT_SIGNATURE:
|
||
|
ResourceId = IDS_SPC_CERT_SIGNATURE;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_CHAINING:
|
||
|
ResourceId = IDS_SPC_CHAINING;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_UNTRUSTEDROOT:
|
||
|
ResourceId = IDS_SPC_UNTRUSTED_ROOT;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_UNTRUSTEDTESTROOT:
|
||
|
ResourceId = IDS_SPC_UNTRUSTED_TEST_ROOT;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_VALIDITYPERIODNESTING:
|
||
|
ResourceId = IDS_SPC_INVALID_CERT_NESTING;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_PURPOSE:
|
||
|
ResourceId = IDS_SPC_INVALID_PURPOSE;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_BASIC_CONSTRAINTS:
|
||
|
ResourceId = IDS_SPC_INVALID_BASIC_CONSTRAINTS;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_FINANCIAL_CRITERIA:
|
||
|
ResourceId = IDS_SPC_INVALID_FINANCIAL;
|
||
|
break;
|
||
|
|
||
|
case TRUST_E_TIME_STAMP:
|
||
|
ResourceId = IDS_SPC_TIMESTAMP;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_REVOKED:
|
||
|
ResourceId = IDS_SPC_CERT_REVOKED;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_REVOCATION_FAILURE:
|
||
|
ResourceId = IDS_SPC_REVOCATION_ERROR;
|
||
|
break;
|
||
|
|
||
|
case CRYPT_E_SECURITY_SETTINGS:
|
||
|
ResourceId = IDS_SPC_SECURITY_SETTINGS;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_MALFORMED:
|
||
|
ResourceId = IDS_SPC_INVALID_EXTENSION;
|
||
|
break;
|
||
|
|
||
|
case CERT_E_WRONG_USAGE:
|
||
|
ResourceId = IDS_WRONG_USAGE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If it does, load the string out of our resource string tables and
|
||
|
// return that. Otherwise, try to format the message from the system
|
||
|
//
|
||
|
|
||
|
DWORD_PTR MessageArgument;
|
||
|
CHAR szError[13]; // for good luck
|
||
|
WCHAR wszError[13]; // for good luck
|
||
|
LPVOID pvMsg;
|
||
|
|
||
|
pvMsg = NULL;
|
||
|
|
||
|
if ( ResourceId != 0 )
|
||
|
{
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
ResourceId,
|
||
|
psz,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
|
||
|
*ppsz = new WCHAR[wcslen(psz) + 1];
|
||
|
|
||
|
if ( *ppsz != NULL )
|
||
|
{
|
||
|
wcscpy(*ppsz, psz);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return( E_OUTOFMEMORY );
|
||
|
}
|
||
|
}
|
||
|
else if ( ( hr >= 0x80093000 ) && ( hr <= 0x80093999 ) )
|
||
|
{
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
IDS_SPC_OSS_ERROR,
|
||
|
psz,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
|
||
|
sprintf(szError, "%lx", hr);
|
||
|
MultiByteToWideChar(0, 0, szError, -1, &wszError[0], 13);
|
||
|
MessageArgument = (DWORD_PTR)wszError;
|
||
|
|
||
|
if ( FormatMessageU(
|
||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_FROM_STRING |
|
||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
|
psz,
|
||
|
0,
|
||
|
0,
|
||
|
(LPWSTR)&pvMsg,
|
||
|
0,
|
||
|
(va_list *)&MessageArgument
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( FormatMessageU(
|
||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
||
|
NULL,
|
||
|
hr,
|
||
|
0,
|
||
|
(LPWSTR)&pvMsg,
|
||
|
0,
|
||
|
NULL
|
||
|
) == 0 )
|
||
|
{
|
||
|
if ( LoadStringU(
|
||
|
g_hModule,
|
||
|
IDS_SPC_UNKNOWN,
|
||
|
psz,
|
||
|
MAX_LOADSTRING_BUFFER
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
|
||
|
sprintf(szError, "%lx", hr);
|
||
|
MultiByteToWideChar(0, 0, szError, -1, &wszError[0], 13);
|
||
|
MessageArgument = (DWORD_PTR)wszError;
|
||
|
|
||
|
if ( FormatMessageU(
|
||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
|
FORMAT_MESSAGE_FROM_STRING |
|
||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
|
psz,
|
||
|
0,
|
||
|
0,
|
||
|
(LPWSTR)&pvMsg,
|
||
|
0,
|
||
|
(va_list *)&MessageArgument
|
||
|
) == 0 )
|
||
|
{
|
||
|
return( HRESULT_FROM_WIN32(GetLastError()) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pvMsg)
|
||
|
{
|
||
|
*ppsz = new WCHAR[wcslen((WCHAR *)pvMsg) + 1];
|
||
|
|
||
|
if (*ppsz)
|
||
|
{
|
||
|
wcscpy(*ppsz, (WCHAR *)pvMsg);
|
||
|
}
|
||
|
|
||
|
LocalFree(pvMsg);
|
||
|
}
|
||
|
|
||
|
return( S_OK );
|
||
|
}
|
||
|
|
||
|
|