📄 pgpike.c
字号:
#endif
}
}
break;
}
default:
invalidPayload:
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidPayload );
goto done;
}
payload = nextPayload;
mp += payLength;
}
if( PGPHMACContextRefIsValid( p2hmac ) )
{
PGPByte * p2hmacFinal[kPGPike_MaxHashSize];
err = PGPFinalizeHMAC( p2hmac, p2hmacFinal ); CKERR;
if( !rcvdHash ||
!pgpMemoryEqual( p2hmacFinal, hashPY, partner->hashSize ) )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_AuthenticationFailed );
goto done;
}
}
if( IsntNull( ndPays ) )
{
for( wNDPays = ndPays; IsntNull( wNDPays); wNDPays = wNDPays->nextND )
{
err = pgpIKEProcessInformational( exchange->ike,
exchange->partner->ipAddress, &exchange, wNDPays ); CKERR;
if( IsNull( exchange ) )
goto done;
}
}
if( exchange->initiator )
{
switch( exchange->state )
{
case kPGPike_S_MM_WaitSA:
switch( exchange->proposals->t[0].u.ike.authMethod )
{
case kPGPike_AM_PreSharedKey:
case kPGPike_AM_DSS_Sig:
case kPGPike_AM_RSA_Sig:
err = pgpIKELoadGroup( exchange ); CKERR;
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_KeyExchange,
kPGPike_PY_Nonce,
kPGPike_PY_None ); CKERR;
break;
case kPGPike_AM_RSA_Encrypt:
case kPGPike_AM_RSA_Encrypt_R:
default:
pgpAssert( 0 ); /* unsupported */
break;
}
exchange->state = kPGPike_S_MM_WaitKE;
break;
case kPGPike_S_MM_WaitKE:
{
PGPikePartner * oPartner;
found = FALSE;
if( ( exchange->respNonceLen == 0 ) ||
( IsNull( exchange->dhYr ) ) )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidPayload );
goto done;
}
/* encrypto mondo */
err = pgpIKEGoSecure( exchange ); CKERR;
for( oPartner = exchange->ike->partner; IsntNull( oPartner );
oPartner = oPartner->nextPartner )
{
if( ( oPartner->ipAddress == partner->ipAddress ) &&
( oPartner != partner ) )
found = TRUE;
}
exchange->outAlert = kPGPike_AL_InitialContact;
exchange->outInfoProtocol = kPGPike_PR_IKE;
exchange->outInfoSPICount = 0;
switch( exchange->proposals->t[0].u.ike.authMethod )
{
case kPGPike_AM_RSA_Encrypt:
case kPGPike_AM_RSA_Encrypt_R:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Hash,
!found ? kPGPike_PY_Notification : kPGPike_PY_Skip,
kPGPike_PY_None ); CKERR;
break;
case kPGPike_AM_PreSharedKey:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Identification,
kPGPike_PY_Hash,
!found ? kPGPike_PY_Notification : kPGPike_PY_Skip,
kPGPike_PY_None ); CKERR;
break;
case kPGPike_AM_DSS_Sig:
case kPGPike_AM_RSA_Sig:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Identification,
kPGPike_PY_Certificate,
kPGPike_PY_Signature,
kPGPike_PY_CertRequest,
!found ? kPGPike_PY_Notification : kPGPike_PY_Skip,
kPGPike_PY_None ); CKERR;
break;
default:
pgpAssert( 0 ); /* unsupported */
break;
}
exchange->state = kPGPike_S_MM_WaitFinal;
break;
}
case kPGPike_S_MM_WaitFinal:
if( partner->authenticated )
{
partner->kbLifeTime = exchange->proposals->kbLifeTime;
partner->secLifeTime = exchange->proposals->secLifeTime;
partner->birthTime = PGPGetTime();
if( PGPKeySetRefIsValid( partner->remoteKeySet ) )
PGPFreeKeySet( partner->remoteKeySet );
partner->remoteKeySet = kInvalidPGPKeySetRef;
partner->remoteKey = kInvalidPGPKeyRef;
partner->remoteCert = kInvalidPGPSigRef;
if( IsntNull( partner->pgpAuthKey.pass ) )
PGPFreeData( partner->pgpAuthKey.pass );
partner->pgpAuthKey.pass = NULL;
partner->pgpAuthKey.passLength = 0;
if( IsntNull( partner->x509AuthKey.pass ) )
PGPFreeData( partner->x509AuthKey.pass );
partner->x509AuthKey.pass = NULL;
partner->x509AuthKey.passLength = 0;
partner->ready = TRUE;
err = pgpIKEFreeExchange( exchange );
exchange = NULL;
err = pgpIKELocalAlert( partner->ike, partner->ipAddress,
kPGPike_AL_None, kPGPike_IA_NewPhase1SA, FALSE );
#if PGPIKE_DEBUG
pgpIKEDebugLog( partner->ike, "\tPhase 1 SA Negotiated(I)\n" );
#endif
for( found = FALSE, sa = partner->ike->sa; IsntNull( sa ); sa = sa->nextSA )
if( ( sa->ipAddress == partner->ipAddress ) &&
( sa->ipAddrStart == partner->ipsecOpts.ipAddrStart ) &&
( sa->ipMaskEnd == partner->ipsecOpts.ipMaskEnd ) &&
( sa->destIsRange == partner->ipsecOpts.destIsRange ) &&
sa->activeOut )
{
found = TRUE;
break;
}
if( !found )
{
/* Phase 1 complete, begin Phase 2 if no P2 SAs exist */
err = pgpIKEStartQMExchange( partner, &exchange ); CKERR;
}
}
else
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_AuthenticationFailed );
goto done;
}
break;
case kPGPike_S_QM_WaitSA:
if( exchange->respNonceLen > 0 )
{
if( IsntNull( exchange->idBody ) &&
( !exchange->checkedIDci || !exchange->checkedIDcr ) )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tOnly one client ID rcvd!\n" );
#endif
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidID );
goto done;
}
if( ( exchange->proposals->t[0].u.ipsec.groupID !=
kPGPike_GR_None ) && IsNull( exchange->dhYr ) )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_AuthenticationFailed );
goto done;
}
exchange->state = kPGPike_S_QM_WaitHash3;
err = pgpIKEDoPacket( &exchange, kPGPike_PY_None );CKERR;
/* Phase 2 complete. Generate the SAs */
if( !exchange->needsCommit )
{
err = pgpIKECompletePhase2( exchange, &sa ); CKERR;
err = pgpIKESAEstablished( exchange->ike, sa ); CKERR;
err = pgpIKEFreeExchange( exchange ); CKERR;
exchange = NULL;
}
else
exchange->complete = TRUE;
}
else
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidPayload );
goto done;
}
break;
case kPGPike_S_QM_WaitHash3:
/* we would only legally receive something in this state
when the commit bit was set by the responder and we
are waiting for a connected notify message */
if( !exchange->needsCommit )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidPayload );
goto done;
}
break;
}
}
else
{
switch( exchange->state )
{
case kPGPike_S_MM_WaitSA:
exchange->outAlert = kPGPike_AL_ResponderLifetime;
exchange->outRLSeconds = exchange->outRLKB = FALSE;
exchange->outInfoProtocol = kPGPike_PR_IKE;
exchange->outInfoSPICount = 0;
if( ( ( exchange->proposals->secLifeTime > exchange->ike->secLifeTimeIKE ) &&
exchange->ike->secLifeTimeIKE ) ||
( !exchange->proposals->secLifeTime && exchange->ike->secLifeTimeIKE ) )
{
exchange->outRLSeconds = TRUE;
sendRL = TRUE;
}
if( ( ( exchange->proposals->kbLifeTime > exchange->ike->kbLifeTimeIKE ) &&
exchange->ike->kbLifeTimeIKE ) ||
( !exchange->proposals->kbLifeTime && exchange->ike->kbLifeTimeIKE ) )
{
exchange->outRLKB = TRUE;
sendRL = TRUE;
}
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_SA,
sendRL ? kPGPike_PY_Notification : kPGPike_PY_Skip,
kPGPike_PY_VendorID,
kPGPike_PY_None );CKERR;
err = pgpIKELoadGroup( exchange ); CKERR;
exchange->state = kPGPike_S_MM_WaitKE;
break;
case kPGPike_S_MM_WaitKE:
if( ( exchange->initNonceLen == 0 ) ||
( IsNull( exchange->dhYi ) ) )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidPayload );
goto done;
}
switch( exchange->proposals->t[0].u.ike.authMethod )
{
case kPGPike_AM_PreSharedKey:
case kPGPike_AM_DSS_Sig:
case kPGPike_AM_RSA_Sig:
sharedKey = FALSE;
if( exchange->proposals->t[0].u.ike.authMethod ==
kPGPike_AM_PreSharedKey )
sharedKey = TRUE;
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_KeyExchange,
kPGPike_PY_Nonce,
sharedKey ? kPGPike_PY_Skip : kPGPike_PY_CertRequest,
kPGPike_PY_None );CKERR;
break;
case kPGPike_AM_RSA_Encrypt:
case kPGPike_AM_RSA_Encrypt_R:
default:
pgpAssert( 0 ); /* unsupported */
break;
}
/* encrypto mondo */
err = pgpIKEGoSecure( exchange ); CKERR;
exchange->state = kPGPike_S_MM_WaitFinal;
break;
case kPGPike_S_MM_WaitFinal:
if( partner->authenticated )
{
switch( exchange->proposals->t[0].u.ike.authMethod )
{
case kPGPike_AM_PreSharedKey:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Identification,
kPGPike_PY_Hash,
kPGPike_PY_None ); CKERR;
break;
case kPGPike_AM_DSS_Sig:
case kPGPike_AM_RSA_Sig:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Identification,
kPGPike_PY_Certificate,
kPGPike_PY_Signature,
kPGPike_PY_None ); CKERR;
break;
case kPGPike_AM_RSA_Encrypt:
case kPGPike_AM_RSA_Encrypt_R:
err = pgpIKEDoPacket( &exchange,
kPGPike_PY_Hash,
kPGPike_PY_None ); CKERR;
break;
default:
pgpAssert( 0 ); /* unsupported */
break;
}
partner->kbLifeTime = exchange->proposals->kbLifeTime;
partner->secLifeTime = exchange->proposals->secLifeTime;
partner->birthTime = PGPGetTime();
if( PGPKeySetRefIsValid( partner->remoteKeySet ) )
PGPFreeKeySet( partner->remoteKeySet );
partner->remoteKeySet = kInvalidPGPKeySetRef;
partner->remoteKey = kInvalidPGPKeyRef;
partner->remoteCert = kInvalidPGPSigRef;
if( IsntNull( partner->pgpAuthKey.pass ) )
PGPFreeData( partner->pgpAuthKey.pass );
partner->pgpAuthKey.pass = NULL;
partner->pgpAuthKey.passLength = 0;
if( IsntNull( partner->x509AuthKey.pass ) )
PGPFreeData( partner->x509AuthKey.pass );
partner->x509AuthKey.pass = NULL;
partner->x509AuthKey.passLength = 0;
partner->ready = TRUE;
err = pgpIKEFreeExchange( exchange );
exchange = NULL;
err = pgpIKELocalAlert( partner->ike, partner->ipAddress,
kPGPike_AL_None, kPGPike_IA_NewPhase1SA, FALSE );
#if PGPIKE_DEBUG
pgpIKEDebugLog( partner->ike, "\tPhase 1 SA Negotiated(R)\n" );
#endif
}
else
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_AuthenticationFailed );
goto done;
}
break;
case kPGPike_S_QM_WaitSA:
if( exchange->initNonceLen > 0 )
{
PGPBoolean pfs = FALSE,
idC = FALSE;
exchange->state = kPGPike_S_QM_WaitHash3;
if( IsntNull( exchange->idBody ) != IsntNull( exchange->idRBody ) )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tOnly one client ID rcvd!\n" );
#endif
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidID );
goto done;
}
if( IsntNull( exchange->idBody ) )
{
PGPUInt32 idIP,
fullMask;
PGPBoolean rrange;
PGPikeMTClientIDCheck msg;
/* interpret IDci */
if( IsPGPError( pgpIKEProcessP2ID( exchange,
exchange->idBody,
exchange->idBodySize,
&rrange,
&idIP,
&fullMask ) ) )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tClient ID Parse error!\n" );
#endif
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidID );
goto done;
}
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tIDci: %u.%u.%u.%u/%u.%u.%u.%u\n",
( idIP >> 24 ), ( idIP >> 16 ) & 0xFF, ( idIP >> 8 ) & 0xFF,
( idIP & 0xFF ), ( fullMask >> 24 ), ( fullMask >> 16 ) & 0xFF,
( fullMask >> 8 ) & 0xFF, ( fullMask & 0xFF ) );
#endif
pgpClearMemory( &msg, sizeof(PGPikeMTClientIDCheck) );
msg.ipAddress = partner->ipAddress;
msg.destIsRange = rrange;
msg.ipAddrStart = idIP;
msg.ipMaskEnd = fullMask;
err = (exchange->ike->msgProc)( (PGPikeContextRef)exchange->ike,
exchange->ike->userData, kPGPike_MT_ClientIDCheck, &msg );CKERR;
if( !msg.approved )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tClient ID not approved.\n" );
#endif
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidID );
goto done;
}
exchange->partner->ipsecOpts.ipAddrStart = idIP;
exchange->partner->ipsecOpts.ipMaskEnd = fullMask;
exchange->partner->ipsecOpts.destIsRange = rrange;
/* make sure IDcr is our local IP here */
/* ***** change this to support local gateway! */
if( IsPGPError( pgpIKEProcessP2ID( exchange, exchange->idRBody,
exchange->idRBodySize, &rrange, &idIP, &fullMask ) ) ||
( idIP != partner->localIPAddress ) ||
( fullMask != 0xFFFFFFFF ) || rrange )
{
#if PGPIKE_DEBUG
pgpIKEDebugLog( exchange->ike, "\tIDcr is not our ID!\n" );
#endif
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_InvalidID );
goto done;
}
(void)PGPFreeData( exchange->idBody );
(void)PGPFreeData( exchange->idRBody );
exchange->idBody = NULL;
exchange->idRBody = NULL;
exchange->idBodySize = 0;
exchange->idRBodySize = 0;
idC = TRUE;
}
if( exchange->proposals->t[0].u.ipsec.groupID !=
kPGPike_GR_None )
{
if( IsNull( exchange->dhYi ) )
{
err = pgpIKEAbortExchange( &exchange,
kPGPike_AL_AuthenticationFailed );
goto done;
}
pfs = TRUE;
err = pgpIKELoa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -