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

📄 ssl_svr.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
				exitMutex( MUTEX_SESSIONCACHE );
				return( uniqueID );
				}
			}
		}

	/* If the total number of entries has shrunk due to old entries expiring, 
	   reduce the overall cache size */
	if( lastUsedEntry + 1 < sessionCacheLastEntry )
		sessionCacheLastEntry = lastUsedEntry + 1;

	/* No match found, if we're adding a new entry, add it at the 
	   appropriate location */
	if( cacheAction == CACHE_ACTION_ADD )
		{
		if( !dataHashed )
			hashData( hashValue, sessionID, sessionIDlength );
		cachePos = ( nextFreeEntry != CRYPT_ERROR ) ? nextFreeEntry : \
				   ( sessionCacheLastEntry >= SESSIONCACHE_SIZE ) ? \
				   oldestEntry : sessionCacheLastEntry++;
		sessionCacheIndex[ cachePos ].checkValue = checkValue;
		memcpy( sessionCacheIndex[ cachePos ].hashValue, hashValue, 20 );
		sessionCacheIndex[ cachePos ].expiryTime = \
										currentTime + SESSIONCACHE_TIMEOUT;
		sessionCacheIndex[ cachePos ].uniqueID = uniqueID = \
													sesionCacheUniqueID++;
		sessionCacheIndex[ cachePos ].fixedEntry = isFixedEntry;
		memcpy( sessionCacheData[ cachePos ], masterKey, SSL_SECRET_SIZE );
		}

	exitMutex( MUTEX_SESSIONCACHE );
	return( uniqueID );
	}

/* Add and delete entries to/from the session cache.  These are just wrappers 
   for the local cache-access function, for use by external code */

int findSessionCacheEntryID( const void *sessionID, 
							 const int sessionIDlength )
	{
	return( handleSessionCache( sessionID, sessionIDlength, NULL,
								FALSE, CACHE_ACTION_PRESENCECHECK ) );
	}

static int findSessionCacheEntry( const void *sessionID, 
								  const int sessionIDlength, 
								  void *masterSecret )
	{
	return( handleSessionCache( sessionID, sessionIDlength, masterSecret,
								FALSE, CACHE_ACTION_LOOKUP ) );
	}

int addSessionCacheEntry( const void *sessionID, const int sessionIDlength, 
						  const void *masterSecret, 
						  const BOOLEAN isFixedEntry )
	{
	assert( masterSecret != NULL );

	/* If we're not doing resumes (or the ID is suspiciously short), don't 
	   try and update the session cache */
	if( sessionIDlength < 8 )
		return( 0 );

	/* Add the entry to the cache */
	return( handleSessionCache( sessionID, sessionIDlength,
								( void * ) masterSecret, isFixedEntry,
								CACHE_ACTION_ADD ) );
	}

void deleteSessionCacheEntry( const int uniqueID )
	{
	int i;

	enterMutex( MUTEX_SESSIONCACHE );

	/* Search the cache for the entry with the given ID */
	for( i = 0; i < sessionCacheLastEntry; i++ )
		{
		SESSIONCACHE_INDEX *sessionCacheInfo = &sessionCacheIndex[ i ];

		/* If we've found the entry we're after, clear it and exit */
		if( sessionCacheInfo->uniqueID == uniqueID )
			{
			sessionCacheIndex[ i ] = SESSIONCACHE_INDEX_TEMPLATE;
			zeroise( sessionCacheData[ i ], sizeof( SESSIONCACHE_DATA ) );
			break;
			}
		}
	exitMutex( MUTEX_SESSIONCACHE );
	}

/* Initialise and shut down the session cache */

