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

📄 pgpike.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
		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;
	PGPikePayload			payload,
							nextPayload;
	PGPUInt16				payLength;
	PGPikeProposal *		proposal = NULL;
	PGPikeSA *				sa;
	PGPBoolean				rcvdSA = FALSE;
	PGPBoolean				rcvdHash = FALSE;
	PGPBoolean				found = FALSE;
	PGPBoolean				sendRL = FALSE;
	PGPByte					hashPY[kPGPike_MaxHashSize];
	PGPHMACContextRef		p2hmac = kInvalidPGPHMACContextRef;
	PGPikeNDPayload	*		ndPays = NULL,
					*		wNDPays;
	PGPBoolean				sharedKey;
	
	if( ( ( exchange->state == kPGPike_S_MM_WaitSA ) &&
			( firstPayload != kPGPike_PY_SA ) ) ||
		( ( exchange->state == kPGPike_S_QM_WaitSA ) &&
			( ( firstPayload != kPGPike_PY_Hash ) ||
			  ( (PGPikePayload)*mp != kPGPike_PY_SA ) ) ) ||
		  ( ( exchange->state == kPGPike_S_ND_Informational ) &&
		  	partner->ready && ( firstPayload != kPGPike_PY_Hash ) ) )
	{
		err = pgpIKEAbortExchange( &exchange,
						kPGPike_AL_InvalidPayload );
		goto done;
	}
	if( PGPCBCContextRefIsValid( partner->cbc ) &&
		( ( exchange->exchangeT == kPGPike_EX_IPSEC_Quick ) ||
		( ( exchange->exchangeT == kPGPike_EX_Informational ) &&
			( firstPayload == kPGPike_PY_Hash ) ) ) )
	{
		pgpClearMemory( hashPY, kPGPike_MaxHashSize );
		err = PGPNewHMACContext( partner->ike->memMgr,
						partner->sdkHashAlg,
						partner->skeyid_a,
						partner->hashSize,
						&p2hmac );	CKERR;
		if( !exchange->initiator && ( exchange->state == kPGPike_S_QM_WaitHash3 ) )
		{
			err = PGPContinueHMAC( p2hmac, "\0", 1 );	CKERR;
		}
		err = PGPContinueHMAC( p2hmac, exchange->messageID,
								sizeof(PGPikeMessageID) );	CKERR;
		if( exchange->exchangeT == kPGPike_EX_IPSEC_Quick )
		{
			if( ( exchange->initiator && ( exchange->state == kPGPike_S_QM_WaitSA ) ) ||
				( !exchange->initiator && ( exchange->state == kPGPike_S_QM_WaitHash3 ) ) )
				err = PGPContinueHMAC( p2hmac, exchange->initNonce,
											exchange->initNonceLen );CKERR;
			if( !exchange->initiator && ( exchange->state == kPGPike_S_QM_WaitHash3 ) )
				err = PGPContinueHMAC( p2hmac, exchange->respNonce,
											exchange->respNonceLen );CKERR;
		}
	}
	payload = firstPayload;
	while( payload != kPGPike_PY_None )
	{
		PGPByte	*	pp,
				*	ep;
		
		nextPayload = (PGPikePayload)*mp++;
		mp++;	/* reserved */
		payLength = PGPEndianToUInt16( kPGPBigEndian, mp );
		mp += sizeof(PGPUInt16);
		if( PGPHMACContextRefIsValid( p2hmac ) && ( payload != kPGPike_PY_Hash ) )
		{
			err = PGPContinueHMAC( p2hmac, mp - kPGPike_ISAKMPPayloadHeaderSize,
							payLength );	CKERR;
		}
		payLength -= kPGPike_ISAKMPPayloadHeaderSize;
		pp = mp;
		ep = mp + payLength;
		switch( payload )
		{
			case kPGPike_PY_SA:
			{
				PGPikeDOI			doi;
				PGPUInt32			situation;
				PGPikePayload		nextSAPayload;
				PGPUInt16			saPayLength;
				PGPikeAlert			alert = kPGPike_AL_None;
				PGPikeProposal *	nproposal;
				PGPBoolean			valid = FALSE;
				
				if( rcvdSA )	/* we only handle one SA payload */
					break;
				rcvdSA = TRUE;
				if( ( exchange->state != kPGPike_S_QM_WaitSA ) &&
					( exchange->state != kPGPike_S_MM_WaitSA ) )
					goto invalidPayload;
				if( !exchange->initiator &&
					( exchange->state == kPGPike_S_MM_WaitSA ) )
				{
					/* save the SA payload body for HASH_X */
					pgpAssert( IsNull( exchange->initSABody ) );
					exchange->initSABodySize = payLength;
					exchange->initSABody = PGPNewData(
									exchange->ike->memMgr,
									payLength, kPGPMemoryMgrFlags_Clear );
					if( IsNull( exchange->initSABody ) )
					{
						err = kPGPError_OutOfMemory;
						goto done;
					}
					pgpCopyMemory( pp, exchange->initSABody, payLength );
				}
				if( ep - pp < sizeof(PGPUInt32) * 2 )
				{
					err = pgpIKEAbortExchange( &exchange,
								kPGPike_AL_UnequalPayloadLengths );
					goto done;
				}
				/* doi */
				doi = (PGPikeDOI)PGPEndianToUInt32( kPGPBigEndian, pp );
				pp += sizeof( PGPikeDOI );
				if( doi != kPGPike_DOI_IPSEC )
				{
					err = pgpIKEAbortExchange( &exchange,
								kPGPike_AL_DOIUnsupported );
					goto done;
				}
				/* situation */
				situation = PGPEndianToUInt32( kPGPBigEndian, pp );
				pp += sizeof( PGPUInt32 );
				if( ( situation & kPGPike_IPSEC_SIT_Integrity ) ||
					( situation & kPGPike_IPSEC_SIT_Secrecy ) ||
					!( situation & kPGPike_IPSEC_SIT_IdentityOnly ))
				{
					err = pgpIKEAbortExchange( &exchange,
								kPGPike_AL_SituationUnsupported );
					goto done;
				}
				/* Proposals */
				do
				{
					nproposal = NULL;
					
					if( ep - pp < kPGPike_ISAKMPPayloadHeaderSize )
					{
						err = pgpIKEAbortExchange( &exchange,
									kPGPike_AL_UnequalPayloadLengths );
						goto done;
					}
					nextSAPayload = (PGPikePayload)*pp++;	pp++;
					saPayLength = PGPEndianToUInt16( kPGPBigEndian, pp ) -
									kPGPike_ISAKMPPayloadHeaderSize;
					pp += sizeof(PGPUInt16);
					
					err = pgpIKEProcessProposal( &exchange, pp, ep,
												&alert, &nproposal );
					if( IsPGPError( err ) || ( alert != kPGPike_AL_None ) )
						goto done;
					if( IsntNull( nproposal ) )
					{
						PGPikeProposal *wproposal = proposal;
						
						if( IsNull( wproposal ) )
							proposal = nproposal;
						else
						{
							while( IsntNull( wproposal->nextProposal ) )
								wproposal = wproposal->nextProposal;
							wproposal->nextProposal = nproposal;
						}
					}
					pp += saPayLength;
				} while( nextSAPayload == kPGPike_PY_Proposal );
				if( IsNull( proposal ) )
				{
					if( alert == kPGPike_AL_None )
						err = pgpIKEAbortExchange( &exchange,
								kPGPike_AL_BadProposal );
					goto done;
				}
				err = pgpIKESelectProposal( exchange, proposal, &valid );CKERR;
				if( !valid )
				{
					err = pgpIKEAbortExchange( &exchange,
							kPGPike_AL_NoProposalChoice );
					goto done;
				}
				break;
			}
			case kPGPike_PY_KeyExchange:
				if( ( exchange->state == kPGPike_S_MM_WaitKE ) ||
					( exchange->state == kPGPike_S_QM_WaitSA ) )
				{
					err = pgpIKEProcessKE( &exchange, pp,
											payLength );CKERR;
				}
				else
					goto invalidPayload;
				break;
			case kPGPike_PY_Identification:
				if( exchange->exchangeT == kPGPike_EX_IPSEC_Quick )
				{
					if( exchange->initiator )
					{
						PGPBoolean	goodID = FALSE;
						
						if( !exchange->checkedIDci )
						{
							if( ( payLength == exchange->idBodySize ) &&
								pgpMemoryEqual( pp, exchange->idBody, payLength ) )
							{
								exchange->checkedIDci = TRUE;
								goodID = TRUE;
							}
						}
						else if( !exchange->checkedIDcr )
						{
							if( ( payLength == exchange->idRBodySize ) &&
								pgpMemoryEqual( pp, exchange->idRBody, payLength ) )
							{
								exchange->checkedIDcr = TRUE;
								goodID = TRUE;
							}
						}
						if( !goodID )
						{
#if PGPIKE_DEBUG
							pgpIKEDebugLog( exchange->ike, "\tToo many IDs rcvd.\n" );
#endif
							err = pgpIKEAbortExchange( &exchange,
									kPGPike_AL_InvalidID );
							goto done;
						}
					}
					else
					{
						if( IsNull( exchange->idBody ) )
						{
							goto saveIDBody;
						}
						if( IsNull( exchange->idRBody ) )
						{
							exchange->idRBodySize = payLength;
							exchange->idRBody = PGPNewData( exchange->ike->memMgr,
								payLength, kPGPMemoryMgrFlags_Clear );
							if( IsNull( exchange->idBody ) )
							{
								err = kPGPError_OutOfMemory;
								goto done;
							}
							pgpCopyMemory( pp, exchange->idRBody, payLength );
						}
						else
						{
#if PGPIKE_DEBUG
							pgpIKEDebugLog( exchange->ike, "\tToo many IDs rcvd.\n" );
#endif
							err = pgpIKEAbortExchange( &exchange, kPGPike_AL_InvalidID );
							goto done;
						}
					}
				}
				else
				{
					PGPByte		ipProtocol;
					PGPUInt16	ipPort;
					
				saveIDBody:
					/* save the ID payload for HASH_X */
					if( IsntNull( exchange->idBody ) )
					{
						(void)PGPFreeData( exchange->idBody );
						exchange->idBody = NULL;
					}
					exchange->idBodySize = payLength;
					exchange->idBody = PGPNewData( exchange->ike->memMgr,
											payLength, kPGPMemoryMgrFlags_Clear );
					if( IsNull( exchange->idBody ) )
					{
						err = kPGPError_OutOfMemory;
						goto done;
					}
					pgpCopyMemory( pp, exchange->idBody, payLength );
#if PGPIKE_DEBUG
					pgpIKEDebugLog( exchange->ike,
						"\tRemote ID: %s\n", pgpIKEIDTypeString( (PGPipsecIdentity)*pp ) );
#endif
					*pp++;
					ipProtocol = *pp++;
					ipPort = PGPEndianToUInt16( kPGPBigEndian, pp );
					pp += sizeof(PGPUInt16);
					if( ( exchange->exchangeT != kPGPike_EX_IPSEC_Quick ) &&
						( ( ( ipProtocol != 0 ) && (ipProtocol != kPGPike_IPProtocolUDP ) ) ||
						( ( ipPort != 0 ) && ( ipPort != kPGPike_CommonPort ) ) ) )
					{
						err = pgpIKEAbortExchange( &exchange, kPGPike_AL_InvalidID );
						goto done;
					}
				}
				break;
			case kPGPike_PY_Certificate:
				if( ( exchange->state == kPGPike_S_MM_WaitFinal ) &&
					( ( exchange->proposals->t[0].u.ike.authMethod ==
						kPGPike_AM_DSS_Sig ) ||
						( exchange->proposals->t[0].u.ike.authMethod ==
						kPGPike_AM_RSA_Sig ) ) )
				{
					err = pgpIKEProcessCert( &exchange, pp, payLength );CKERR;
				}
				else
					goto invalidPayload;
				break;
			case kPGPike_PY_Signature:
				if( ( exchange->state == kPGPike_S_MM_WaitFinal ) &&
					( ( exchange->proposals->t[0].u.ike.authMethod ==
						kPGPike_AM_DSS_Sig ) ||
						( exchange->proposals->t[0].u.ike.authMethod ==
						kPGPike_AM_RSA_Sig ) ) )
				{
					err = pgpIKEProcessSig( &exchange, pp, payLength );CKERR;
				}
				else
					goto invalidPayload;
				break;
			case kPGPike_PY_CertRequest:
				err = pgpIKEProcessCertRequest( &exchange, pp, payLength );CKERR;
				break;
			case kPGPike_PY_Hash:
				if( !rcvdHash && ( partner->hashSize == payLength ) )
				{
					switch( exchange->state )
					{
						case kPGPike_S_MM_WaitFinal:
							switch( exchange->proposals->t[0].u.ike.authMethod )
							{
								case kPGPike_AM_PreSharedKey:
								case kPGPike_AM_RSA_Encrypt:
								case kPGPike_AM_RSA_Encrypt_R:
								{
									PGPByte		lHash[kPGPike_MaxHashSize];
									
									err = pgpIKEGetAuthHash( exchange,
												(PGPBoolean)!exchange->initiator,
												lHash );	CKERR;
									if( pgpMemoryEqual( lHash, pp,
											partner->hashSize ) )
									{
										partner->authenticated = TRUE;
									}
									else
									{
										err = pgpIKEAbortExchange( &exchange,
													kPGPike_AL_AuthenticationFailed );
										goto done;
									}
									break;
								}
								default:
									goto invalidPayload;
							}
							break;
						case kPGPike_S_QM_WaitSA:
						case kPGPike_S_QM_WaitHash3:
						case kPGPike_S_ND_Informational:
							pgpCopyMemory( pp, hashPY, payLength );
							break;
						default:
							goto invalidPayload;
					}
					rcvdHash = TRUE;
				}
				else
					goto invalidPayload;	
				break;
			case kPGPike_PY_Nonce:
				if( ( exchange->state == kPGPike_S_MM_WaitKE ) ||
					( exchange->state == kPGPike_S_QM_WaitSA ) )
				{
					if( ( payLength >= kPGPike_MinNonceSize ) &&
						( payLength <= kPGPike_MaxNonceSize ) )
					{
						if( exchange->initiator )
						{
							exchange->respNonceLen = payLength;
							pgpCopyMemory( pp, exchange->respNonce,
											payLength );
						}
						else
						{
							exchange->initNonceLen = payLength;
							pgpCopyMemory( pp, exchange->initNonce,
											payLength );
						}
					}
					else
						goto invalidPayload;
				}
				else
					goto invalidPayload;
				break;
			case kPGPike_PY_Notification:
			case kPGPike_PY_Delete:
			{
				PGPikeNDPayload *	newND;
				
				/* save off the notify and delete payloads to make
					sure the QM hash is approved prior to action */
				newND = PGPNewData( exchange->ike->memMgr,
								sizeof(PGPikeNDPayload), kPGPMemoryMgrFlags_Clear );
				if( IsntNull( newND ) )
					newND->pay = PGPNewData( exchange->ike->memMgr,
								payLength, 0 );
				if( IsntNull( newND ) && IsntNull( newND->pay ) )
				{
					pgpCopyMemory( pp, newND->pay, payLength );
					newND->payLen	= payLength;
					newND->payType	= payload;
					newND->nextND	= ndPays;
					ndPays			= newND;
				}
				else
				{
					err = kPGPError_OutOfMemory;
					goto done;
				}
				break;
			}
			case kPGPike_PY_VendorID:
			{
				PGPSize	vidSize = strlen( kPGPike_PGPVendorString1 );
				
				if( pgpMemoryEqual( kPGPike_PGPVendorString1, pp, vidSize ) )
				{
					partner->remotePGPVersion = 1;
					if( payLength > vidSize )
					{
						partner->remotePGPVersion = 2;
#if PGPIKE_DEBUG
						pgpIKEDebugLog( exchange->ike, "\tDetected PGPikeV2\n" );

⌨️ 快捷键说明

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