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

📄 pgpike.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.
	
	Platform independent state machine based implementation of
	IETF RFC 2409: Internet Key Exchange protocol
	Also implements XAuth V6+, Config Mode, and NAT Traversal.

	$Id: pgpIKE.c,v 1.129 2002/08/06 20:11:10 dallen Exp $
____________________________________________________________________________*/

#include "pgpIKEPriv.h"

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

#include <string.h>
#include <stdio.h>

#if PGP_DEBUG
#define PGPIKE_DEBUG	1
#define PGPIKE_VERBOSE	1
#else
#define PGPIKE_DEBUG	1
#define PGPIKE_VERBOSE	0
#endif

const PGPikeTransform kPGPike_DefaultIKETransforms[] =
	{
		{
			kPGPike_AM_PreSharedKey,
			kPGPike_HA_SHA1,
			kPGPike_SC_CAST_CBC, 0,
			kPGPike_GR_MODPFive
		},
		{
			kPGPike_AM_PreSharedKey,
			kPGPike_HA_MD5,
			kPGPike_SC_3DES_CBC, 0,
			kPGPike_GR_MODPTwo
		},
		/*{	
			kPGPike_AM_PreSharedKey,
			kPGPike_HA_SHA1,
			kPGPike_SC_CAST_CBC, 0,
			kPGPike_GR_ECEight
		},*/
		{
			kPGPike_AM_DSS_Sig,
			kPGPike_HA_SHA1,
			kPGPike_SC_CAST_CBC, 0,
			kPGPike_GR_MODPFive
		},
		{
			kPGPike_AM_DSS_Sig,
			kPGPike_HA_SHA1,
			kPGPike_SC_3DES_CBC, 0,
			kPGPike_GR_MODPTwo
		},
		{
			kPGPike_AM_RSA_Sig,
			kPGPike_HA_SHA1,
			kPGPike_SC_CAST_CBC, 0,
			kPGPike_GR_MODPFive
		},
		{
			kPGPike_AM_RSA_Sig,
			kPGPike_HA_MD5,
			kPGPike_SC_3DES_CBC, 0,
			kPGPike_GR_MODPTwo
		},
		/*{	
			kPGPike_AM_RSA_Sig,
			kPGPike_HA_SHA1,
			kPGPike_SC_CAST_CBC, 0,
			kPGPike_EC2NGroupType, kPGPike_GR_ECEight
		},*/
	};

const PGPipsecTransform kPGPike_DefaultIPSECTransforms[] =
	{
		{	/* ESP, CAST, SHA1 */
			TRUE, { kPGPike_ET_CAST, 0, kPGPike_AA_HMAC_SHA, kPGPike_PM_None },
			FALSE, { kPGPike_AH_None, kPGPike_AA_None, kPGPike_PM_None },
			FALSE, { kPGPike_IC_None },
			kPGPike_GR_None
		},
		{	/* ESP, 3DES, MD5 */
			TRUE, { kPGPike_ET_3DES, 0, kPGPike_AA_HMAC_MD5, kPGPike_PM_None },
			FALSE, { kPGPike_AH_None, kPGPike_AA_None, kPGPike_PM_None },
			FALSE, { kPGPike_IC_None },
			kPGPike_GR_None
		},
	};


const char					kPGPike_PGPVendorString1[] = "OpenPGP1";
const char					kPGPike_PGPVendorString2[] = "0171";	/* last v change is SDK 171 */
const PGPByte				kPGPike_XAuth6VendorID[8] =
								{	0x09, 0x00, 0x26, 0x89, 0xDF, 0xD6, 0xB7, 0x12	};

/* This is the MD5 hash of "draft-ietf-ipsec-nat-t-ike-00" */
const PGPByte				kPGPike_NATTraversalVendorID[16] =
								{	0x44, 0x85, 0x15, 0x2d, 0x18, 0xb6, 0xbb, 0xcd, 
									0x0b, 0xe8, 0xa8, 0x46, 0x95, 0x79, 0xdd, 0xcc	};


enum pgpIKEDHComponent_
{
	kPGPike_dhP,
	kPGPike_dhYi,
	kPGPike_dhYr,

	PGP_ENUM_FORCE( pgpIKEDHComponent_ )
};
PGPENUM_TYPEDEF( pgpIKEDHComponent_, pgpIKEDHComponent );