int initSessionCache( void )
	{
	int i, status;

	enterMutex( MUTEX_SESSIONCACHE );

	/* Initialise the session cache */
	if( ( sessionCacheIndex = clAlloc( "initSessionCache", \
				SESSIONCACHE_SIZE * sizeof( SESSIONCACHE_INDEX ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	status = krnlMemalloc( ( void ** ) &sessionCacheData, 
						   SESSIONCACHE_SIZE * sizeof( SESSIONCACHE_DATA ) );
	if( cryptStatusError( status ) )
		{
		clFree( "initSessionCache", sessionCacheIndex );
		return( status );
		}
	for( i = 0; i < SESSIONCACHE_SIZE; i++ )
		sessionCacheIndex[ i ] = SESSIONCACHE_INDEX_TEMPLATE;
	memset( sessionCacheData, 0, SESSIONCACHE_SIZE * \
								 sizeof( SESSIONCACHE_DATA ) );
	sessionCacheLastEntry = 0;
	sesionCacheUniqueID = 1;

	exitMutex( MUTEX_SESSIONCACHE );
	return( CRYPT_OK );
	}

void endSessionCache( void )
	{
	int i;

	enterMutex( MUTEX_SESSIONCACHE );

	/* Clear and free the session cache */
	krnlMemfree( ( void ** ) &sessionCacheData );
	for( i = 0; i < SESSIONCACHE_SIZE; i++ )
		sessionCacheIndex[ i ] = SESSIONCACHE_INDEX_TEMPLATE;
	clFree( "endSessionCache", sessionCacheIndex );

	exitMutex( MUTEX_SESSIONCACHE );
	}

/****************************************************************************
*																			*
*							Server-side Connect Functions					*
*																			*
****************************************************************************/

/* Perform the initial part of the handshake with the client */

int beginServerHandshake( SESSION_INFO *sessionInfoPtr, 
						  SSL_HANDSHAKE_INFO *handshakeInfo )
	{
	RESOURCE_DATA msgData;
	BYTE *bufPtr, *lengthPtr;
	const void *sessionIDptr, *suitePtr;
	int length, suiteLength, sessionIDlength, resumedSessionID = 0, status;
	BOOLEAN isV2handshake = FALSE, isExtendedHello = FALSE;

	/* Wait for the hello packet from the client */
	status = readPacketSSL( sessionInfoPtr, handshakeInfo, 
							SSL_MSG_SPECIAL_HANDSHAKE );
	if( cryptStatusError( status ) )
		return( status );

	/* Process the client hello.  Although this should be a v3 hello, 
	   Netscape always sends a v2 hello (even if SSLv2 is disabled) so we
	   have to process both types.  The v2 type and version have already 
	   been processed in readPacketSSL() since this information, which is 
	   moved into the header in v3, is part of the body in v2.  What's
	   left for the v2 hello is the remainder of the payload, however we
	   need to know the minor version in order to know whether we can use
	   SSL or TLS, so the header-read code inserts this information at the
	   start of the SSLv2 data:

			SSLv2						SSLv3/TLS
		[ byte		minorVersion ]	byte		ID = 1
		uint16		suiteLen		uint24		len
		uint16		sessIDlen		byte[2]		version = { 0x03, 0x0n }
		uint16		nonceLen		uint32		time		| Client nonce
		uint24[]	suites			byte[28]	nonce		|
		byte[]		sessID			byte		sessIDlen	| May receive nonzero len +
		byte[]		nonce			byte[]		sessID		|	<len> bytes data
									uint16		suiteLen
									uint16[]	suites
									byte		coprLen = 1
									byte		copr = 0 */
	bufPtr = sessionInfoPtr->receiveBuffer;
	if( *bufPtr == SSL_HAND_CLIENT_HELLO )
		{
		/* SSLv3/TLS hello */
		length = checkPacketHeader( sessionInfoPtr, &bufPtr, 
									SSL_HAND_CLIENT_HELLO, 
									VERSIONINFO_SIZE + SSL_NONCE_SIZE + 1 + \
										( UINT16_SIZE * 2 ) + 1 + 1, 
									SSL_MAJOR_VERSION );
		if( cryptStatusError( length ) )
			return( length );
		handshakeInfo->clientOfferedVersion = *bufPtr++;
		status = processVersionInfo( sessionInfoPtr, 
									 handshakeInfo->clientOfferedVersion );
		if( cryptStatusError( status ) )
			return( status );
		memcpy( handshakeInfo->clientNonce, bufPtr, SSL_NONCE_SIZE );
		bufPtr += SSL_NONCE_SIZE;
		sessionIDlength = *bufPtr++;
		sessionIDptr = bufPtr;
		if( sessionIDlength < 0 || sessionIDlength > MAX_SESSIONID_SIZE )
			retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
					"Invalid session ID length %d", sessionIDlength );
		bufPtr += sessionIDlength;
		suiteLength = mgetWord( bufPtr );
		if( suiteLength < 2 || ( suiteLength % 2 ) != 0 )
			retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
					"Invalid handshake cipher suite length %d", 
					suiteLength );
		length -= VERSIONINFO_SIZE + SSL_NONCE_SIZE + \
				  1 + sessionIDlength + UINT16_SIZE + suiteLength + 1 + 1;
		if( length < 0 )
			retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
					"Invalid header data length %d", length );
		suitePtr = bufPtr;
		bufPtr += suiteLength;
		if( *bufPtr++ != 1 || *bufPtr++ )
			retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
					"Invalid compression suite info 0x%02X", 
					bufPtr[ -1 ] );
		if( length > 0 )
			{
			int extListLen;

			/* There's extra data present in the request which (according to
			   RFC 3546's rather optimistic assumptions) should be TLS 
			   extension data.  Make sure that it's valid:

				uint16		extListLen		| RFC 3546
					byte	extType
					uint16	extLen
					byte[]	extData ] */
			if( length < UINT16_SIZE + 1 + UINT16_SIZE )
				retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
						"Client hello contains %d bytes extraneous data",
						length );
			extListLen = mgetWord( bufPtr );
			if( length != UINT16_SIZE + extListLen )
				retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
						"Invalid TLS extension length %d, extension list "
						"length %d", length, extListLen );
			isExtendedHello = TRUE;
			status = processExtensions( sessionInfoPtr, bufPtr, extListLen );
			if( cryptStatusError( status ) )
				return( status );
			}
		}
	else
		{
		int nonceLength;

		/* SSLv2 hello with SSLv3/TLS contents */
		assert( *bufPtr & 0x80 );

		/* Extract the minor version information that was inserted by the
		   header-read code.  We also need to reset the high bit, which was
		   set to ensure that the version doesn't get confused with a 
		   standard SSL packet type */
		handshakeInfo->clientOfferedVersion = *bufPtr++ & 0x7F;
		status = processVersionInfo( sessionInfoPtr, 
									 handshakeInfo->clientOfferedVersion );
		if( cryptStatusError( status ) )
			return( status );

		/* SSLv2 hello from Netscape */
		isV2handshake = TRUE;
		suiteLength = mgetWord( bufPtr );
		sessionIDlength = mgetWord( bufPtr );
		nonceLength = mgetWord( bufPtr );
		if( suiteLength < 3 || ( suiteLength % 3 ) != 0 || \
			sessionIDlength < 0 || sessionIDlength > MAX_SESSIONID_SIZE || \
			nonceLength < 16 || nonceLength > SSL_NONCE_SIZE || \
			( 3 * UINT16_SIZE ) + suiteLength + sessionIDlength + \
				nonceLength > sessionInfoPtr->receiveBufEnd )
			retExt( sessionInfoPtr, CRYPT_ERROR_BADDATA,
					"Invalid SSLv2 handshake info, suite length %d, session "
					"ID length %d, nonce length %d", suiteLength, 
					sessionIDlength, nonceLength );
		suitePtr = bufPtr;
		bufPtr += suiteLength;
		sessionIDptr = bufPtr;
		bufPtr += sessionIDlength;
		memcpy( handshakeInfo->clientNonce + SSL_NONCE_SIZE - nonceLength, 
				bufPtr, nonceLength );
		}
	if( sessionIDlength == SESSIONID_SIZE )
		{
		/* There's a resumed session ID present and it's of the right size to
		   have come from a cryptlib server, remember it for later */
		memcpy( handshakeInfo->sessionID, sessionIDptr, sessionIDlength );
		handshakeInfo->sessionIDlength = sessionIDlength;

		/* Check whether this session is cached */
		resumedSessionID = findSessionCacheEntry( handshakeInfo->sessionID, 
											handshakeInfo->sessionIDlength,
											handshakeInfo->premasterSecret );
		}
	if( resumedSessionID )
		{
		/* It's a resumed session, if it's a fixed entry that was added 
		   manually store the session ID as the user name */
		if( resumedSessionID < 0 )
			{
			length = handshakeInfo->sessionIDlength;

			memcpy( sessionInfoPtr->userName, handshakeInfo->sessionID, 
					handshakeInfo->sessionIDlength );
			while( length > 0 && !sessionInfoPtr->userName[ length - 1 ] )
				length--;	/* Strip zero-padding */
			sessionInfoPtr->userNameLength = length;
			resumedSessionID = -resumedSessionID;	/* Fix ID polarity */
			}
		}
	else
		{
		/* It's a new session or the session data has expired from the cache,
		   generate a new session ID */
		setMessageData( &msgData, handshakeInfo->sessionID, SESSIONID_SIZE );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S, 
								  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
		if( cryptStatusError( status ) )
			return( status );
		handshakeInfo->sessionIDlength = SESSIONID_SIZE;
		}
	handshakeInfo->cipherSuite = chooseCipherSuite( suitePtr, 
									suiteLength / ( isV2handshake ? 3 : 2 ), 
									isV2handshake );
	if( handshakeInfo->cipherSuite == SSL_NULL_WITH_NULL )
		retExt( sessionInfoPtr, CRYPT_ERROR_NOTAVAIL,
				"No crypto algorithm compatible with the remote system "
				"could be found" );
	status = initCiphersuiteInfo( sessionInfoPtr, handshakeInfo, 
								  handshakeInfo->cipherSuite );
	if( cryptStatusError( status ) )
		return( status );

⌨️ 快捷键说明

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