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.
 
 
 
 
 
 

402 lines
8.0 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
exchange.cxx
Abstract:
This module implements the IIS_CRYPTO_EXCHANGE_SERVER class.
Author:
Keith Moore (keithmo) 02-Dec-1996
Revision History:
--*/
#include "precomp.hxx"
#pragma hdrstop
//
// Private constants.
//
//
// Private types.
//
//
// Private globals.
//
//
// Private prototypes.
//
//
// Public functions.
//
IIS_CRYPTO_EXCHANGE_SERVER::IIS_CRYPTO_EXCHANGE_SERVER()
/*++
Routine Description:
IIS_CRYPTO_EXCHANGE_SERVER class constructor.
Arguments:
None.
Return Value:
None.
--*/
{
//
// Just put the member variables into known states.
//
m_hClientKeyExchangeKey = CRYPT_NULL;
m_hClientSignatureKey = CRYPT_NULL;
} // IIS_CRYPTO_EXCHANGE_SERVER::IIS_CRYPTO_EXCHANGE_SERVER
IIS_CRYPTO_EXCHANGE_SERVER::~IIS_CRYPTO_EXCHANGE_SERVER()
/*++
Routine Description:
IIS_CRYPTO_EXCHANGE_SERVER class destructor.
Arguments:
None.
Return Value:
None.
--*/
{
//
// Close any open keys.
//
CLOSE_KEY( m_hClientKeyExchangeKey );
CLOSE_KEY( m_hClientSignatureKey );
} // IIS_CRYPTO_EXCHANGE_SERVER::~IIS_CRYPTO_EXCHANGE_SERVER
HRESULT
IIS_CRYPTO_EXCHANGE_SERVER::ServerPhase1(
IN PIIS_CRYPTO_BLOB pClientKeyExchangeKeyBlob,
IN PIIS_CRYPTO_BLOB pClientSignatureKeyBlob,
OUT PIIS_CRYPTO_BLOB * ppServerKeyExchangeKeyBlob,
OUT PIIS_CRYPTO_BLOB * ppServerSignatureKeyBlob,
OUT PIIS_CRYPTO_BLOB * ppServerSessionKeyBlob
)
/*++
Routine Description:
Performs server-side phase 1 of the multi-phase key exchange protocol.
Arguments:
pClientKeyExchangeKeyBlob - Pointer to the client's key exchange key
public blob.
pClientSignatureKeyBlob - Pointer to the client's signature public
blob.
ppServerKeyExchangeKeyBlob - Receives a pointer to the server's key
exchange key public blob if successful. It is the server's
responsibility to (somehow) transmit this to the client.
ppServerSignatureKeyBlob - Receives a pointer to the server's signature
public blob if successful. It is the server's responsibility to
(somehow) transmit this to the client.
ppServerSessionKeyBlob - Receives a pointer to the server's
session key blob if successful. It is the server's responsibility
to (somehow) transmit this to the client.
Return Value:
HRESULT - Completion status, 0 if successful, !0 otherwise.
--*/
{
HRESULT result;
PIIS_CRYPTO_BLOB keyExchangeKeyBlob = NULL;
PIIS_CRYPTO_BLOB signatureKeyBlob = NULL;
PIIS_CRYPTO_BLOB sessionKeyBlob = NULL;
//
// Sanity check.
//
DBG_ASSERT( ValidateState() );
DBG_ASSERT( pClientKeyExchangeKeyBlob != NULL );
DBG_ASSERT( ::IISCryptoIsValidBlob( pClientKeyExchangeKeyBlob ) );
DBG_ASSERT( pClientSignatureKeyBlob != NULL );
DBG_ASSERT( ::IISCryptoIsValidBlob( pClientSignatureKeyBlob ) );
DBG_ASSERT( ppServerKeyExchangeKeyBlob != NULL );
DBG_ASSERT( ppServerSessionKeyBlob != NULL );
//
// Import the client's keys.
//
DBG_ASSERT( m_hClientKeyExchangeKey == CRYPT_NULL );
result = ::IISCryptoImportPublicKeyBlob(
&m_hClientKeyExchangeKey,
pClientKeyExchangeKeyBlob,
m_hProv
);
if( FAILED(result) ) {
goto fatal;
}
DBG_ASSERT( m_hClientSignatureKey == CRYPT_NULL );
result = ::IISCryptoImportPublicKeyBlob(
&m_hClientSignatureKey,
pClientSignatureKeyBlob,
m_hProv
);
if( FAILED(result) ) {
goto fatal;
}
//
// Export the key exchange key blob.
//
result = ::IISCryptoExportPublicKeyBlob(
&keyExchangeKeyBlob,
m_hProv,
m_hKeyExchangeKey
);
if( FAILED(result) ) {
goto fatal;
}
//
// Export the signature key blob.
//
result = ::IISCryptoExportPublicKeyBlob(
&signatureKeyBlob,
m_hProv,
m_hSignatureKey
);
if( FAILED(result) ) {
goto fatal;
}
//
// Generate our local session key.
//
DBG_ASSERT( m_hServerSessionKey == CRYPT_NULL );
result = ::IISCryptoGenerateSessionKey(
&m_hServerSessionKey,
m_hProv
);
if( FAILED(result) ) {
goto fatal;
}
//
// Export it.
//
result = SafeExportSessionKeyBlob(
&sessionKeyBlob,
m_hProv,
m_hServerSessionKey,
m_hClientKeyExchangeKey
);
if( FAILED(result) ) {
goto fatal;
}
//
// Success!
//
*ppServerKeyExchangeKeyBlob = keyExchangeKeyBlob;
*ppServerSignatureKeyBlob = signatureKeyBlob;
*ppServerSessionKeyBlob = sessionKeyBlob;
return NO_ERROR;
fatal:
FREE_BLOB(sessionKeyBlob);
FREE_BLOB(signatureKeyBlob);
FREE_BLOB(keyExchangeKeyBlob);
DBG_ASSERT( FAILED(result) );
return result;
} // IIS_CRYPTO_EXCHANGE_SERVER::ServerPhase1
HRESULT
IIS_CRYPTO_EXCHANGE_SERVER::ServerPhase2(
IN PIIS_CRYPTO_BLOB pClientSessionKeyBlob,
IN PIIS_CRYPTO_BLOB pClientHashBlob,
OUT PIIS_CRYPTO_BLOB * ppServerHashBlob
)
/*++
Routine Description:
Performs server-side phase 2 of the multi-phase key exchange protocol.
Arguments:
pClientSessionKeyBlob - Pointer to the client's session key blob.
pClientHashBlob - Pointer to the client's hash blob.
ppServerHashBlob - Receives a pointer to the server's hash blob
if successful.
Return Value:
HRESULT - Completion status, 0 if successful, !0 otherwise.
--*/
{
HRESULT result;
PIIS_CRYPTO_BLOB phase3HashBlob;
PIIS_CRYPTO_BLOB phase4HashBlob;
//
// Sanity check.
//
DBG_ASSERT( ValidateState() );
DBG_ASSERT( pClientSessionKeyBlob != NULL );
DBG_ASSERT( IISCryptoIsValidBlob( pClientSessionKeyBlob ) );
DBG_ASSERT( pClientHashBlob != NULL );
DBG_ASSERT( IISCryptoIsValidBlob( pClientHashBlob ) );
DBG_ASSERT( ppServerHashBlob != NULL );
//
// Setup our locals so we know how to cleanup on exit.
//
phase3HashBlob = NULL;
phase4HashBlob = NULL;
//
// Import the client's session key.
//
DBG_ASSERT( m_hClientSessionKey == CRYPT_NULL );
result = SafeImportSessionKeyBlob(
&m_hClientSessionKey,
pClientSessionKeyBlob,
m_hProv,
m_hClientSignatureKey
);
if( FAILED(result) ) {
goto fatal;
}
//
// Create the phase 3 hash and compare it with the incoming hash.
//
result = CreatePhase3Hash(
&phase3HashBlob
);
if( FAILED(result) ) {
goto fatal;
}
if( !::IISCryptoCompareBlobs(
pClientHashBlob,
phase3HashBlob
) ) {
result = ERROR_INVALID_DATA;
goto fatal;
}
//
// Create the phase 4 hash to return to the client.
//
result = CreatePhase4Hash(
&phase4HashBlob
);
if( FAILED(result) ) {
goto fatal;
}
//
// Success!
//
*ppServerHashBlob = phase4HashBlob;
FREE_BLOB( phase3HashBlob );
return NO_ERROR;
fatal:
FREE_BLOB( phase3HashBlob );
FREE_BLOB( phase4HashBlob );
DBG_ASSERT( FAILED(result) );
return result;
} // IIS_CRYPTO_EXCHANGE_SERVER::ServerPhase2
//
// Private functions.
//