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

📄 ssl.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
					algoAvailable( CRYPT_ALGO_RC4 ) )
					suite = currentSuite;
				break;

			case SSL_RSA_WITH_DES_CBC_SHA:
				if( suite == SSL_NULL_WITH_NULL && \
					algoAvailable( CRYPT_ALGO_DES ) )
					suite = currentSuite;
				break;
			}
		}

	return( suite );
	}

/* Initialise and destroy the handshake state information */

static void destroyHandshakeInfo( SSL_HANDSHAKE_INFO *handshakeInfo )
	{
	/* Destroy any active contexts */
	if( handshakeInfo->clientMD5context != CRYPT_ERROR )
		krnlSendNotifier( handshakeInfo->clientMD5context,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
	if( handshakeInfo->serverMD5context != CRYPT_ERROR )
		krnlSendNotifier( handshakeInfo->serverMD5context,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
	if( handshakeInfo->clientSHA1context != CRYPT_ERROR )
		krnlSendNotifier( handshakeInfo->clientSHA1context,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
	if( handshakeInfo->serverSHA1context != CRYPT_ERROR )
		krnlSendNotifier( handshakeInfo->serverSHA1context,
						  RESOURCE_IMESSAGE_DECREFCOUNT );

	zeroise( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) );
	}

static int initHandshakeInfo( SSL_HANDSHAKE_INFO *handshakeInfo )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	int status;

	/* Initialise the handshake state info values */
	memset( handshakeInfo, 0, sizeof( SSL_HANDSHAKE_INFO ) );
	handshakeInfo->clientMD5context = \
		handshakeInfo->serverMD5context = \
		handshakeInfo->clientSHA1context = \
		handshakeInfo->serverSHA1context = CRYPT_ERROR;

	/* Create the MAC contexts for ingoing and outgoing data.  SSL uses a 
	   pre-HMAC variant for which we can't use real HMAC but have to 
	   construct it ourselves from MD5 and SHA-1, TLS uses a straight hash
	   and MACs that once a MAC key is available */
	setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_MD5 );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		{
		handshakeInfo->clientMD5context = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_MD5 );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		{
		handshakeInfo->serverMD5context = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_SHA );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		{
		handshakeInfo->clientSHA1context = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_SHA );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		{
		handshakeInfo->serverSHA1context = createInfo.cryptHandle;
		return( CRYPT_OK );
		}

	/* One or more of the contexts couldn't be created, destroy all the 
	   contexts which have been created so far */
	destroyHandshakeInfo( handshakeInfo );
	return( status );
	}

/* Initialise and destroy the security contexts */

