Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

545 lines
17 KiB

#define INITGUID
#include <windows.h>
#include <stdio.h>
#include <ole2.h>
#define USE_CAPI2
#if defined(USE_CAPI2)
#include <wincrypt.h>
#endif
#include "admex.h"
//
// HRESULTTOWIN32() maps an HRESULT to a Win32 error. If the facility code
// of the HRESULT is FACILITY_WIN32, then the code portion (i.e. the
// original Win32 error) is returned. Otherwise, the original HRESULT is
// returned unchagned.
//
#define HRESULTTOWIN32(hres) \
((HRESULT_FACILITY(hres) == FACILITY_WIN32) \
? HRESULT_CODE(hres) \
: (hres))
#define RETURNCODETOHRESULT(rc) \
(((rc) < 0x10000) \
? HRESULT_FROM_WIN32(rc) \
: (rc))
#define PAD4(a) (((a)+3)&~3)
VOID
DisplayErrorMessage(
DWORD dwErr,
DWORD dwMsg = 0
);
/////////////////////////////////////////////////////
VOID
DisplayErrorMessage(
DWORD dwErr,
DWORD dwMsg
)
{
LPSTR pErr;
CHAR achMsg[2048];
if ( dwMsg != 0 )
{
if ( LoadString( NULL, dwMsg, achMsg, sizeof(achMsg) ) )
{
printf( achMsg );
}
}
if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&pErr,
0,
NULL ) )
{
puts( pErr );
LocalFree( pErr );
}
}
VOID
Dump(
LPSTR pszMsg,
LPBYTE pb,
DWORD dw
)
{
printf( "%s size is %d\n", pszMsg, dw );
for ( UINT x = 0 ; x < dw ; ++x )
{
printf( "%02x ", pb[x] );
}
if ( dw )
{
printf( "\n" );
}
}
int __cdecl main( int argc, char*argv[] )
{
IMSAdminReplication* pIf;
IMSAdminCryptoCapabilities* pIfS;
IClassFactory* pcsfFactory = NULL;
int iA;
HRESULT hRes;
COSERVERINFO csiMachineName;
WCHAR awchComputer[64];
BYTE abBuf[32768];
DWORD dwReqSize;
MULTI_QI rgmq;
LPSTR pszMachineName = NULL;
int arg;
BOOL fDoTest = FALSE;
HKEY hKey;
CHAR achName[128];
DWORD dwNameLen;
DWORD dwValueLen;
DWORD dwType;
int iV, iV2;
LPBYTE pbSerial;
DWORD dwSerialLen, dwSerialLen2;
DWORD dwErr;
for ( arg = 1 ; arg < argc ; ++arg )
{
if ( argv[arg][0] == '-' )
{
switch ( argv[arg][1] )
{
case 'm':
pszMachineName = argv[arg]+2;
break;
case 't':
fDoTest = TRUE;
break;
}
}
}
if ( argc < 1 )
{
CHAR achMsg[2048];
if ( LoadString( NULL, 100, achMsg, sizeof(achMsg) ) )
{
printf( achMsg );
}
return 3;
}
//fill the structure for CoCreateInstanceEx
ZeroMemory( &csiMachineName, sizeof(csiMachineName) );
// csiMachineName.pAuthInfo = NULL;
// csiMachineName.dwFlags = 0;
// csiMachineName.pServerInfoExt = NULL;
if ( pszMachineName )
{
if ( !MultiByteToWideChar( CP_ACP,
MB_PRECOMPOSED,
pszMachineName,
-1,
awchComputer,
sizeof(awchComputer) ) )
{
return FALSE;
}
csiMachineName.pwszName = awchComputer;
}
else
{
csiMachineName.pwszName = NULL;
}
CoInitializeEx( NULL, COINIT_MULTITHREADED );
if ( fDoTest )
{
hRes = CoGetClassObject(CLSID_MSCryptoAdmEx, CLSCTX_SERVER, &csiMachineName,
IID_IClassFactory, (void**) &pcsfFactory);
if ( SUCCEEDED( hRes ) )
{
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminReplication, (void **) &rgmq.pItf);
if ( SUCCEEDED( hRes ) )
{
rgmq.pItf->Release();
}
else
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
pcsfFactory->Release();
}
else
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
//
// call replication I/F
//
rgmq.pIID = &IID_IMSAdminReplication;
rgmq.pItf = NULL;
rgmq.hr = 0;
if ( SUCCEEDED( hRes = CoCreateInstanceEx( CLSID_MSCryptoAdmEx,
NULL,
CLSCTX_SERVER,
&csiMachineName,
1,
&rgmq ) ) &&
SUCCEEDED( hRes = rgmq.hr ) )
{
pIf = (IMSAdminReplication*)rgmq.pItf;
hRes = pIf->GetSignature( sizeof(abBuf), abBuf, &dwReqSize );
if ( SUCCEEDED( hRes ) )
{
Dump( "GetSignature:", abBuf, dwReqSize );
hRes = pIf->Serialize( sizeof(abBuf), abBuf, &dwReqSize );
}
if ( SUCCEEDED( hRes ) )
{
Dump( "Serialize:", abBuf, dwReqSize );
hRes = pIf->DeSerialize( dwReqSize, abBuf );
}
pIf->Release();
if ( FAILED( hRes ) )
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
}
else
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
//
// call crypto capabilities I/F
//
rgmq.pIID = &IID_IMSAdminCryptoCapabilities;
rgmq.pItf = NULL;
rgmq.hr = 0;
if ( SUCCEEDED( hRes = CoCreateInstanceEx( CLSID_MSCryptoAdmEx,
NULL,
CLSCTX_SERVER,
&csiMachineName,
1,
&rgmq ) ) &&
SUCCEEDED( hRes = rgmq.hr ) )
{
pIfS = (IMSAdminCryptoCapabilities*)rgmq.pItf;
hRes = pIfS->GetProtocols( sizeof(abBuf), abBuf, &dwReqSize );
if ( SUCCEEDED(hRes) )
{
Dump( "Protocols:", abBuf, dwReqSize );
hRes = pIfS->GetSupportedAlgs( sizeof(abBuf), (LPDWORD)abBuf, &dwReqSize );
}
if ( SUCCEEDED(hRes) )
{
Dump( "Algs:", abBuf, dwReqSize );
hRes = pIfS->GetRootCertificates( sizeof(abBuf), abBuf, &dwReqSize );
}
if ( SUCCEEDED(hRes) )
{
Dump( "CAs:", abBuf, dwReqSize );
hRes = pIfS->GetMaximumCipherStrength( &dwReqSize );
}
if ( SUCCEEDED(hRes) )
{
Dump( "Cipher strength:", (LPBYTE)&dwReqSize, sizeof(DWORD) );
}
pIfS->Release();
if ( FAILED( hRes ) )
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
}
else
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
}
else
{
//
// Check full access to registry ( granted only to administrators )
//
if ( (dwErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\InetInfo\\Parameters",
0,
KEY_ALL_ACCESS,
&hKey )) == ERROR_SUCCESS )
{
RegCloseKey( hKey );
}
else
{
hRes = RETURNCODETOHRESULT( dwErr );
}
if ( SUCCEEDED( hRes ) )
{
hRes = CoGetClassObject(CLSID_MSCryptoAdmEx, CLSCTX_SERVER, &csiMachineName,
IID_IClassFactory, (void**) &pcsfFactory);
}
if ( SUCCEEDED( hRes ) )
{
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminCryptoCapabilities, (void **) &pIfS);
if ( FAILED( hRes ) )
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ) );
}
else
{
//
// get CA list
//
#if defined(USE_CAPI2)
HCERTSTORE hStore = NULL;
BOOL fReturn = FALSE;
PCCERT_CONTEXT pCtx;
hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
"ROOT" );
if ( hStore )
{
for ( pCtx = NULL, dwSerialLen = 0 ;
pCtx = CertEnumCertificatesInStore( hStore, pCtx ) ; )
{
// CertDeleteCertificateFromStore, CertAddSerializedElementToStore
dwValueLen = sizeof(abBuf);
if ( CertSerializeCertificateStoreElement( pCtx, 0, NULL, &dwValueLen ) )
{
dwSerialLen += sizeof(DWORD) + PAD4(dwValueLen);
}
else
{
hRes = RETURNCODETOHRESULT( GetLastError() );
break;
}
}
}
else
{
hRes = RETURNCODETOHRESULT( GetLastError() );
}
if ( SUCCEEDED( hRes ) )
{
if ( pbSerial = (LPBYTE)LocalAlloc( LMEM_FIXED, dwSerialLen ) )
{
for ( pCtx = NULL, dwSerialLen2 = 0 ;
pCtx = CertEnumCertificatesInStore( hStore, pCtx ) ; )
{
dwValueLen = dwSerialLen - dwSerialLen2 - sizeof(DWORD);
if ( CertSerializeCertificateStoreElement( pCtx, 0, pbSerial + dwSerialLen2 + sizeof(DWORD), &dwValueLen ) )
{
*(LPDWORD)(pbSerial+dwSerialLen2) = dwValueLen;
dwSerialLen2 += sizeof(DWORD) + PAD4(dwValueLen);
}
else
{
hRes = RETURNCODETOHRESULT( GetLastError() );
break;
}
}
if ( SUCCEEDED( hRes ) )
{
//
// call deserialize. This will be invoked in IIS SYSTEM context
//
hRes = pIfS->SetCAList( dwSerialLen2, pbSerial );
}
LocalFree( pbSerial );
}
else
{
hRes = E_OUTOFMEMORY;
}
}
if ( hStore )
{
CertCloseStore( hStore, CERT_CLOSE_STORE_FORCE_FLAG );
}
#else
if ( (dwErr = RegOpenKeyEx( HKEY_CURRENT_USER,
"Software\\Microsoft\\SystemCertificates\\ROOT\\Certificates",
0,
KEY_READ,
&hKey )) == ERROR_SUCCESS )
{
//
// compute length of serialized CA list
//
for ( iV = 0, dwSerialLen = 0 ; ; ++iV )
{
dwNameLen = sizeof( achName );
dwValueLen = sizeof(abBuf);
if ( RegEnumValue( hKey,
iV,
achName,
&dwNameLen,
NULL,
&dwType,
abBuf,
&dwValueLen ) != ERROR_SUCCESS )
{
break;
}
++dwNameLen;
dwSerialLen += sizeof(DWORD) + PAD4(dwNameLen) + sizeof(DWORD) + PAD4(dwValueLen);
}
if ( pbSerial = (LPBYTE)LocalAlloc( LMEM_FIXED, dwSerialLen ) )
{
//
// build serialized list
//
for ( iV2 = 0, dwSerialLen2 = 0 ;; ++iV2 )
{
dwNameLen = sizeof( achName );
dwValueLen = sizeof(abBuf);
if ( RegEnumValue( hKey,
iV2,
achName,
&dwNameLen,
NULL,
&dwType,
abBuf,
&dwValueLen ) != ERROR_SUCCESS )
{
break;
}
++dwNameLen;
if ( iV2 == iV ||
dwSerialLen2 + sizeof(DWORD) + PAD4(dwNameLen) + sizeof(DWORD) + PAD4(dwValueLen) > dwSerialLen )
{
hRes = E_OUTOFMEMORY;
break;
}
// each element ( name or content ) is stored prefixed by
// a DWORD length. element actual storage is padded
// so that length is multiple of 4, to make sure following
// DWORDs are DWORD aligned.
// store value name ( includes zero byte delimiter )
*(LPDWORD)(pbSerial+dwSerialLen2) = dwNameLen;
dwSerialLen2 += sizeof(DWORD);
memcpy( pbSerial+dwSerialLen2, achName, dwNameLen );
dwSerialLen2 += PAD4(dwNameLen);
// store value content
*(LPDWORD)(pbSerial+dwSerialLen2) = dwValueLen;
dwSerialLen2 += sizeof(DWORD);
memcpy( pbSerial+dwSerialLen2, abBuf, dwValueLen );
dwSerialLen2 += PAD4(dwValueLen);
}
if ( SUCCEEDED( hRes ) )
{
//
// call deserialize. This will be invoked in IIS SYSTEM context
//
hRes = pIfS->SetCAList( dwSerialLen2, pbSerial );
}
LocalFree( pbSerial );
}
else
{
hRes = E_OUTOFMEMORY;
}
RegCloseKey( hKey );
}
else
{
hRes = RETURNCODETOHRESULT( dwErr );
}
#endif
if ( FAILED(hRes) )
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ), 102 );
}
else
{
CHAR achMsg[2048];
if ( LoadString( NULL, 101, achMsg, sizeof(achMsg) ) )
{
printf( achMsg );
}
}
pIfS->Release();
}
pcsfFactory->Release();
}
else
{
DisplayErrorMessage( HRESULTTOWIN32( hRes ), 102 );
}
}
CoUninitialize();
return SUCCEEDED(hRes) ? 0 : 1;
}