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

📄 pgptls.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1997-1999 Network Associates, Inc.
	All rights reserved.
	
	Platform independent state machine based implementation of
	IETF Transport Layer Security 1.0 with support for OpenPGP/TLS.
	
	TLS 1.0 is specified in IETF RFC 2246

	$Id: pgpTLS.c,v 1.72.6.1 1999/06/04 00:28:50 heller Exp $
____________________________________________________________________________*/

#define PGPTLS_SSL_V2_CLIENT_HELLO
#define noPGPTLS_FORCESSL3	/* define this for all 6.0.X builds */
#define noPGPTLS_DEBUG

#include "pgpTLSPriv.h"
#include "pgpTLSPrimes.h"

#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpMem.h"
#include "pgpEndianConversion.h"
#include "pgpHash.h"
#include "pgpHMAC.h"
#include "pgpPublicKey.h"
#include "pgpSymmetricCipher.h"
#include "pgpCBC.h"
#include "pgpKeys.h"
#include "pgpFeatures.h"

#include "pgpOptionListPriv.h"

#include <string.h>


#define CKERR			if( err ) goto done	
#define FATALTLS( x )	{									\
			err = x;										\
			session->state = kPGPtls_FatalErrorState;		\
			goto done;	}

#define TLSNUMCLIENTSTATES	10
#define TLSNUMSERVERSTATES	7
#define TLSNUMEVENTS		15