/* Insert Big Endian bytes into data structures for prime group or EC.
   Those are public "Y" values, received from the peer
 */
	static PGPError
sInsertDH(
	PGPikeExchange		*exchange, 
	pgpIKEDHComponent	compType,
	const PGPByte		*p,
	PGPSize				size )  
{
	PGPError			err = kPGPError_NoErr;
#if PGPIKE_VERBOSE
	char				dbg_msg[80];

	pgpCopyMemory( "Insert ", dbg_msg, 8 );
#endif
	if( compType == kPGPike_dhYi )  
	{
#if PGPIKE_VERBOSE
		strcat( dbg_msg, "dhYi" );
#endif
		pgpAssert( exchange->dhYi == NULL );

		exchange->dhYi = pgpContextMemAlloc( exchange->ike->pgpContext, size, 0 );
		if( IsNull(exchange->dhYi) )  
			err = kPGPError_OutOfMemory;
		else  
		{
			pgpCopyMemory( p, exchange->dhYi, size );
			exchange->dhYi_size = size; 
		}
	}
	else if( compType == kPGPike_dhYr )  
	{
#if PGPIKE_VERBOSE
		strcat( dbg_msg, "dhYr" );
#endif
		pgpAssert( exchange->dhYr == NULL );

		exchange->dhYr = pgpContextMemAlloc( exchange->ike->pgpContext, size, 0 );
		if( IsNull(exchange->dhYr) )  
			err = kPGPError_OutOfMemory;
		else  
		{
			pgpCopyMemory( p, exchange->dhYr, size );
			exchange->dhYr_size = size; 
		}
	}
	else if( compType == kPGPike_dhP )  	/* for prime field only */
	{
#if PGPIKE_VERBOSE
		strcat( dbg_msg, "dhP" );
#endif
		pgpAssert( exchange->isPrimeDH );
		err = PGPNewBigNum( exchange->ike->pgpContext, TRUE, &exchange->primeDH.dhP );
		if( IsntPGPError(err) )
			err = PGPBigNumInsertBigEndianBytes( exchange->primeDH.dhP, p, 0, size );
	}
#if PGP_DEBUG
	else 
	{
		pgpAssert(0);
	}
#endif
#if PGPIKE_VERBOSE
	pgpIKEDebugData( exchange->ike, dbg_msg, (void*)p, size );
#endif
	return err;
}

/* Perform DH step 1 with internal structures, 
   i.e. G (op) dhX, 
   where (op) is either exponentiation or scalar multiplication . 
 */
	static PGPError
sGenerateDH_1( PGPikeExchange *exchange, PGPByte *secretX, PGPSize secretXsize )  
{
	PGPError		err = kPGPError_NoErr;
	PGPByte			*out1 = NULL;
	PGPSize			out1_size;

	/* allocate buffers */
	if( exchange->initiator )	/* store initiator Y value */
	{
		pgpAssert( exchange->dhYi == NULL );
		
		/* I always transmit compressed */
		out1_size = exchange->dhYi_size = exchange->ySizeInTransitMyDH;
		exchange->dhYi = pgpContextMemAlloc( exchange->ike->pgpContext,
											exchange->dhYi_size, 0 );
		if( exchange->dhYi == NULL )  
			err = kPGPError_OutOfMemory;
		else  
			out1 = exchange->dhYi;
	}
	else	/* store responder Y value */
	{
		pgpAssert( exchange->dhYr == NULL );
		
		/* always transmit compressed */
		out1_size = exchange->dhYr_size = exchange->ySizeInTransitMyDH;
		exchange->dhYr = pgpContextMemAlloc( exchange->ike->pgpContext,
											exchange->dhYr_size, 0 );
		if( exchange->dhYr == NULL )  
			err = kPGPError_OutOfMemory;
		else
			out1 = exchange->dhYr;
	}
	if( IsPGPError(err) )
		return err;

	pgpAssert( out1_size );
	if( exchange->isPrimeDH )  
	{
		PGPBigNumRef dhY = NULL;	/* public value, "my" or "his" */

		pgpAssert( exchange->primeDH.xSecretDH == NULL );

		err = PGPNewBigNum( exchange->ike->pgpContext, TRUE, &exchange->primeDH.xSecretDH );
		if( IsntPGPError(err) )
			err = PGPBigNumInsertBigEndianBytes( 
				exchange->primeDH.xSecretDH, secretX, 0, secretXsize );

		err = PGPNewBigNum( exchange->ike->pgpContext, TRUE, &dhY );

		if( IsntPGPError(err) )
			err = PGPBigNumExpMod( exchange->ike->dhPrimeG, exchange->primeDH.xSecretDH, exchange->primeDH.dhP, dhY ); 
		if( IsntPGPError(err) ) 
			err = PGPBigNumExtractBigEndianBytes( dhY, out1, 0, out1_size );
		
		if( dhY != kPGPInvalidBigNumRef )
			(void)PGPFreeBigNum( dhY );
	}
	else  
	{
		err = pgpECIKE_DH1( exchange->ecDH.c, secretX, out1 );
	}
	return err;
}

	static PGPError