static void destroySecurityContexts( SESSION_INFO *sessionInfoPtr )
	{
	/* Destroy any active contexts */
	if( sessionInfoPtr->iKeyexCryptContext != CRYPT_ERROR )
		{
		krnlSendNotifier( sessionInfoPtr->iKeyexCryptContext,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		sessionInfoPtr->iKeyexCryptContext = CRYPT_ERROR;
		}
	if( sessionInfoPtr->iAuthInContext != CRYPT_ERROR )
		{
		krnlSendNotifier( sessionInfoPtr->iAuthInContext,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		sessionInfoPtr->iAuthInContext = CRYPT_ERROR;
		}
	if( sessionInfoPtr->iAuthOutContext != CRYPT_ERROR )
		{
		krnlSendNotifier( sessionInfoPtr->iAuthOutContext,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		sessionInfoPtr->iAuthOutContext = CRYPT_ERROR;
		}
	if( sessionInfoPtr->iCryptInContext != CRYPT_ERROR )
		{
		krnlSendNotifier( sessionInfoPtr->iCryptInContext,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		sessionInfoPtr->iCryptInContext = CRYPT_ERROR;
		}
	if( sessionInfoPtr->iCryptOutContext != CRYPT_ERROR )
		{
		krnlSendNotifier( sessionInfoPtr->iCryptOutContext,
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		sessionInfoPtr->iCryptOutContext = CRYPT_ERROR;
		}
	}

static int initSecurityContexts( SESSION_INFO *sessionInfoPtr )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	int status;

	setMessageCreateObjectInfo( &createInfo, sessionInfoPtr->integrityAlgo );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		{
		sessionInfoPtr->iAuthInContext = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, sessionInfoPtr->integrityAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		{
		sessionInfoPtr->iAuthOutContext = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, sessionInfoPtr->cryptAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		{
		sessionInfoPtr->iCryptInContext = createInfo.cryptHandle;
		setMessageCreateObjectInfo( &createInfo, sessionInfoPtr->cryptAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusOK( status ) )
		sessionInfoPtr->iCryptOutContext = createInfo.cryptHandle;
	else
		/* One or more of the contexts couldn't be created, destroy all the 
		   contexts which have been created so far */
		destroySecurityContexts( sessionInfoPtr );
	return( status );
	}

/* Encrypt/decrypt a data block */

static int encryptData( SESSION_INFO *sessionInfoPtr, BYTE *data,
						const int dataLength )
	{
	int length = dataLength, status;

	/* If it's a block cipher, we need to add end-of-block padding */
	if( sessionInfoPtr->cryptBlocksize > 1 )
		{
		BYTE *dataPadPtr = data + dataLength;
		const int padSize = ( sessionInfoPtr->cryptBlocksize - 1 ) - \
						    ( dataLength & ( sessionInfoPtr->cryptBlocksize - 1 ) );
		int i;

		for( i = 0; i < padSize + 1; i++ )
			*dataPadPtr++ = padSize;	/* PKCS #5 padding required by TLS */
		length += padSize + 1;
		}

	status = krnlSendMessage( sessionInfoPtr->iCryptOutContext,
							  RESOURCE_IMESSAGE_CTX_ENCRYPT, data, length );
	return( cryptStatusError( status ) ? status : length );
	}

static int decryptData( SESSION_INFO *sessionInfoPtr, BYTE *data,
						const int dataLength )
	{
	int length = dataLength, status;

	/* Decrypt the data */
	status = krnlSendMessage( sessionInfoPtr->iCryptInContext,
							  RESOURCE_IMESSAGE_CTX_DECRYPT, data, length );
	if( cryptStatusError( status ) )
		return( status );

	/* If it's a block cipher, we need to remove end-of-block padding */
	if( sessionInfoPtr->cryptBlocksize > 1 )
		{
		const int ch = data[ dataLength - 1 ];

		if( ch < 0 || ch > sessionInfoPtr->cryptBlocksize - 1 )
			return( CRYPT_ERROR_BADDATA );
		length -= ch + 1;
		}

	return( length );
	}

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

static int macDataSSL( SESSION_INFO *sessionInfoPtr, const void *data, 
					   const int dataLength, const int type, 
					   const BOOLEAN isRead )
	{
	RESOURCE_DATA msgData;
	BYTE buffer[ 128 ], *bufPtr;
	BYTE *macPtr = isRead ? buffer : ( BYTE * ) data + dataLength;
	const CRYPT_CONTEXT iHashContext = isRead ? \
			sessionInfoPtr->iAuthInContext : sessionInfoPtr->iAuthOutContext;
	const void *macSecret = isRead ? \
			sessionInfoPtr->sslMacReadSecret : sessionInfoPtr->sslMacWriteSecret;
	const long seqNo = isRead ? \
			sessionInfoPtr->readSeqNo++ : sessionInfoPtr->writeSeqNo++;
	const int padSize = \
			( sessionInfoPtr->integrityAlgo == CRYPT_ALGO_MD5 ) ? 48 : 40;
	int status;

	/* Set up the sequence number and length data */
	memset( buffer, 0, sizeof( buffer ) );
	memcpy( buffer, PROTOHMAC_PAD1, padSize );
	bufPtr = buffer + padSize + 4;
	mputBLong( bufPtr, seqNo );
	*bufPtr++ = type;
	mputBWord( bufPtr, dataLength );

	/* Reset the hash context and generate the inner portion of the MAC:
		hash( MAC_secret || pad1 || seq_num || type || length || data ) */
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_DELETEATTRIBUTE, NULL, 
					 CRYPT_CTXINFO_HASHVALUE );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 ( void * ) macSecret, sessionInfoPtr->authBlocksize );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 buffer, padSize + 8 + ID_SIZE + UINT16_SIZE );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 ( void * ) data, dataLength );
	status = krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
							  "", 0 );
	if( cryptStatusError( status ) )
		return( status );

	/* Extract the inner hash value */
	memcpy( buffer, PROTOHMAC_PAD2, padSize );
	setResourceData( &msgData, buffer + padSize, CRYPT_MAX_HASHSIZE );
	status = krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_GETATTRIBUTE_S, 
							  &msgData, CRYPT_CTXINFO_HASHVALUE );
	if( cryptStatusError( status ) )
		return( status );

	/* Generate the outer portion of the handshake message's MAC and get the
	   MAC value, which is either written to the end of the data (for a 
	   write) or to a separate buffer (for a read):
		hash( MAC_secret || pad2 || inner_hash ) */
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_DELETEATTRIBUTE, NULL, 
					 CRYPT_CTXINFO_HASHVALUE );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 ( void * ) macSecret, sessionInfoPtr->authBlocksize );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 buffer, padSize + msgData.length );
	status = krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, "", 0 );
	if( cryptStatusOK( status ) )
		{
		setResourceData( &msgData, macPtr, CRYPT_MAX_HASHSIZE );
		status = krnlSendMessage( iHashContext, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S, &msgData, 
								  CRYPT_CTXINFO_HASHVALUE );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* If it's a read, compare the calculated MAC to the MAC present at the
	   end of the data */
	if( isRead )
		return( memcmp( macPtr, ( BYTE * ) data + dataLength, msgData.length ) ? \
				CRYPT_ERROR_SIGNATURE : CRYPT_OK );

	return( dataLength + msgData.length );
	}