static PGPInt8 kPGPtls_ClientStateTable[TLSNUMCLIENTSTATES][TLSNUMEVENTS] =
{
	/*		HR	CH	SH	CE	EC	SC	SKE	CR	SHD	CV	CKE	FIN	FAT	NC	CC	*/
{	/* 0 */	-1,	-2,	1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 1 */	-1, -2,	-2,	2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 2 */	-1,	-2,	-2,	-2,	3,	4,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 3 */	-1,	-2,	-2,	-2,	-2,	-2,	5,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 4 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	6,	7,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 5 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	6,	7,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 6 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	7,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 7 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	8	},
{	/* 8 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	9,	-2,	-2,	-2	},
{	/* 9 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	}
};

static PGPInt8 kPGPtls_ServerStateTable[TLSNUMSERVERSTATES][TLSNUMEVENTS] =
{
	/*		HR	CH	SH	CE	EC	SC	SKE	CR	SHD	CV	CKE	FIN	FAT	NC	CC	*/
{	/* 0 */	-1,	1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 1 */	-1, -2,	-2,	2,	-2,	-2,	-2,	-2,	-2,	-2,	3,	-2,	-2,	-2,	-2	},
{	/* 2 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	3,	-2,	-2,	-2,	-2	},
{	/* 3 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	4,	-2,	-2,	-2,	-2,	5	},
{	/* 4 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	5	},
{	/* 5 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	6,	-2,	-2,	-2	},
{	/* 6 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	}
};

static PGPInt8 kPGPtls_SSL3ServerStateTable[TLSNUMSERVERSTATES][TLSNUMEVENTS] =
{
	/*		HR	CH	SH	CE	EC	SC	SKE	CR	SHD	CV	CKE	FIN	FAT	NC	CC	*/
{	/* 0 */	-1,	1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	},
{	/* 1 */	-1, -2,	-2,	2,	-2,	-2,	-2,	-2,	-2,	-2,	3,	-2,	-2,	-1,	-2	},
{	/* 2 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	3,	-2,	-2,	-2,	-2	},
{	/* 3 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	4,	-2,	-2,	-2,	-1,	5	},
{	/* 4 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	5	},
{	/* 5 */	-1, -2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	6,	-2,	-2,	-2	},
{	/* 6 */	-1,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2,	-2	}
};
		
	PGPInt8
pgpTLSNextState(
	PGPtlsSessionPriv *	session,
	PGPByte				event )
{
	PGPInt8	newState;
	
	if( session->isClientSide )
		newState = kPGPtls_ClientStateTable[session->intState][event];
	else if( session->minorVersion == kPGPtls_SSL3MinorVersion )
		newState = kPGPtls_SSL3ServerStateTable[session->intState][event];
	else
		newState = kPGPtls_ServerStateTable[session->intState][event];
	if( newState == -2 )
		session->state = kPGPtls_FatalErrorState;
	else if( newState >= 0 )
		session->intState = newState;
	return newState;
}

	PGPError
PGPNewTLSContext(
	PGPContextRef		context,
	PGPtlsContextRef *	outRef )
{
	PGPError			err	= kPGPError_NoErr;
	PGPtlsContextPriv *	pContext;

	PGPValidatePtr( context );
	*outRef = NULL;
	
	pContext = (PGPtlsContextPriv *) pgpContextMemAlloc( context,
											sizeof(PGPtlsContextPriv),
											kPGPMemoryMgrFlags_Clear );
	if( IsntNull( pContext ) )
	{
		pContext->pgpContext = context;
		pContext->useCache = TRUE;		
		
		*outRef = ( PGPtlsContextRef ) pContext;
	}
	else
		err = kPGPError_OutOfMemory;
	
	pgpAssertErrWithPtr( err, *outRef );
	return err;
}

	PGPError
PGPFreeTLSContext(
	PGPtlsContextRef	ref )
{
	PGPValidatePtr( ref );

	return pgpContextMemFree( ((PGPtlsContextPriv *) ref)->pgpContext,
								ref );
}

	PGPError
PGPtlsSetCache(
	PGPtlsContextRef	ref,
	PGPBoolean			useCache )
{
	PGPValidatePtr( ref );
	
	((PGPtlsContextPriv *) ref)->useCache = useCache;
	/* not implemented yet */
	
	return kPGPError_NoErr;
}

	PGPError
PGPtlsClearCache(
	PGPtlsContextRef	ref )
{
	(void) ref;
	
	/* not implemented yet */
	return kPGPError_NoErr;
}

	PGPBoolean
pubAlgSupported(
	PGPPublicKeyAlgorithm		pubAlg )
{
	PGPUInt32					numPubAlgs,
								algIndex;
	PGPPublicKeyAlgorithmInfo	info;
	
	PGPCountPublicKeyAlgorithms( &numPubAlgs );
	for( algIndex = 0; algIndex < numPubAlgs; algIndex++ )
	{
		PGPGetIndexedPublicKeyAlgorithmInfo( algIndex, &info);
		if( info.algID == pubAlg )
			return TRUE;
	}
	return FALSE;
}

	PGPError
PGPNewTLSSession(
	PGPtlsContextRef		ref,
	PGPtlsSessionRef *		outRef )
{
	PGPError			err	= kPGPError_NoErr;
	PGPtlsContextPriv *	pContext;
	PGPtlsSessionPriv *	session;

	PGPValidatePtr( ref );
	*outRef = NULL;
	
	pContext = ( PGPtlsContextPriv * ) ref;
	session = ( PGPtlsSessionPriv * ) pgpContextMemAlloc( pContext->pgpContext,
											sizeof( PGPtlsSessionPriv ),
											kPGPMemoryMgrFlags_Clear );
	if( IsntNull( session ) )
	{
		session->pgpContext			= pContext->pgpContext;
		session->tlsContext			= pContext;
		session->memMgr				=
			PGPGetContextMemoryMgr( pContext->pgpContext );
		session->state				= kPGPtls_IdleState;
		session->intState			= 0;
		session->isClientSide		= TRUE;
		session->blocking			= TRUE;
		session->minorVersion		= kPGPtls_MinorVersion;
		
		session->localKeyAlg		= kPGPPublicKeyAlgorithm_Invalid;
		session->requestedPrime		= kPGPtls_DHPrime2048;
		session->certRequested		= FALSE;
		session->certVerified		= FALSE;
		
		session->tlsReceiveProc		= NULL;
		session->tlsSendProc		= NULL;
		session->tlsReceiveUserData	= NULL;
		session->tlsSendUserData	= NULL;

#ifdef PGPTLS_DEBUG
		err = pgpTLSPRFTest( session );
		if( IsPGPError( err ) )
		{
			pgpAssert( 0 );
		}
#endif
		
		err = PGPNewHashContext( session->memMgr, kPGPHashAlgorithm_SHA,
									&session->handshakeSHA);
		if( IsntPGPError( err ) )
		{
			err = PGPNewHashContext( session->memMgr, kPGPHashAlgorithm_MD5,
									&session->handshakeMD5);
		}
		if( IsntPGPError( err ) )
		{
			session->cipherSuites = ( PGPtlsCipherSuite * )
				pgpContextMemAlloc( pContext->pgpContext,
									sizeof( kPGPtls_CipherSuites ),
									kPGPMemoryMgrFlags_Clear );
			if( IsntNull( session->cipherSuites ) )
			{
				/* Determine which available cipher suites we can
					actually perform given the underlying SDK
					algorithms. */
				PGPUInt32					suiteIndex,
											numSymAlgs,
											algIndex,
											totalSuites;
				PGPSymmetricCipherInfo		symInfo;
				PGPBoolean					foundPub,
											foundSym;
				
				totalSuites =	sizeof( kPGPtls_CipherSuites ) /
								sizeof( PGPtlsCipherSuite );
				session->numCipherSuites = 0;
				PGPCountSymmetricCiphers( &numSymAlgs );
				for( suiteIndex = 0; suiteIndex < totalSuites;
						suiteIndex++ )
				{
					foundPub = foundSym = FALSE;
					if( pubAlgSupported(
							kPGPtls_CipherSuites[ suiteIndex ].sigAlg ) )
						foundPub = TRUE;
					if( kPGPtls_CipherSuites[ suiteIndex ].cipherID ==
						kPGPCipherAlgorithm_None )
						foundSym = TRUE;
					else for( algIndex = 0; algIndex < numSymAlgs;
								algIndex++ )
					{
						PGPGetIndexedSymmetricCipherInfo(	algIndex,
															&symInfo );
						if( symInfo.algID ==
							kPGPtls_CipherSuites[ suiteIndex ].cipherID )
						{
							foundSym = TRUE;
							break;
						}
					}
					if( foundPub && foundSym )
						session->cipherSuites[ session->numCipherSuites++ ] =
							kPGPtls_CipherSuites[ suiteIndex ];
				}
			}
			else
				err = kPGPError_OutOfMemory;
		}
		
		session->fatalAlert			= kPGPtls_AT_None;
		
		*outRef = ( PGPtlsSessionRef ) session;
	}
	else
		err = kPGPError_OutOfMemory;
	
	if( IsPGPError( err ) && IsntNull( session ) )
	{
		if( PGPHashContextRefIsValid( session->handshakeSHA ) )
		{
			(void)PGPFreeHashContext( session->handshakeSHA );
			session->handshakeSHA = kInvalidPGPHashContextRef;
		}
		if( PGPHashContextRefIsValid( session->handshakeMD5 ) )
		{
			(void)PGPFreeHashContext( session->handshakeMD5 );
			session->handshakeMD5 = kInvalidPGPHashContextRef;
		}
		if( IsntNull( session->cipherSuites ) )
			(void)PGPFreeData( session->cipherSuites );
		
		pgpContextMemFree( pContext->pgpContext, session );
		*outRef = NULL;
	}
	pgpAssertErrWithPtr( err, *outRef );
	return err;
}

	PGPError
PGPCopyTLSSession( PGPtlsSessionRef ref, PGPtlsSessionRef *outRef )
{
	PGPError			err	= kPGPError_NoErr;
	PGPtlsSessionPriv *	session,
					  *	newSession;
	
	PGPValidatePtr( ref );
	*outRef = NULL;
	session = (PGPtlsSessionPriv *) ref;
	
	newSession = ( PGPtlsSessionPriv * ) pgpContextMemAlloc(
							session->pgpContext,
							sizeof( PGPtlsSessionPriv ),
							kPGPMemoryMgrFlags_Clear );
	if( IsNull( newSession ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	newSession->state				= kPGPtls_IdleState;
	newSession->intState			= 0;
	newSession->minorVersion		= kPGPtls_MinorVersion;
	newSession->pgpContext			= session->pgpContext;
	newSession->tlsContext			= session->tlsContext;
	newSession->memMgr				= session->memMgr;
	
	newSession->requestedPrime		= kPGPtls_DHPrime2048;
	newSession->certRequested		= FALSE;
	newSession->certVerified		= FALSE;
	
	newSession->isClientSide		= session->isClientSide;
	newSession->tlsReceiveProc		= session->tlsReceiveProc;
	newSession->tlsSendProc			= session->tlsSendProc;
	newSession->tlsReceiveUserData	= session->tlsReceiveUserData;
	newSession->tlsSendUserData		= session->tlsSendUserData;
	newSession->isClientSide		= session->isClientSide;
	newSession->blocking			= session->blocking;
	newSession->requestCert			= session->requestCert;
	newSession->numCipherSuites		= session->numCipherSuites;
	newSession->localKey			= session->localKey;
	newSession->localCert			= session->localCert;
	newSession->localCertChain		= session->localCertChain;
	newSession->localKeyAlg			= session->localKeyAlg;
	newSession->localKeyPasskeySize	= session->localKeyPasskeySize;
	newSession->localKeyUsePasskey	= session->localKeyUsePasskey;
	newSession->remoteKey			= session->remoteKey;
	newSession->remoteKeySet		= session->remoteKeySet;
	newSession->remoteKeyAlg		= session->remoteKeyAlg;


	err = PGPNewHashContext( newSession->memMgr, kPGPHashAlgorithm_SHA,
								&newSession->handshakeSHA);
	if( IsPGPError( err ) )
		goto done;
	err = PGPNewHashContext( newSession->memMgr, kPGPHashAlgorithm_MD5,
								&newSession->handshakeMD5);
	if( IsPGPError( err ) )
		goto done;
	newSession->cipherSuites = ( PGPtlsCipherSuite * ) pgpContextMemAlloc(
							newSession->pgpContext,
							sizeof( kPGPtls_CipherSuites ),
							kPGPMemoryMgrFlags_Clear );
	if( IsNull( newSession ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	pgpCopyMemory( session->cipherSuites, newSession->cipherSuites,
							sizeof( kPGPtls_CipherSuites ) );
	if( IsntNull( session->localKeyPasskeyBuffer ) )
	{
		newSession->localKeyPasskeyBuffer = PGPNewSecureData(
									newSession->memMgr,
									newSession->localKeyPasskeySize,
									kPGPMemoryMgrFlags_Clear );
		if( IsNull( newSession->localKeyPasskeyBuffer ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pgpCopyMemory( session->localKeyPasskeyBuffer,
						newSession->localKeyPasskeyBuffer,
						newSession->localKeyPasskeySize );
	}
	if( IsntNull( session->localKeyPassphrase ) )
	{
		PGPUInt16	passLen = strlen( session->localKeyPassphrase ) + 1;
		
		newSession->localKeyPassphrase = PGPNewSecureData(
									newSession->memMgr, passLen,
									kPGPMemoryMgrFlags_Clear );
		if( IsNull( newSession->localKeyPassphrase ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pgpCopyMemory( session->localKeyPassphrase,
						newSession->localKeyPassphrase, passLen );
	}
	*outRef = ( PGPtlsSessionRef ) newSession;
done:
	if( IsPGPError( err ) && IsntNull( newSession ) )
	{	
		if( PGPHashContextRefIsValid( newSession->handshakeSHA ) )
			(void)PGPFreeHashContext( newSession->handshakeSHA );
		if( PGPHashContextRefIsValid( newSession->handshakeMD5 ) )
			(void)PGPFreeHashContext( newSession->handshakeMD5 );
		if( IsntNull( newSession->cipherSuites ) )
			(void)PGPFreeData( newSession->cipherSuites );
		
		pgpContextMemFree( newSession->pgpContext, newSession );
		*outRef = NULL;
	}
	return err;
}

	PGPError

⌨️ 快捷键说明

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