Leaked source code of windows server 2003
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.
 
 
 
 
 
 

351 lines
9.5 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
main.cpp
Abstract:
This file contains the client program for dealing with script signature.
Revision History:
Davide Massarenti (Dmassare) 04/11/2000
created
******************************************************************************/
#include "stdafx.h"
#include <iostream>
#include <string>
#include <list>
//////////////////////////////////////////////////////////////////////
static void Usage( int argc ,
LPCWSTR argv[] )
{
wprintf( L"Usage: %s <command> <parameters>\n\n", argv[0] );
wprintf( L"Available commands:\n\n" );
wprintf( L" CREATE <private key file> <public key file>\n" );
wprintf( L" SIGN <private key file> <file to sign> <signature file>\n" );
wprintf( L" VERIFY <public key file> <signed file> <signature file>\n" );
}
////////////////////////////////////////////////////////////////////////////////
static HRESULT LoadFile( /*[in ]*/ LPCWSTR szFile ,
/*[out]*/ HGLOBAL& hg )
{
__HCP_FUNC_ENTRY( "LoadFile" );
HRESULT hr;
CComPtr<IStream> streamMem;
CComPtr<MPC::FileStream> streamFile;
//
// Create a stream for a file.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamFile ));
__MPC_EXIT_IF_METHOD_FAILS(hr, streamFile->InitForRead( szFile ));
//
// Create a memory stream.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateStreamOnHGlobal( NULL, FALSE, &streamMem ));
//
// Load the contents in memory.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamFile, streamMem ));
__MPC_EXIT_IF_METHOD_FAILS(hr, ::GetHGlobalFromStream( streamMem, &hg ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT SaveFile( /*[in]*/ LPCWSTR szFile ,
/*[in]*/ HGLOBAL hg )
{
__HCP_FUNC_ENTRY( "SaveFile" );
HRESULT hr;
CComPtr<IStream> streamMem;
CComPtr<MPC::FileStream> streamFile;
//
// Create a stream for a file.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &streamFile ));
__MPC_EXIT_IF_METHOD_FAILS(hr, streamFile->InitForWrite( szFile ));
//
// Create a memory stream.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CreateStreamOnHGlobal( hg, FALSE, &streamMem ));
//
// Load the contents in memory.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::BaseStream::TransferData( streamMem, streamFile ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
static HRESULT LoadFileAsString( /*[in ]*/ LPCWSTR szFile ,
/*[out]*/ CComBSTR& bstrData )
{
__HCP_FUNC_ENTRY( "LoadFileAsString" );
HRESULT hr;
HGLOBAL hg = NULL;
DWORD dwLen;
LPWSTR str;
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile( szFile, hg ));
dwLen = ::GlobalSize( hg );
bstrData.Attach( ::SysAllocStringLen( NULL, dwLen ) );
::MultiByteToWideChar( CP_ACP, 0, (LPCSTR)::GlobalLock( hg ), dwLen, bstrData, (dwLen+1)*sizeof(WCHAR) ); bstrData[dwLen] = 0;
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hg) ::GlobalFree( hg );
__HCP_FUNC_EXIT(hr);
}
static HRESULT SaveFileAsString( /*[in]*/ LPCWSTR szFile ,
/*[in]*/ const CComBSTR& bstrData )
{
__HCP_FUNC_ENTRY( "SaveFileAsString" );
USES_CONVERSION;
HRESULT hr;
DWORD dwLen = ::SysStringLen( bstrData );
HGLOBAL hg = NULL;
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwLen )));
::CopyMemory( hg, W2A(bstrData), dwLen );
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveFile( szFile, hg ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hg) ::GlobalFree( hg );
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
static HRESULT Create( /*[in]*/ LPCWSTR szPrivateFile ,
/*[in]*/ LPCWSTR szPublicFile )
{
__HCP_FUNC_ENTRY( "Create" );
HRESULT hr;
CPCHCryptKeys key;
CComBSTR bstrPrivate;
CComBSTR bstrPublic;
__MPC_EXIT_IF_METHOD_FAILS(hr, key.CreatePair());
__MPC_EXIT_IF_METHOD_FAILS(hr, key.ExportPair( bstrPrivate, bstrPublic ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szPrivateFile, bstrPrivate ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szPublicFile , bstrPublic ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
static HRESULT Sign( /*[in]*/ LPCWSTR szPrivateFile ,
/*[in]*/ LPCWSTR szDataFile ,
/*[in]*/ LPCWSTR szSignatureFile )
{
__HCP_FUNC_ENTRY( "Sign" );
HRESULT hr;
CPCHCryptKeys key;
CComBSTR bstrPrivate;
CComBSTR bstrSignature;
HGLOBAL hg = NULL;
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szPrivateFile, bstrPrivate ));
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile ( szDataFile , hg ));
__MPC_EXIT_IF_METHOD_FAILS(hr, key.ImportPrivate( bstrPrivate ));
__MPC_EXIT_IF_METHOD_FAILS(hr, key.SignData( bstrSignature, (BYTE*)::GlobalLock( hg ), ::GlobalSize( hg ) ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveFileAsString( szSignatureFile, bstrSignature ));
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hg) ::GlobalFree( hg );
__HCP_FUNC_EXIT(hr);
}
static HRESULT Verify( /*[in]*/ LPCWSTR szPublicFile ,
/*[in]*/ LPCWSTR szDataFile ,
/*[in]*/ LPCWSTR szSignatureFile )
{
__HCP_FUNC_ENTRY( "Sign" );
HRESULT hr;
CPCHCryptKeys key;
CComBSTR bstrPublic;
CComBSTR bstrSignature;
HGLOBAL hg = NULL;
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szPublicFile , bstrPublic ));
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFileAsString( szSignatureFile, bstrSignature ));
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadFile ( szDataFile , hg ));
__MPC_EXIT_IF_METHOD_FAILS(hr, key.ImportPublic( bstrPublic ));
hr = key.VerifyData( bstrSignature, (BYTE*)::GlobalLock( hg ), ::GlobalSize( hg ) );
if(FAILED(hr))
{
wprintf( L"Verification failure: 0x%08x\n", hr );
}
else
{
wprintf( L"Verification successful: 0x%08x\n", hr );
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
if(hg) ::GlobalFree( hg );
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
static HRESULT ProcessArguments( int argc ,
LPCWSTR argv[] )
{
__HCP_FUNC_ENTRY( "ProcessArguments" );
HRESULT hr;
if(argc < 2) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
if(!_wcsicmp( argv[1], L"CREATE" ))
{
if(argc < 4) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
__MPC_EXIT_IF_METHOD_FAILS(hr, Create( argv[2], argv[3] ));
}
if(!_wcsicmp( argv[1], L"SIGN" ))
{
if(argc < 5) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
__MPC_EXIT_IF_METHOD_FAILS(hr, Sign( argv[2], argv[3], argv[4] ));
}
if(!_wcsicmp( argv[1], L"VERIFY" ))
{
if(argc < 5) { Usage( argc, argv ); __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL); }
__MPC_EXIT_IF_METHOD_FAILS(hr, Verify( argv[2], argv[3], argv[4] ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
int __cdecl wmain( int argc ,
LPCWSTR argv[] )
{
HRESULT hr;
//DebugBreak();
//
// We need to be a single-threaded application, because we are hosting script engines and
// script engines don't like to be called from different threads...
//
if(SUCCEEDED(hr = ::CoInitializeEx( NULL, COINIT_APARTMENTTHREADED )))
{
if(SUCCEEDED(hr = ::CoInitializeSecurity( NULL ,
-1 , // We don't care which authentication service we use.
NULL ,
NULL ,
RPC_C_AUTHN_LEVEL_CONNECT, // We want to identify the callers.
RPC_C_IMP_LEVEL_DELEGATE , // We want to be able to forward the caller's identity.
NULL ,
EOAC_DYNAMIC_CLOAKING , // Let's use the thread token for outbound calls.
NULL )))
{
__MPC_TRACE_INIT();
//
// Process arguments.
//
hr = ProcessArguments( argc, argv );
__MPC_TRACE_TERM();
}
::CoUninitialize();
}
return FAILED(hr) ? 10 : 0;
}