static int macDataTLS( SESSION_INFO *sessionInfoPtr, const void *data, 
					   const int dataLength, const int type, 
					   const BOOLEAN isRead )
	{
	RESOURCE_DATA msgData;
	BYTE buffer[ 128 ], *bufPtr;
	BYTE *macPtr = isRead ? buffer : ( BYTE * ) data + dataLength;
	const CRYPT_CONTEXT iHashContext = isRead ? \
			sessionInfoPtr->iAuthInContext : sessionInfoPtr->iAuthOutContext;
	const long seqNo = isRead ? \
			sessionInfoPtr->readSeqNo++ : sessionInfoPtr->writeSeqNo++;
	int status;

	/* Set up the sequence number, type, version, and length data */
	memset( buffer, 0, sizeof( buffer ) );
	bufPtr = buffer + 4;
	mputBLong( bufPtr, seqNo );
	*bufPtr++ = type;
	*bufPtr++ = SSL_MAJOR_VERSION;
	*bufPtr++ = TLS_MINOR_VERSION;
	mputBWord( bufPtr, dataLength );

	/* Reset the hash context and generate the MAC, which is either written 
	   to the end of the data (for a write) or to a separate buffer (for a 
	   read):
		HMAC( seq_num || type || version || length || data ) */
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_DELETEATTRIBUTE, NULL, 
					 CRYPT_CTXINFO_HASHVALUE );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 buffer, 8 + ID_SIZE + VERSIONINFO_SIZE + UINT16_SIZE );
	krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
					 ( void * ) data, dataLength );
	status = krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_CTX_HASH, 
							  "", 0 );
	if( cryptStatusOK( status ) )
		{
		setResourceData( &msgData, macPtr, CRYPT_MAX_HASHSIZE );
		status = krnlSendMessage( iHashContext, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S, 
								  &msgData, CRYPT_CTXINFO_HASHVALUE );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* If it's a read, compare the calculated MAC to the MAC present at the
	   end of the data */
	if( isRead )
		return( memcmp( macPtr, ( BYTE * ) data + dataLength, msgData.length ) ? \
				CRYPT_ERROR_SIGNATURE : CRYPT_OK );

	return( dataLength + msgData.length );
	}

static int dualMacData( SSL_HANDSHAKE_INFO *handshakeInfo, const void *data,
						const int dataLength )
	{

⌨️ 快捷键说明

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