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

📄 pgpike.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
	PGPByte					rawOut[32];

	/* cookie recipe per draft-ietf-ipsec-isakmp-10, 2.5.3 */
	if( !ike->cookieDough )
	{
		err = PGPContextGetRandomBytes( ike->pgpContext, &ike->cookieSecret,
									kPGPike_CookieSize ); CKERR;
		ike->cookieDough = TRUE;
	}
	err = PGPNewHashContext( ike->pgpContext, kPGPHashAlgorithm_SHA, &hash); CKERR;
	
	(void)PGPContinueHash( hash, &srcAddress, sizeof(srcAddress) );
	(void)PGPContinueHash( hash, &destAddress, sizeof(destAddress) );
	(void)PGPContinueHash( hash, &port, sizeof(port) );	/* srcPort */
	(void)PGPContinueHash( hash, &port, sizeof(port) );	/* destPort */
	(void)PGPContinueHash( hash, &ike->cookieSecret, sizeof(ike->cookieSecret) );
	(void)PGPContinueHash( hash, &now, sizeof(now) );

	(void)PGPFinalizeHash( hash, rawOut );
	
	pgpCopyMemory( rawOut, outCookie, kPGPike_CookieSize );

done:
	if( PGPHashContextRefIsValid( hash ) )
		PGPFreeHashContext( hash );
	return err;
}

/* The Mighty ISAKMP Packet Interpreter */
	PGPError