sGenerateDH_2(
	PGPikeExchange			*exchange )
{
	PGPError				err = kPGPError_NoErr;

	pgpAssert( exchange->gXYLen == 0 && exchange->gXY == NULL );

	exchange->gXYLen = exchange->xySizeDH;
	exchange->gXY = PGPNewSecureData( exchange->ike->memMgr, exchange->gXYLen, 0 );
	if( IsNull( exchange->gXY ) )
	{
		exchange->gXYLen = 0;
		return kPGPError_OutOfMemory;
	}
	if( exchange->isPrimeDH )  
	{
		PGPBigNumRef	dhSecret = kPGPInvalidBigNumRef;
		PGPBigNumRef	dhY = kPGPInvalidBigNumRef;

		err = PGPNewBigNum( exchange->ike->pgpContext, TRUE, &dhSecret ); 

		if( IsntPGPError( err) )
			err = PGPNewBigNum( exchange->ike->pgpContext, TRUE, &dhY ); 
		if( exchange->initiator )
			err = PGPBigNumInsertBigEndianBytes( dhY, exchange->dhYr,
					0, exchange->dhYr_size );
		else
			err = PGPBigNumInsertBigEndianBytes( dhY, exchange->dhYi, 
					0, exchange->dhYi_size );
		if( IsntPGPError(err) )
			err = PGPBigNumExpMod( dhY, exchange->primeDH.xSecretDH, exchange->primeDH.dhP, dhSecret ); 
		
		/* Load gXY with the shared secret */
		if( IsntPGPError(err) ) 
			err = PGPBigNumExtractBigEndianBytes( dhSecret, 
				exchange->gXY, 0, exchange->gXYLen );	

		if( dhSecret != kPGPInvalidBigNumRef )
			(void)PGPFreeBigNum( dhSecret );
		if( dhY != kPGPInvalidBigNumRef )
			(void)PGPFreeBigNum( dhY );
	}
	else  
	{
		if( exchange->initiator )   
			err = pgpECIKE_import_Y( exchange->ecDH.c, exchange->dhYr );
		else  
			err = pgpECIKE_import_Y( exchange->ecDH.c, exchange->dhYi );
		if( IsntPGPError(err) )
			err = pgpECIKE_DH2( exchange->ecDH.c, exchange->gXY );
	}
	return err;
}

/* This function makes assumptions about values of group IDs for performance */
const static PGPByte id2type[] = 
{
	0, 
	kPGPike_MODPGroupType,	/* kPGPike_GR_MODPOne */
	kPGPike_MODPGroupType,	/* kPGPike_GR_MODPTwo */
	0,						/* don't support EC 2^composite */
	0, 
	kPGPike_MODPGroupType,	/* kPGPike_GR_MODPFive */
	
	kPGPike_EC2NGroupType,	/* kPGPike_GR_ECSix */
	kPGPike_EC2NGroupType,	/* kPGPike_GR_ECSeven */
	kPGPike_EC2NGroupType,	/* kPGPike_GR_ECEight */
	kPGPike_EC2NGroupType	/* kPGPike_GR_ECNine */
};

	static PGPByte
sGroupTypeFromGroupID(
	PGPikeGroupID	groupID )  
{
	if( groupID >= sizeof(id2type) )
	{
		/* TODO: when IANA number is assigned, use id2type instead of switch */
		switch( groupID )
		{
			case kPGPike_GR_MODP2048:
			case kPGPike_GR_MODP3072:
			case kPGPike_GR_MODP4096:
			case kPGPike_GR_MODP6144:
			case kPGPike_GR_MODP8192:
				return kPGPike_MODPGroupType;
			default:
				break;
		}
		return 0;
	}
	return id2type[groupID];
}

    PGPError
