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.
312 lines
7.7 KiB
312 lines
7.7 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
KeysLib.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the CPCHCryptKeys class,
|
|
that is uses to sign and verify trusted scripts.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 04/11/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CPCHCryptKeys::CPCHCryptKeys()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::CPCHCryptKeys" );
|
|
|
|
m_hCryptProv = NULL; // HCRYPTPROV m_hCryptProv;
|
|
m_hKey = NULL; // HCRYPTKEY m_hKey;
|
|
}
|
|
|
|
CPCHCryptKeys::~CPCHCryptKeys()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::~CPCHCryptKeys" );
|
|
|
|
Close();
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::Close()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::Close" );
|
|
|
|
if(m_hKey)
|
|
{
|
|
::CryptDestroyKey( m_hKey ); m_hKey = NULL;
|
|
}
|
|
|
|
if(m_hCryptProv)
|
|
{
|
|
::CryptReleaseContext( m_hCryptProv, 0 ); m_hCryptProv = NULL;
|
|
}
|
|
|
|
__HCP_FUNC_EXIT(S_OK);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::Init()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::Init" );
|
|
|
|
HRESULT hr;
|
|
|
|
Close();
|
|
|
|
if(!::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT ))
|
|
{
|
|
DWORD dwRes = ::GetLastError();
|
|
|
|
if(dwRes != NTE_BAD_KEYSET)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
|
|
}
|
|
|
|
//
|
|
// Key set doesn't exist, let's create one.
|
|
//
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
if(FAILED(hr)) Close();
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHCryptKeys::CreatePair()
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::CreatePair" );
|
|
|
|
HRESULT hr;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, Init());
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptGenKey( m_hCryptProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &m_hKey ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::ExportPair( /*[out]*/ CComBSTR& bstrPrivate ,
|
|
/*[out]*/ CComBSTR& bstrPublic )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::ExportPair" );
|
|
|
|
HRESULT hr;
|
|
DWORD dwSize;
|
|
HGLOBAL hg = NULL;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(m_hKey);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
////////////////////////////////////////
|
|
//
|
|
// Export private/public pair.
|
|
//
|
|
dwSize = 0;
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwSize ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PRIVATEKEYBLOB, 0, (BYTE*)hg, &dwSize ));
|
|
|
|
//
|
|
// Convert from blob to string.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrPrivate ));
|
|
|
|
::GlobalFree( hg ); hg = NULL;
|
|
|
|
////////////////////////////////////////
|
|
//
|
|
// Export public pair.
|
|
//
|
|
dwSize = 0;
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwSize ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptExportKey( m_hKey, NULL, PUBLICKEYBLOB, 0, (BYTE*)hg, &dwSize ));
|
|
|
|
//
|
|
// Convert from blob to string.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrPublic ));
|
|
|
|
////////////////////////////////////////
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::ImportPrivate( /*[in] */ const CComBSTR& bstrPrivate )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::ImportPrivate" );
|
|
|
|
HRESULT hr;
|
|
HGLOBAL hg = NULL;
|
|
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, Init());
|
|
|
|
|
|
//
|
|
// Convert from string to blob.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrPrivate, hg ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptImportKey( m_hCryptProv, (BYTE*)hg, ::GlobalSize( hg ), NULL, CRYPT_EXPORTABLE, &m_hKey ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::ImportPublic( /*[in ]*/ const CComBSTR& bstrPublic )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::ImportPublic" );
|
|
|
|
HRESULT hr;
|
|
HGLOBAL hg = NULL;
|
|
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, Init());
|
|
|
|
|
|
//
|
|
// Convert from string to blob.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrPublic, hg ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptImportKey( m_hCryptProv, (BYTE*)hg, ::GlobalSize( hg ), NULL, 0, &m_hKey ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::SignData( /*[out]*/ CComBSTR& bstrSignature ,
|
|
/*[in ]*/ BYTE* pbData ,
|
|
/*[in ]*/ DWORD dwDataLen )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::SignData" );
|
|
|
|
HRESULT hr;
|
|
DWORD dwSize = 0;
|
|
HGLOBAL hg = NULL;
|
|
HCRYPTHASH hHash = NULL;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(m_hKey);
|
|
__MPC_PARAMCHECK_NOTNULL(pbData);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptCreateHash( m_hCryptProv, CALG_MD5, 0, 0, &hHash ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptHashData( hHash, pbData, dwDataLen, 0 ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSize ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (hg = ::GlobalAlloc( GMEM_FIXED, dwSize )));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, (BYTE*)hg, &dwSize ));
|
|
|
|
//
|
|
// Convert from blob to string.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrSignature ));
|
|
|
|
////////////////////////////////////////
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
if(hHash) ::CryptDestroyHash( hHash );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT CPCHCryptKeys::VerifyData( /*[in]*/ const CComBSTR& bstrSignature,
|
|
/*[in]*/ BYTE* pbData ,
|
|
/*[in]*/ DWORD dwDataLen )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHCryptKeys::VerifyData" );
|
|
|
|
HRESULT hr;
|
|
HGLOBAL hg = NULL;
|
|
HCRYPTHASH hHash = NULL;
|
|
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(m_hKey);
|
|
__MPC_PARAMCHECK_NOTNULL(pbData);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
//
|
|
// Convert from string to blob.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrSignature, hg ));
|
|
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptCreateHash( m_hCryptProv, CALG_MD5, 0, 0, &hHash ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptHashData( hHash, pbData, dwDataLen, 0 ));
|
|
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptVerifySignature( hHash, (BYTE*)hg, ::GlobalSize( hg ), m_hKey, NULL, 0 ));
|
|
|
|
////////////////////////////////////////
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
if(hHash) ::CryptDestroyHash( hHash );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|