mirror of https://github.com/lianthony/NT4.0
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.
335 lines
8.5 KiB
335 lines
8.5 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1995.
|
|
//
|
|
// File: message.c
|
|
//
|
|
// Contents:
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 9-22-95 RichardW Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "sslsspi.h"
|
|
|
|
|
|
SECURITY_STATUS
|
|
SEC_ENTRY
|
|
SslMakeSignature(PCtxtHandle phContext,
|
|
DWORD fQOP,
|
|
PSecBufferDesc pMessage,
|
|
ULONG MessageSeqNo)
|
|
{
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
SECURITY_STATUS SEC_ENTRY
|
|
SslVerifySignature(PCtxtHandle phContext,
|
|
PSecBufferDesc pMessage,
|
|
ULONG MessageSeqNo,
|
|
DWORD * pfQOP)
|
|
{
|
|
return(SEC_E_UNSUPPORTED_FUNCTION);
|
|
}
|
|
|
|
SECURITY_STATUS
|
|
SEC_ENTRY
|
|
SslSealMessage( PCtxtHandle phContext,
|
|
DWORD fQOP,
|
|
PSecBufferDesc pMessage,
|
|
ULONG MessageSeqNo)
|
|
{
|
|
|
|
PSecBuffer pBuffer;
|
|
PSecBuffer pHeader;
|
|
PSslContext pContext;
|
|
PCheckSumBuffer pSum;
|
|
DWORD i;
|
|
DWORD PaddingCount;
|
|
UCHAR Padding[16];
|
|
DWORD ReverseSequence;
|
|
PSsl_Message_Header pRecord;
|
|
DWORD TotalSize;
|
|
UCHAR SumBuffer[MAX_SUM_BUFFER];
|
|
|
|
pContext = SslpValidateContextHandle(phContext);
|
|
if (!pContext)
|
|
{
|
|
return( SEC_E_INVALID_HANDLE );
|
|
}
|
|
|
|
//
|
|
// Find the buffer with the data:
|
|
//
|
|
|
|
pBuffer = NULL;
|
|
|
|
for (i = 0 ; i < pMessage->cBuffers ; i++ )
|
|
{
|
|
if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK) ) == SECBUFFER_DATA )
|
|
{
|
|
pBuffer = &pMessage->pBuffers[i];
|
|
}
|
|
else if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK) ) == SECBUFFER_TOKEN )
|
|
{
|
|
pHeader = &pMessage->pBuffers[i];
|
|
}
|
|
}
|
|
|
|
if (!pBuffer || !pHeader)
|
|
{
|
|
return( SEC_E_INVALID_TOKEN );
|
|
}
|
|
|
|
if ( pBuffer->cbBuffer == 0 )
|
|
{
|
|
return( SEC_E_INVALID_TOKEN );
|
|
}
|
|
|
|
PaddingCount = (pBuffer->cbBuffer & (pContext->pSystem->BlockSize - 1));
|
|
if (PaddingCount)
|
|
{
|
|
SslGenerateRandomBits( Padding, PaddingCount );
|
|
}
|
|
|
|
pRecord = pHeader->pvBuffer;
|
|
if (pHeader->cbBuffer < sizeof(Ssl_Message_Header))
|
|
{
|
|
return( SEC_E_INVALID_TOKEN );
|
|
}
|
|
|
|
TotalSize = sizeof(Ssl_Message_Header) + pBuffer->cbBuffer +
|
|
PaddingCount - sizeof(Ssl_Record_Header);
|
|
|
|
pRecord->Header.Byte1 = LSBOF(TotalSize);
|
|
pRecord->Header.Byte0 = MSBOF(TotalSize) | ( PaddingCount ? 0 : 0x80 ) ;
|
|
|
|
|
|
CopyMemory( SumBuffer,
|
|
pContext->pWriteBuffer,
|
|
pContext->pCheck->cbBufferSize );
|
|
|
|
pSum = (PCheckSumBuffer) SumBuffer;
|
|
|
|
pContext->pCheck->Sum( pSum, pBuffer->cbBuffer, pBuffer->pvBuffer );
|
|
if (PaddingCount)
|
|
{
|
|
pContext->pCheck->Sum( pSum, PaddingCount, Padding );
|
|
}
|
|
|
|
DebugLog((DEB_TRACE_MESSAGES, "Sealing with WriteCounter = %d\n",
|
|
pContext->WriteCounter));
|
|
|
|
ReverseSequence = htonl( pContext->WriteCounter );
|
|
pContext->pCheck->Sum( pSum, sizeof(DWORD), (PUCHAR) &ReverseSequence );
|
|
|
|
pContext->pCheck->Finalize( pSum, pRecord->MacData );
|
|
|
|
//
|
|
// BUGBUG: Handle 3-byte messages
|
|
//
|
|
if (PaddingCount)
|
|
{
|
|
return( SEC_E_UNSUPPORTED_FUNCTION );
|
|
}
|
|
|
|
pContext->pSystem->Encrypt( pContext->pWriteState,
|
|
pRecord->MacData,
|
|
pRecord->MacData,
|
|
pContext->pCheck->cbCheckSum );
|
|
|
|
pContext->pSystem->Encrypt( pContext->pWriteState,
|
|
pBuffer->pvBuffer,
|
|
pBuffer->pvBuffer,
|
|
pBuffer->cbBuffer );
|
|
|
|
pContext->WriteCounter ++ ;
|
|
|
|
return( SEC_E_OK );
|
|
|
|
}
|
|
|
|
|
|
SECURITY_STATUS
|
|
SEC_ENTRY
|
|
SslUnsealMessage( PCtxtHandle phContext,
|
|
PSecBufferDesc pMessage,
|
|
ULONG MessageSeqNo,
|
|
DWORD * pfQOP)
|
|
{
|
|
PUCHAR DecryptPoint;
|
|
PSslContext pContext;
|
|
PCheckSumBuffer pSum;
|
|
DWORD i;
|
|
DWORD ReverseSequence;
|
|
DWORD PaddingCount;
|
|
PSsl_Message_Header pRecord;
|
|
PSsl_Message_Header_Ex pRecEx;
|
|
DWORD TotalSize;
|
|
UCHAR Digest[16];
|
|
PSecBuffer pFirstBlank;
|
|
PSecBuffer pWholeMessage;
|
|
UCHAR SumBuffer[MAX_SUM_BUFFER];
|
|
DWORD LeftOver;
|
|
DWORD LeadSize;
|
|
PUCHAR pLeftOver;
|
|
|
|
pContext = SslpValidateContextHandle(phContext);
|
|
if (!pContext)
|
|
{
|
|
return( SEC_E_INVALID_HANDLE );
|
|
}
|
|
|
|
pFirstBlank = NULL;
|
|
pWholeMessage = NULL;
|
|
|
|
for (i = 0 ; i < pMessage->cBuffers ; i++ )
|
|
{
|
|
if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_DATA )
|
|
{
|
|
pWholeMessage = &pMessage->pBuffers[i];
|
|
if (pFirstBlank)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_EMPTY )
|
|
{
|
|
pFirstBlank = &pMessage->pBuffers[i];
|
|
if (pWholeMessage)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!pWholeMessage)
|
|
{
|
|
return( SEC_E_INVALID_TOKEN );
|
|
}
|
|
|
|
if ( pWholeMessage->cbBuffer < sizeof( Ssl_Message_Header ) )
|
|
{
|
|
if ( pFirstBlank )
|
|
{
|
|
pFirstBlank->cbBuffer = sizeof( Ssl_Message_Header );
|
|
pFirstBlank->BufferType = SECBUFFER_MISSING;
|
|
}
|
|
return( SEC_E_INCOMPLETE_MESSAGE );
|
|
}
|
|
|
|
pRecord = pWholeMessage->pvBuffer;
|
|
|
|
if (pRecord->Header.Byte0 & 0x80)
|
|
{
|
|
TotalSize = COMBINEBYTES(pRecord->Header.Byte0, pRecord->Header.Byte1) & 0x7FFF;
|
|
|
|
LeadSize = 2;
|
|
|
|
PaddingCount = 0;
|
|
|
|
pRecEx = NULL;
|
|
DecryptPoint = pRecord->MacData;
|
|
|
|
}
|
|
else
|
|
{
|
|
pRecEx = pWholeMessage->pvBuffer;
|
|
PaddingCount = pRecEx->Header.PaddingSize;
|
|
|
|
DecryptPoint = pRecEx->MacData;
|
|
|
|
TotalSize = COMBINEBYTES( pRecord->Header.Byte0, pRecord->Header.Byte1) & 0x3fff;
|
|
|
|
LeadSize = 3;
|
|
|
|
}
|
|
|
|
if (TotalSize > pWholeMessage->cbBuffer - 2)
|
|
{
|
|
|
|
pFirstBlank->cbBuffer = TotalSize - (pWholeMessage->cbBuffer - 2);
|
|
pFirstBlank->BufferType = SECBUFFER_MISSING;
|
|
|
|
return( SEC_E_INCOMPLETE_MESSAGE );
|
|
}
|
|
|
|
if (TotalSize < sizeof( Ssl_Record_Header ) + pContext->pCheck->cbCheckSum )
|
|
{
|
|
return( SEC_E_MESSAGE_ALTERED );
|
|
}
|
|
|
|
if (TotalSize < pWholeMessage->cbBuffer)
|
|
{
|
|
LeftOver = pWholeMessage->cbBuffer - (TotalSize + LeadSize) ;
|
|
pLeftOver = (PUCHAR) pWholeMessage->pvBuffer + (TotalSize + LeadSize);
|
|
}
|
|
else
|
|
{
|
|
LeftOver = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Decrypt:
|
|
//
|
|
|
|
pContext->pSystem->Decrypt( pContext->pReadState,
|
|
DecryptPoint,
|
|
DecryptPoint,
|
|
TotalSize );
|
|
|
|
//
|
|
// Validate MAC:
|
|
//
|
|
|
|
CopyMemory( SumBuffer,
|
|
pContext->pReadBuffer,
|
|
pContext->pCheck->cbBufferSize );
|
|
|
|
pSum = (PCheckSumBuffer) SumBuffer;
|
|
|
|
pContext->pCheck->Sum( pSum, TotalSize - 16, DecryptPoint + 16 );
|
|
|
|
DebugLog((DEB_TRACE_MESSAGES, "Verifying with ReadCounter = %d\n",
|
|
pContext->ReadCounter));
|
|
|
|
ReverseSequence = htonl( pContext->ReadCounter );
|
|
|
|
pContext->pCheck->Sum( pSum, sizeof(DWORD), (PUCHAR) &ReverseSequence );
|
|
|
|
pContext->pCheck->Finalize( pSum, Digest );
|
|
|
|
pContext->ReadCounter ++;
|
|
|
|
if (memcmp( Digest, DecryptPoint, 16 ) )
|
|
{
|
|
return( SEC_E_MESSAGE_ALTERED );
|
|
}
|
|
|
|
pWholeMessage->BufferType = SECBUFFER_TOKEN;
|
|
pWholeMessage->cbBuffer = (pRecEx ?
|
|
sizeof(Ssl_Message_Header_Ex) :
|
|
sizeof(Ssl_Message_Header) );
|
|
|
|
pFirstBlank->pvBuffer = DecryptPoint + 16;
|
|
pFirstBlank->cbBuffer = TotalSize - 16 - PaddingCount;
|
|
pFirstBlank->BufferType = SECBUFFER_DATA;
|
|
|
|
if (LeftOver)
|
|
{
|
|
pFirstBlank ++;
|
|
pFirstBlank->BufferType = SECBUFFER_EXTRA;
|
|
|
|
pFirstBlank->cbBuffer = LeftOver;
|
|
pFirstBlank->pvBuffer = pLeftOver;
|
|
|
|
}
|
|
|
|
return( SEC_E_OK );
|
|
}
|