⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_cry.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* Compare the calculated MAC to the MAC present at the end of the 
	   data */
	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
					sessionInfoPtr->authBlocksize );
	status = krnlSendMessage( sessionInfoPtr->iAuthInContext, 
							  IMESSAGE_COMPARE, &msgData, 
							  MESSAGE_COMPARE_HASH );
	if( cryptStatusError( status ) )
		{
		/* If the error message has already been set at a higher level, 
		   don't update the error info */
		if( noReportError )
			return( CRYPT_ERROR_SIGNATURE );

		retExt( CRYPT_ERROR_SIGNATURE,
				( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO, 
				  "Bad message MAC for packet type %d, length %d",
				  type, dataLength ) );
		}

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*								TLS MAC Functions							*
*																			*
****************************************************************************/

/* Perform a TLS MAC of a data block.  We have to provide special-case 
   handling of zero-length blocks since some versions of OpenSSL send these 
   as a kludge in SSL/TLS 1.0 to work around chosen-IV attacks */

CHECK_RETVAL STDC_NONNULL_ARG( ( 4 ) ) \
static int macDataTLS( const CRYPT_CONTEXT iHashContext, const long seqNo, 
					   const int version,
					   IN_BUFFER( dataLength ) \
					   const void *data, const int dataLength, 
					   const int type )
	{
	STREAM stream;
	BYTE buffer[ 64 + 8 ];
	int length = DUMMY_INIT, status;

	assert( isHandleRangeValid( iHashContext ) );
	assert( seqNo >= 0 );
	assert( version >= 1 );
	assert( isReadPtr( data, dataLength ) );
	assert( dataLength >= 0 && dataLength <= MAX_PACKET_SIZE );

	/* Set up the sequence number, type, version, and length data */
	sMemOpen( &stream, buffer, 64 );
	writeUint64( &stream, seqNo );
	sputc( &stream, type );
	sputc( &stream, SSL_MAJOR_VERSION );
	sputc( &stream, version );
	status = writeUint16( &stream, dataLength );
	if( cryptStatusOK( status ) )
		length = stell( &stream );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		return( status );

	/* Reset the hash context and generate the MAC:

		HMAC( seq_num || type || version || length || data ) */
	krnlSendMessage( iHashContext, IMESSAGE_DELETEATTRIBUTE, NULL,
					 CRYPT_CTXINFO_HASHVALUE );
	krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, buffer, length );
	if( dataLength > 0 )
		krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, ( void * ) data,
						 dataLength );
	return( krnlSendMessage( iHashContext, IMESSAGE_CTX_HASH, "", 0 ) );
	}

int createMacTLS( SESSION_INFO *sessionInfoPtr, void *data,
				  const int dataMaxLength, int *dataLength,
				  const int payloadLength, const int type )
	{
	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
	MESSAGE_DATA msgData;
	int status;

	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
	assert( isWritePtr( data, dataMaxLength ) );
	assert( isWritePtr( dataLength, sizeof( int ) ) );
	assert( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE && \
			payloadLength + sessionInfoPtr->authBlocksize <= dataMaxLength );

	/* Sanity-check the state */
	if( payloadLength < 0 || payloadLength > MAX_PACKET_SIZE || \
		payloadLength + sessionInfoPtr->authBlocksize > dataMaxLength )
		retIntError();

	/* Clear return value */
	*dataLength = 0;

	/* MAC the payload */
	status = macDataTLS( sessionInfoPtr->iAuthOutContext, sslInfo->writeSeqNo,
						 sessionInfoPtr->version, data, payloadLength, type );
	if( cryptStatusError( status ) )
		return( status );
	sslInfo->writeSeqNo++;

	/* Set the MAC value at the end of the packet */
	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
					sessionInfoPtr->authBlocksize );
	status = krnlSendMessage( sessionInfoPtr->iAuthOutContext, 
							  IMESSAGE_GETATTRIBUTE_S, &msgData, 
							  CRYPT_CTXINFO_HASHVALUE );
	if( cryptStatusError( status ) )
		return( status );
	*dataLength = payloadLength + msgData.length;

	return( CRYPT_OK );
	}