pgpIKEHandlePacket(
	PGPikeContextPriv *		ike,
	PGPikeMTPacket *		packet )
{
	PGPError				err = kPGPError_NoErr;
	PGPikePartner *			partner;
	PGPikeExchange *		exchange;
	PGPByte *				mp;
	PGPByte *				ep;
	PGPSize					mLen;
	PGPBoolean				valid = FALSE;
	PGPBoolean				startP1 = FALSE;
	PGPikeCookie			initCookie,
							respCookie;
	PGPikePayload			firstPayload;
	PGPikeExchangeT			exchangeT;
	PGPikeMessageID			messageID;
	PGPUInt8				flags;
	PGPUInt32				thisCksm = 0;
	PGPByte					noMessageID[4] = { 0, 0, 0, 0 };
	PGPByte					noCookie[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
	
	err = pgpIKEHeaderSniffer( ike, packet, &valid );
	if( !valid )
		goto done;
	mp		= packet->packet;
	mLen	= packet->packetSize;
	ep		= mp + mLen;
	
	pgpCopyMemory( mp, initCookie, sizeof( PGPikeCookie ) );
	mp += sizeof( PGPikeCookie );
	pgpCopyMemory( mp, respCookie, sizeof( PGPikeCookie ) );
	mp += sizeof( PGPikeCookie );
	firstPayload	= (PGPikePayload) *mp++;	mp++;
	exchangeT		= (PGPikeExchangeT) *mp++;
	flags			= *mp++;
	pgpCopyMemory( mp, messageID, sizeof( PGPikeMessageID ) );
	mp += sizeof( PGPikeMessageID );
	mp += sizeof( PGPUInt32 );		/* length checked by pgpIKEHeaderSniffer */

	if( ( ( exchangeT == kPGPike_EX_Identity ) || ( exchangeT == kPGPike_EX_Aggressive ) ) &&
		( firstPayload == kPGPike_PY_SA ) &&
		pgpMemoryEqual( &messageID, &noMessageID, sizeof(PGPikeMessageID) ) )
		startP1 = TRUE;
	if( startP1 && ( ike->numExchanges >= kPGPike_MaxExchanges ) )
	{
		err = pgpIKELocalAlert( ike, packet->ipAddress,
				kPGPike_AL_None, kPGPike_IA_TooManyExchanges, FALSE );
		goto done;
	}
	
	for( partner = ike->partner; IsntNull( partner ); partner = partner->nextPartner )
		if( ( partner->ipAddress == packet->ipAddress ) &&
			pgpMemoryEqual( initCookie, partner->initCookie, sizeof(PGPikeCookie) ) &&
			pgpMemoryEqual( respCookie, partner->respCookie, sizeof(PGPikeCookie) ) )
			break;
	
	if( IsNull( partner ) )
	{
		for( partner = ike->partner; IsntNull( partner ); partner = partner->nextPartner )
			if( ( partner->ipAddress == packet->ipAddress ) &&
				( ( exchangeT == kPGPike_EX_Informational ) ||
				pgpMemoryEqual( initCookie, partner->initCookie, sizeof(PGPikeCookie) ) ) &&
				( startP1 || ( exchangeT == kPGPike_EX_Informational ) ||
				pgpMemoryEqual( respCookie, partner->respCookie, sizeof(PGPikeCookie) )) )
				break;
	}
	
#if PGPIKE_DEBUG
	pgpIKEDebugLog( ike, TRUE, "Rcvd: %sexchange=%s, firstPayload=%s%s%s, port=%u\n",
		( flags & kPGPike_ISAKMPEncryptBit ) ? "(E):" : "",
		pgpIKEExchangeTypeString(exchangeT),
		pgpIKEPayloadTypeString(firstPayload),
		( flags & kPGPike_ISAKMPCommitBit ) ? ", Commit" : "",
		( flags & kPGPike_ISAKMPAuthOnlyBit ) ? ", AuthOnly" : "",
		(PGPUInt32)packet->port );
#endif
	if( IsNull( partner ) )
	{
		if( startP1 )
		{
			PGPikeMTSASetup		msg;
			
			if( !pgpMemoryEqual( respCookie, noCookie, sizeof(PGPikeCookie) ) )
			{
#if PGPIKE_DEBUG
				{
					char	ip1Str[20];
					
					pgpIKEGetIPString( packet->ipAddress, ip1Str );
					pgpIKEDebugLog( ike, TRUE, "\tALERT(R): Found ancient cookie from %s (discarded)\n", ip1Str );
				}
#endif
				goto done;
			}
			pgpClearMemory( &msg, sizeof(PGPikeMTSASetup) );
			msg.ipAddress = packet->ipAddress;
			err = (ike->msgProc)( (PGPikeContextRef)ike, ike->userData,
						kPGPike_MT_PolicyCheck, &msg );CKERR;
			if( msg.approved )
			{
				if( ( ( exchangeT == kPGPike_EX_Aggressive ) && !msg.aggressive ) ||
					( !( exchangeT == kPGPike_EX_Aggressive ) && msg.aggressive ) )
				{
#if PGPIKE_DEBUG
					pgpIKEDebugLog( ike, TRUE, "Aggressive mode mismatch\n" );
#endif
					err = pgpIKELocalAlert( ike, packet->ipAddress,
							kPGPike_AL_InvalidExchange, kPGPike_IA_None, FALSE );
					goto done;
				}
				err = pgpIKECreatePartner( ike, &msg, FALSE, &partner );CKERR;
				err = pgpIKECreateExchange( partner, exchangeT, NULL,
									( exchangeT == kPGPike_EX_Aggressive ) ?
									kPGPike_S_AM_WaitSA : kPGPike_S_MM_WaitSA, FALSE,
									&exchange );CKERR;
				pgpCopyMemory( initCookie, partner->initCookie, kPGPike_CookieSize );
				partner->destPort = packet->port;
				if(( packet->port != kPGPike_CommonPort ) &&
                     !IsNATTraversalVendorIDStringPresent(packet->packet, packet->packetSize))
				{
					pgpIKEAbortExchange( &exchange, kPGPike_AL_NATTranslationFailure );
					partner = NULL;
				}
			}
		}
		else
		{
			err = pgpIKELocalAlert( ike, packet->ipAddress,
					kPGPike_AL_InvalidExchange, kPGPike_IA_None, FALSE );
			goto done;
		}
	}
	else
	{
		if( startP1 )
		{
			if( !partner->ready && partner->initiator &&
				IsntNull( partner->exchanges ) )
			{
				if( ( ( partner->exchanges->exchangeT == kPGPike_EX_Aggressive ) &&
						( partner->exchanges->state == kPGPike_S_AM_WaitSA ) ) ||
					( ( partner->exchanges->exchangeT == kPGPike_EX_Identity ) &&
						( partner->exchanges->state == kPGPike_S_MM_WaitSA ) ) )
					pgpCopyMemory( respCookie, partner->respCookie, kPGPike_CookieSize );
				else
				{
#if PGPIKE_DEBUG
					pgpIKEDebugLog( ike, TRUE, "\tDetected repeat packet(1)\n" );
#endif
					partner->rttMillisec *= 2;
					if( partner->rttMillisec > kPGPike_MaxRoundTrip )
						partner->rttMillisec = kPGPike_MaxRoundTrip;
					goto done;
				}
			}
			else
			{
				err = pgpIKELocalAlert( ike, partner->ipAddress,
						kPGPike_AL_InvalidCookie, kPGPike_IA_None, FALSE );
				goto done;
			}
		}
		else if( !pgpMemoryEqual( respCookie, partner->respCookie,
					kPGPike_CookieSize ) )
		{
			/* Force informational exchanges to be encrypted if the
				Phase 1 SA has been setup. */
			if( ( exchangeT == kPGPike_EX_Informational ) && !partner->ready )
			{
				/* super lame versions of IKE send notifications about Phase 1
					negotiations without any of the cookies */
				/*pgpCopyMemory( respCookie, partner->respCookie, kPGPike_CookieSize );*/
			}
			else
			{
				err = pgpIKELocalAlert( ike, partner->ipAddress,
						kPGPike_AL_InvalidCookie, kPGPike_IA_None, FALSE );
				goto done;
			}
		}
	}
	if( IsntNull( partner ) )
	{
		PGPBoolean				found = FALSE;
		
		/* find the exchange */
		for( exchange = partner->exchanges; IsntNull( exchange );
				exchange = exchange->nextExchange )
		{
			if( ( exchange->exchangeT == exchangeT ) &&
				pgpMemoryEqual( &exchange->messageID, messageID,
					sizeof( PGPikeMessageID ) ) )
			{
				found = TRUE;
				break;
			}
		}
		if( !found )
		{
			if( startP1 )
			{
				err = pgpIKECreateExchange( partner, exchangeT, NULL,
						( exchangeT == kPGPike_EX_Aggressive ) ?
						kPGPike_S_AM_WaitSA : kPGPike_S_MM_WaitSA, FALSE,
						&exchange );CKERR;
			}
			else if( ( exchangeT == kPGPike_EX_Informational ) ||
					( ( ( exchangeT == kPGPike_EX_IPSEC_Quick ) ||
						( exchangeT == kPGPike_EX_Transaction ) ) &&
						partner->ready ) )
			{
				if( exchangeT == kPGPike_EX_IPSEC_Quick )
				{
					PGPUInt32	exchIndex;
					
					for( exchIndex = 0; exchIndex < kPGPike_MaxOldExchanges; exchIndex++ )
					{
						if( pgpMemoryEqual( &partner->oldMessageID[exchIndex], messageID, sizeof(PGPikeMessageID) ) )
						{
#if PGPIKE_DEBUG
							pgpIKEDebugLog( ike, TRUE, "\tRemote tried to recycle MessageID, protocol violation\n" );
#endif
							goto done;
						}
					}
				}
				err = pgpIKECreateExchange( partner, exchangeT, &messageID,
						( exchangeT == kPGPike_EX_IPSEC_Quick ) ?
						kPGPike_S_QM_WaitSA : kPGPike_S_ND_OneState,
						FALSE, &exchange );	CKERR;
				if( exchangeT == kPGPike_EX_IPSEC_Quick )
				{
					exchange->destination = (PGPikePendingDest *)PGPNewData( ike->memMgr,
									sizeof(PGPikePendingDest), kPGPMemoryMgrFlags_Clear );
					if( IsNull( exchange->destination ) )
					{
						err = kPGPError_OutOfMemory;
						goto done;
					}
					exchange->destination->ipAddrStart	= 0;
					exchange->destination->ipMaskEnd	= 0;
					exchange->destination->destIsRange	= FALSE;
					exchange->destination->ipPort		= 0;
					exchange->destination->ipProtocol	= 0;
				}
			}
			else
			{
				err = pgpIKELocalAlert( ike,  partner->ipAddress,
							kPGPike_AL_InvalidMessageID, kPGPike_IA_None, FALSE );
				goto done;
			}
		}
		pgpAssertAddrValid( exchange, PGPikeExchange * );
		
		{
			PGPByte *	cp,
					*	ecp;
			
			cp = packet->packet;
			ecp = cp + packet->packetSize;
			while( cp < ecp )
				thisCksm += *cp++;
		}
		/*	Check for repeat packets because this silly protocol
			doesn't have sequence numbers						*/
		if( ( packet->packetSize == exchange->lastRcvdLength ) &&
			( thisCksm == exchange->lastRcvdCksm ) )
		{
			/* just let ourselves time out because we may have already resent */
			partner->rttMillisec *= 2;
			if( partner->rttMillisec > kPGPike_MaxRoundTrip )
				partner->rttMillisec = kPGPike_MaxRoundTrip;
#if PGPIKE_DEBUG
			pgpIKEDebugLog( ike, TRUE, "\tDetected repeat packet(2)\n" );
#endif
			goto done;
		}
		exchange->lastRcvdLength	= packet->packetSize;
		exchange->lastRcvdCksm		= thisCksm;
		
		/* average in estimate of round trip time */
		if( exchange->lastTransmit )
		{
			if( partner->rttMillisec )
			{
				partner->rttMillisec += PGPGetMilliseconds() - exchange->lastTransmit;
				partner->rttMillisec /= 2;
			}
			else
			{
				partner->rttMillisec = PGPGetMilliseconds() - exchange->lastTransmit;
			}
			if( partner->rttMillisec > kPGPike_MaxRoundTrip )
				partner->rttMillisec = kPGPike_MaxRoundTrip;
		}

		if( flags & kPGPike_ISAKMPEncryptBit )
		{
			if( PGPCBCContextRefIsValid( partner->cbc ) )
			{
#if PGPIKE_VERBOSE
				pgpIKEDebugData( partner->ike, "iv", exchange->lastCBC, partner->cipherBlockSize );
#endif
				err = PGPInitCBC( partner->cbc, partner->cipherKey,
									exchange->lastCBC );	CKERR;
				/* Save the IV for the next packet */
				pgpCopyMemory( ep - partner->cipherBlockSize,
								exchange->lastCBC, partner->cipherBlockSize );
				if( ( exchange->exchangeT == kPGPike_EX_Identity ) ||
					( exchange->exchangeT == kPGPike_EX_Aggressive ) )
					pgpCopyMemory( exchange->lastCBC,
								partner->lastP1CBC, partner->cipherBlockSize );
				/* Decrypt packet */
				err = PGPCBCDecrypt( partner->cbc,
								packet->packet + kPGPike_ISAKMPHeaderSize,
								mLen - kPGPike_ISAKMPHeaderSize,
								packet->packet + kPGPike_ISAKMPHeaderSize );CKERR;
			}
			else
			{
				err = pgpIKEAbortExchange( &exchange, 
						kPGPike_AL_InvalidPayload );CKERR;
			}
		}
		if( flags & kPGPike_ISAKMPCommitBit )
		{
			exchange->needsCommit = TRUE;
		}
		if( flags & kPGPike_ISAKMPAuthOnlyBit )
		{
#if PGPIKE_DEBUG
			pgpIKEDebugLog( ike, TRUE, "\tDetected auth-only IKE, rejecting\n" );
#endif
			goto done;
		}
		err = pgpIKEPayloadLengthCheck( partner, firstPayload, mp, ep, &valid );	CKERR;
		if( !valid )
		{
			if( exchange->exchangeT != kPGPike_EX_Informational )
			{
				err = pgpIKEAbortExchange( &exchange,
							kPGPike_AL_UnequalPayloadLengths );	CKERR;
			}
			else
			{
#if PGPIKE_DEBUG
				pgpIKEDebugLog( ike, TRUE, "\tNotify decryption failed (discarded)\n" );
#endif
				err = pgpIKELocalAlert( ike, partner->ipAddress,
						kPGPike_AL_UnequalPayloadLengths, kPGPike_IA_None, FALSE );
				goto done;
			}
		}
		
		/* OK, everything looks cool, now on to the payloads */
		err = pgpIKEProcessPayloads( exchange, firstPayload, mp );CKERR;
	}
	
done:
	return err;	
}

	PGPError
pgpIKEProcessPayloads(
	PGPikeExchange *		exchange,
	PGPikePayload			firstPayload,
	PGPByte *				mp )
{
	PGPError				err = kPGPError_NoErr;
	PGPikePartner *			partner = exchange->partner,
				  *			oPartner;
	PGPikePayload			payload,
							nextPayload;
	PGPUInt16				payLength;
	PGPikeProposal *		proposal = NULL;
	PGPipsecSA *			sa;
	PGPBoolean				rcvdSA = FALSE;
	PGPBoolean				rcvdHash = FALSE;
	PGPBoolean				found = FALSE;
	PGPBoolean				sendRL = FALSE;
	PGPBoolean				rcvdLocalNatDiscoveryPayload = FALSE;
	PGPBoolean				bFoundRemoteHashMatch = FALSE;
	PGPByte					hashPY[kPGPike_MaxHashSize];
	PGPHMACContextRef		p2hmac = kInvalidPGPHMACContextRef;
	PGPikeNDPayload	*		ndPays = NULL,
					*		wNDPays;
	PGPBoolean				sharedKey;
	PGPikeMTAuthCheck *		authCheck = NULL;

	if( ( ( ( exchange->state == kPGPike_S_MM_WaitSA ) ||
			( exchange->state == kPGPike_S_AM_WaitSA ) ) &&
			( firstPayload != kPGPike_PY_SA ) ) ||
		( ( exchange->state == kPGPike_S_QM_WaitSA ) &&
			( ( firstPayload != kPGPike_PY_Hash ) ||
			  ( (PGPikePayload)*mp != kPGPike_PY_SA ) ) ) )
	{
		err = pgpIKEAbortExchange( &exchange,
						kPGPike_AL_InvalidPayload );
		goto done;
	}
	if( ( exchange->state == kPGPike_S_ND_OneState ) &&
		  	partner->ready && ( firstPayload != kPGPike_PY_Hash ) )
	{
#if PGPIKE_DEBUG
		pgpIKEDebugLog( partner->ike, TRUE, "\tRcvd unencrypted Notify linked to P1 (discarded)\n" );
#endif
		err = pgpIKELocalAlert( exchange->ike, partner->ipAddress,
				kPGPike_AL_PayloadMalformed, kPGPike_IA_None, FALSE );
		goto done;
	}
	if( PGPCBCContextRefIsVal

⌨️ 快捷键说明

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