PGPNewIKEContext(
	PGPContextRef			context,
	PGPikeMessageProcPtr	ikeMessageProc,
	void *					inUserData,
	PGPikeContextRef *		outRef )
{
	PGPError				err	= kPGPError_NoErr;
	PGPikeContextPriv *		pContext;

	*outRef = NULL;
	PGPValidatePtr( context );
	if( IsNull( ikeMessageProc ) )
		return kPGPError_BadParams;
	
	pContext = (PGPikeContextPriv *) pgpContextMemAlloc( context,
											sizeof(PGPikeContextPriv),
											kPGPMemoryMgrFlags_Clear );
	if( IsntNull( pContext ) )
	{
		pContext->pgpContext		= context;
		pContext->memMgr			= PGPPeekContextMemoryMgr( context );
		pContext->msgProc			= ikeMessageProc;
		pContext->userData			= inUserData;
		pContext->pending			= NULL;
		pContext->cookieDough		= FALSE;
		err = PGPContextGetRandomBytes( context, &pContext->cookieSecret,
									kPGPike_CookieSize );
		if( IsntPGPError( err ) )
			pContext->cookieDough = TRUE;
		err = kPGPError_NoErr;	/* no entropy error here will be retried later */
		
		pContext->secLifeTimeIKE	= kPGPike_DefaultSecLife;
		pContext->kbLifeTimeIKE		= kPGPike_DefaultKBLife;
		pContext->secLifeTimeIPSEC	= kPGPike_DefaultSecLife;
		pContext->kbLifeTimeIPSEC	= kPGPike_DefaultKBLife;
		
		pContext->defaultIKEProps = (PGPikeTransform *) pgpContextMemAlloc(
				context, sizeof(kPGPike_DefaultIKETransforms),
				kPGPMemoryMgrFlags_Clear );
		if( IsNull( pContext->defaultIKEProps ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pContext->numIKEProps = sizeof(kPGPike_DefaultIKETransforms) /
								sizeof(PGPikeTransform);
		pgpCopyMemory( &kPGPike_DefaultIKETransforms[0], pContext->defaultIKEProps,
						sizeof(kPGPike_DefaultIKETransforms) );

		pContext->defaultIPSECProps = (PGPipsecTransform *) pgpContextMemAlloc(
				context, sizeof(kPGPike_DefaultIPSECTransforms),
				kPGPMemoryMgrFlags_Clear );
		if( IsNull( pContext->defaultIPSECProps ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		pContext->numIPSECProps = sizeof(kPGPike_DefaultIPSECTransforms) /
								sizeof(PGPipsecTransform);
		pgpCopyMemory( &kPGPike_DefaultIPSECTransforms[0],
						pContext->defaultIPSECProps,
						sizeof(kPGPike_DefaultIPSECTransforms) );
		
		pContext->allowedAlgorithms.cast5			= TRUE;
		pContext->allowedAlgorithms.aes				= kPGPike_AESKeyLengthAll;
		pContext->allowedAlgorithms.tripleDES		= TRUE;
		pContext->allowedAlgorithms.singleDES		= FALSE;
		pContext->allowedAlgorithms.espNULL			= FALSE;
		pContext->allowedAlgorithms.sha1			= TRUE;
		pContext->allowedAlgorithms.sha2_256		= TRUE;
		pContext->allowedAlgorithms.sha2_384		= TRUE;
		pContext->allowedAlgorithms.sha2_512		= TRUE;
		pContext->allowedAlgorithms.md5				= TRUE;
		pContext->allowedAlgorithms.noAuth			= FALSE;
		pContext->allowedAlgorithms.lzs				= TRUE;
		pContext->allowedAlgorithms.deflate			= TRUE;
		pContext->allowedAlgorithms.modpOne768		= TRUE;
		pContext->allowedAlgorithms.modpTwo1024		= TRUE;
		pContext->allowedAlgorithms.modpFive1536	= TRUE;

		pContext->allowedAlgorithms.ec2n163			= FALSE;
		pContext->allowedAlgorithms.ec2n283			= FALSE;

		pContext->allowedAlgorithms.modp2048		= FALSE;

⌨️ 快捷键说明

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