int checkMacTLS( SESSION_INFO *sessionInfoPtr, const void *data,
				 const int dataLength, const int payloadLength,
				 const int type, const BOOLEAN noReportError )
	{
	SSL_INFO *sslInfo = sessionInfoPtr->sessionSSL;
	MESSAGE_DATA msgData;
	int status;

	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
	assert( isReadPtr( data, dataLength ) );
	assert( payloadLength >= 0 && payloadLength <= MAX_PACKET_SIZE && \
			payloadLength + sessionInfoPtr->authBlocksize <= dataLength );

	/* Sanity-check the state */
	if( payloadLength < 0 || payloadLength > MAX_PACKET_SIZE || \
		payloadLength + sessionInfoPtr->authBlocksize > dataLength )
		retIntError();

	/* MAC the payload */
	status = macDataTLS( sessionInfoPtr->iAuthInContext, sslInfo->readSeqNo,
						 sessionInfoPtr->version, data, payloadLength, type );
	if( cryptStatusError( status ) )
		return( status );
	sslInfo->readSeqNo++;

	/* Compare the calculated MAC to the MAC present at the end of the 
	   data */
	setMessageData( &msgData, ( BYTE * ) data + payloadLength,
					sessionInfoPtr->authBlocksize );
	status = krnlSendMessage( sessionInfoPtr->iAuthInContext, 
							  IMESSAGE_COMPARE, &msgData, 
							  MESSAGE_COMPARE_HASH );
	if( cryptStatusError( status ) )
		{
		/* If the error message has already been set at a higher level, 
		   don't update the error info */
		if( noReportError )
			return( CRYPT_ERROR_SIGNATURE );

		retExt( CRYPT_ERROR_SIGNATURE,
				( CRYPT_ERROR_SIGNATURE, SESSION_ERRINFO, 
				  "Bad message MAC for packet type %d, length %d",
				  type, dataLength ) );
		}

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*								Dual-MAC Functions							*
*																			*
****************************************************************************/

/* Perform a dual MAC of a data block */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int dualMacData( const SSL_HANDSHAKE_INFO *handshakeInfo,
						IN_BUFFER( dataLength ) \
						const void *data, const int dataLength )
	{
	int status;

	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
	assert( isReadPtr( data, dataLength ) );

	status = krnlSendMessage( handshakeInfo->clientMD5context,
							  IMESSAGE_CTX_HASH, ( void * ) data,
							  dataLength );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( handshakeInfo->clientSHA1context,
								  IMESSAGE_CTX_HASH, ( void * ) data,
								  dataLength );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( handshakeInfo->serverMD5context,
								  IMESSAGE_CTX_HASH, ( void * ) data,
								  dataLength );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( handshakeInfo->serverSHA1context,
								  IMESSAGE_CTX_HASH, ( void * ) data,
								  dataLength );
	return( status );
	}

int dualMacDataRead( const SSL_HANDSHAKE_INFO *handshakeInfo,
					 STREAM *stream )
	{
	const int dataLength = sMemDataLeft( stream );
	void *data;
	int status;

	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
	assert( isReadPtr( stream, sizeof( STREAM ) ) );
	assert( dataLength > 0 );

	/* On a read we've just processed the packet header and everything 
	   that's left in the stream is the data to be MACd */
	status = sMemGetDataBlock( stream, &data, dataLength );
	if( cryptStatusOK( status ) )
		status = dualMacData( handshakeInfo, data, dataLength );
	return( status );
	}

int dualMacDataWrite( const SSL_HANDSHAKE_INFO *handshakeInfo,
					  STREAM *stream )
	{
	const int dataLength = stell( stream ) - SSL_HEADER_SIZE;
	void *data;
	int status;

	assert( isReadPtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
	assert( isReadPtr( stream, sizeof( STREAM ) ) );
	assert( dataLength > 0 );

	/* On a write we've just finished writing the packet and everything but
	   the header needs to be MACd */
	status = sMemGetDataBlockAbs( stream, SSL_HEADER_SIZE, &data, 
								  dataLength );
	if( cryptStatusOK( status ) )
		status = dualMacData( handshakeInfo, data, dataLength );
	return( status );
	}

/* Complete the dual MD5/SHA1 hash/MAC used in the finished message */

int completeSSLDualMAC( const CRYPT_CONTEXT md5context,
						const CRYPT_CONTEXT sha1context, 
						BYTE *hashValues, const int hashValuesMaxLen,
						int *hashValuesLen, const char *label, 
						const int labelLength, const BYTE *masterSecret, 
						const int masterSecretLen )
	{
	MESSAGE_DATA msgData;
	int status;

	assert( isHandleRangeValid( md5context ) );
	assert( isHandleRangeValid( sha1context ) );
	assert( isWritePtr( hashValues, hashValuesMaxLen ) );
	assert( isWritePtr( hashValuesLen, sizeof( int ) ) );
	assert( isReadPtr( label, labelLength ) );
	assert( isReadPtr( masterSecret, masterSecretLen ) );
	assert( hashValuesMaxLen >= MD5MAC_SIZE + SHA1MAC_SIZE );

	/* Clear return value */
	*hashValuesLen = 0;

	/* Generate the inner portion of the handshake message's MAC:

		hash( handshake_messages || cl/svr_label || master_secret || pad1 ).

	   Note that the SHA-1 pad size is 40 bytes and not 44 (to get a total
	   length of 64 bytes), this is due to an error in the spec */
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, ( void * ) label, 
					 labelLength );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, ( void * ) label,
					 labelLength );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, ( void * ) masterSecret,
					 masterSecretLen );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, ( void * ) masterSecret,
					 masterSecretLen );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD1, 48 );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD1, 40 );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, "", 0 );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, "", 0 );
	setMessageData( &msgData, hashValues, MD5MAC_SIZE );
	status = krnlSendMessage( md5context, IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_CTXINFO_HASHVALUE );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, hashValues + MD5MAC_SIZE, SHA1MAC_SIZE );
		status = krnlSendMessage( sha1context, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CTXINFO_HASHVALUE );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Reset the hash contexts */
	krnlSendMessage( md5context, IMESSAGE_DELETEATTRIBUTE, NULL,
					 CRYPT_CTXINFO_HASHVALUE );
	krnlSendMessage( sha1context, IMESSAGE_DELETEATTRIBUTE, NULL,
					 CRYPT_CTXINFO_HASHVALUE );

	/* Generate the outer portion of the handshake message's MAC:

		hash( master_secret || pad2 || inner_hash ) */
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, ( void * ) masterSecret,
					 masterSecretLen );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, ( void * ) masterSecret,
					 masterSecretLen );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD2, 48 );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, PROTOHMAC_PAD2, 40 );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, hashValues,
					 MD5MAC_SIZE );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, hashValues + MD5MAC_SIZE,
					 SHA1MAC_SIZE );
	krnlSendMessage( md5context, IMESSAGE_CTX_HASH, "", 0 );
	krnlSendMessage( sha1context, IMESSAGE_CTX_HASH, "", 0 );
	setMessageData( &msgData, hashValues, MD5MAC_SIZE );
	status = krnlSendMessage( md5context, IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_CTXINFO_HASHVALUE );
	if( cryptStatusError( status ) )
		return( status );
	setMessageData( &msgData, hashValues + MD5MAC_SIZE, SHA1MAC_SIZE );
	status = krnlSendMessage( sha1context, IMESSAGE_GETATTRIBUTE_S,
							  &msgData, CRYPT_CTXINFO_HASHVALUE );
	if( cryptStatusOK( status ) )
		*hashValuesLen = MD5MAC_SIZE + SHA1MAC_SIZE;
	return( status );
	}

int completeTLSHashedMAC( const CRYPT_CONTEXT md5context,
						  const CRYPT_CONTEXT sha1context, 
						  BYTE *hashValues, const int hashValuesMaxLen,
						  int *hashValuesLen, const char *label, 
						  const int labelLength, const BYTE *masterSecret, 
						  const int masterSecretLen )
	{
	MECHANISM_DERIVE_INFO mechanismInfo;
	MESSAGE_DATA msgData;
	BYTE hashBuffer[ 64 + ( CRYPT_MAX_HASHSIZE * 2 ) + 8 ];
	int status;

	assert( isHandleRangeValid( md5context ) );
	assert( isHandleRangeValid( sha1context ) );
	assert( isWritePtr( hashValues, hashValuesMaxLen ) );
	assert( isWritePtr( hashValuesLen, sizeof( int ) ) );
	assert( isReadPtr( label, labelLength ) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -