📄 pgpike.c
字号:
pendDest = PGPNewData( ike->memMgr,
sizeof(PGPikePendingDest),
kPGPMemoryMgrFlags_Clear );
if( IsNull( pendDest ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
pendDest->ipAddrStart = saReq->ipAddrStart;
pendDest->ipMaskEnd = saReq->ipMaskEnd;
pendDest->destIsRange = saReq->destIsRange;
pendDest->ipPort = saReq->ipPort;
pendDest->ipProtocol = saReq->ipProtocol;
pendDest->nextDest = partner->pendList;
partner->pendList = pendDest;
#if PGPIKE_DEBUG
pgpIKEDebugLog( ike, TRUE, "SARequest: P1 Already exists, going to P2\n" );
#endif
}
}
}
if( !foundSA )
{
#if PGPIKE_DEBUG
char ipStr[20];
if( IsntNull( saReq->sharedKey ) && saReq->sharedKeySize )
{
pgpIKEGetIPString( saReq->ipAddress, ipStr );
pgpIKEDebugLog( ike, TRUE,
"\tShared Key Authentication enabled for: %s\n", ipStr );
}
#endif
err = pgpIKEStartIdentityExchange( ike, saReq->ipAddress, saReq ); CKERR;
}
done:
return err;
}
PGPError
pgpIKECreateProposals(
PGPikeExchange * exchange )
{
PGPError err = kPGPError_NoErr;
PGPikeProposal * proposal = NULL;
PGPUInt16 transIndex,
numTransforms;
proposal = PGPNewData( exchange->ike->memMgr, sizeof(PGPikeProposal),
kPGPMemoryMgrFlags_Clear );
if( IsNull( proposal ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
switch( exchange->exchangeT )
{
case kPGPike_EX_Identity:
case kPGPike_EX_Aggressive:
proposal->number = 1;
proposal->protocol = kPGPike_PR_IKE;
numTransforms = exchange->ike->numIKEProps;
if( numTransforms > kPGPike_MaxPropTransforms )
numTransforms = kPGPike_MaxPropTransforms;
for( transIndex = 0; transIndex < numTransforms; transIndex++ )
{
PGPikeTransform xTransform;
pgpCopyMemory( &exchange->ike->defaultIKEProps[transIndex], &xTransform,
sizeof( PGPikeTransform ) );
if( exchange->partner->authStyle != kPGPike_AS_Normal )
{
#if !PGPIKE_XAUTHCISCO
if( exchange->partner->authStyle == kPGPike_AS_XAuth )
{
switch( xTransform.authMethod )
{
case kPGPike_AM_PreSharedKey:
xTransform.authMethod = kPGPike_AM_XAuth_InitPreShared;
break;
case kPGPike_AM_DSS_Sig:
xTransform.authMethod = kPGPike_AM_XAuth_InitDSS;
break;
case kPGPike_AM_RSA_Sig:
xTransform.authMethod = kPGPike_AM_XAuth_InitRSA;
break;
default:
continue;
}
}
else if( exchange->partner->authStyle == kPGPike_AS_HybridAuth )
{
switch( xTransform.authMethod )
{
case kPGPike_AM_DSS_Sig:
xTransform.authMethod = kPGPike_AM_HAuth_InitDSS;
break;
case kPGPike_AM_RSA_Sig:
xTransform.authMethod = kPGPike_AM_HAuth_InitRSA;
break;
default:
continue;
}
}
#endif
}
if( pgpIKEIsTransformValid( exchange->partner, kPGPike_PR_IKE,
(PGPikeGenericTransform *)&xTransform ) )
{
pgpCopyMemory( &xTransform, &proposal->t[proposal->numTransforms].u.ike,
sizeof( PGPikeTransform ) );
proposal->numTransforms++;
}
if( proposal->numTransforms &&
( exchange->exchangeT == kPGPike_EX_Aggressive ) )
break;
}
proposal->secLifeTime = exchange->ike->secLifeTimeIKE;
proposal->kbLifeTime = exchange->ike->kbLifeTimeIKE;
break;
case kPGPike_EX_IPSEC_Quick:
{
PGPikeProposal * nproposal = NULL;
PGPUInt32 propType,
propIndex;
PGPBoolean useProtocol;
PGPipsecTransform * curp;
pgpAssert( IsntNull( exchange->destination ) );
for( propIndex = exchange->ike->numIPSECProps; propIndex > 0; propIndex-- )
{
curp = &exchange->ike->defaultIPSECProps[propIndex - 1];
for( propType = 0; propType < 3; propType++ )
{
useProtocol = FALSE;
if( IsNull( nproposal ) )
nproposal = proposal;
else
{
nproposal = PGPNewData( exchange->ike->memMgr,
sizeof(PGPikeProposal), kPGPMemoryMgrFlags_Clear );
if( IsNull( nproposal ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
nproposal->nextProposal = proposal;
proposal = nproposal;
}
switch( propType ) /* in reverse order */
{
case 0: /* IPCOMP */
if( curp->useIPCOMP )
{
useProtocol = TRUE;
proposal->protocol = kPGPike_PR_IPCOMP;
pgpCopyMemory( &curp->ipcomp,
&proposal->t[0].u.ipsec.ipcomp,
sizeof(PGPipsecIPCOMPTransform) );
}
break;
case 1: /* ESP */
if( curp->useESP )
{
useProtocol = TRUE;
proposal->protocol = kPGPike_PR_ESP;
pgpCopyMemory( &curp->esp, &proposal->t[0].u.ipsec.esp,
sizeof(PGPipsecESPTransform) );
if( ( exchange->partner->encapsulateMode == kPGPike_EM_Always ) ||
exchange->partner->bIsRemoteIPNAT || exchange->partner->bIsLocalIPNAT )
{
proposal->t[0].u.ipsec.esp.mode =
( exchange->destination->ipAddrStart > 0 ) ?
kPGPike_PM_UDPencapsulatedTunnel :
kPGPike_PM_UDPencapsulatedTransport;
}
else
{
proposal->t[0].u.ipsec.esp.mode =
( exchange->destination->ipAddrStart > 0 ) ?
kPGPike_PM_Tunnel : kPGPike_PM_Transport;
}
}
break;
case 2: /* AH */
if( curp->useAH )
{
useProtocol = TRUE;
proposal->protocol = kPGPike_PR_AH;
pgpCopyMemory( &curp->ah, &proposal->t[0].u.ipsec.ah,
sizeof(PGPipsecAHTransform) );
if( ( exchange->partner->encapsulateMode == kPGPike_EM_Always ) ||
exchange->partner->bIsRemoteIPNAT || exchange->partner->bIsLocalIPNAT )
{
proposal->t[0].u.ipsec.ah.mode =
( exchange->destination->ipAddrStart > 0 ) ?
kPGPike_PM_UDPencapsulatedTunnel :
kPGPike_PM_UDPencapsulatedTransport;
}
else
{
proposal->t[0].u.ipsec.ah.mode =
( exchange->destination->ipAddrStart > 0 ) ?
kPGPike_PM_Tunnel : kPGPike_PM_Transport;
}
}
break;
}
if( useProtocol )
{
proposal->number = propIndex;
proposal->numTransforms = 1;
proposal->t[0].u.ipsec.groupID = curp->groupID;
proposal->secLifeTime = exchange->ike->secLifeTimeIPSEC;
proposal->kbLifeTime = exchange->ike->kbLifeTimeIPSEC;
err = PGPContextGetRandomBytes( exchange->ike->pgpContext,
&proposal->initSPI, sizeof(PGPipsecSPI) ); CKERR;
}
else
{
nproposal = proposal;
proposal = proposal->nextProposal;
err = PGPFreeData( nproposal ); CKERR;
}
}
}
break;
}
default:
break;
}
pgpAssert( IsNull( exchange->proposals ) );
exchange->proposals = proposal;
proposal = NULL;
done:
if( IsntNull( proposal ) )
(void) PGPFreeData( proposal );
return err;
}
PGPError
pgpIKECreateExchange(
PGPikePartner * partner,
PGPikeExchangeT exchangeT,
PGPikeMessageID * messageID,
PGPikeState state,
PGPBoolean initiator,
PGPikeExchange ** exchangeP )
{
PGPError err = kPGPError_NoErr;
PGPikeExchange * exchange = NULL;
PGPHashContextRef hash = kInvalidPGPHashContextRef;
*exchangeP = NULL;
pgpAssertAddrValid( partner, PGPikePartner );
exchange = PGPNewData( partner->ike->memMgr, sizeof(PGPikeExchange),
kPGPMemoryMgrFlags_Clear );
if( IsNull( exchange ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
partner->ike->numExchanges++;
exchange->ike = partner->ike;
exchange->partner = partner;
exchange->initiator = initiator;
exchange->state = state;
exchange->doi = kPGPike_DOI_IPSEC;
exchange->exchangeT = exchangeT;
#if PGPIKE_DEBUG
pgpIKEDebugLog( partner->ike, TRUE, "\tNew %s Exchange - %s\n",
pgpIKEExchangeTypeString( exchangeT ),
initiator ? "Initiator" : "Responder" );
#endif
if( ( exchangeT == kPGPike_EX_IPSEC_Quick ) ||
( ( ( exchangeT == kPGPike_EX_Informational ) ||
( exchangeT == kPGPike_EX_Transaction ) )
&& partner->ready ) )
{
PGPByte p2iv[kPGPike_MaxHashSize];
if( IsNull( messageID ) )
{
err = PGPContextGetRandomBytes( partner->ike->pgpContext,
&exchange->messageID,
sizeof(PGPikeMessageID) ); CKERR;
}
else
{
pgpCopyMemory( messageID, exchange->messageID,
sizeof(PGPikeMessageID) );
}
if( exchangeT == kPGPike_EX_IPSEC_Quick )
{
pgpCopyMemory( exchange->messageID, partner->oldMessageID[partner->oldMessageIDIndex],
sizeof(PGPikeMessageID) );
if( ++partner->oldMessageIDIndex >= kPGPike_MaxOldExchanges )
partner->oldMessageIDIndex = 0;
}
#if PGPIKE_VERBOSE
pgpIKEDebugData( partner->ike, "\tMessageID",
exchange->messageID, sizeof(PGPikeMessageID) );
#endif
/* Set the last CBC block to correct value for a new P1/P2 exchange */
err = PGPNewHashContext( partner->ike->pgpContext,
partner->sdkHashAlg, &hash ); CKERR;
err = PGPContinueHash( hash, partner->lastP1CBC,
partner->cipherBlockSize ); CKERR;
err = PGPContinueHash( hash, &exchange->messageID,
sizeof(PGPikeMessageID) ); CKERR;
err = PGPFinalizeHash( hash, p2iv ); CKERR;
pgpCopyMemory( p2iv, exchange->lastCBC, partner->cipherBlockSize );
}
if( IsNull( partner->exchanges ) )
partner->exchanges = exchange;
else
{
PGPikeExchange *cn = partner->exchanges;
while( IsntNull( cn->nextExchange ) )
cn = cn->nextExchange;
cn->nextExchange = exchange;
}
*exchangeP = exchange;
done:
if( PGPHashContextRefIsValid( hash ) )
(void)PGPFreeHashContext( hash );
if( IsPGPError( err ) )
(void)PGPFreeData( exchange );
return err;
}
PGPError
pgpIKECreatePartner(
PGPikeContextPriv * ike,
PGPikeMTSASetup * setup,
PGPBoolean initiator,
PGPikePartner ** partnerP )
{
PGPError err = kPGPError_NoErr;
PGPikePartner * partner;
pgpAssert( IsntNull( setup ) );
pgpAssert( IsntNull( partnerP ) );
*partnerP = NULL;
partner = PGPNewData( ike->memMgr, sizeof(PGPikePartner),
kPGPMemoryMgrFlags_Clear );
if( IsntNull( partner ) )
{
partner->magic = kPGPike_Magic;
partner->rttMillisec = kPGPike_RoundTripSlack * 2;
partner->ike = ike;
partner->ipAddress = setup->ipAddress;
partner->localIPAddress = setup->localIPAddress;
partner->initiator = initiator;
partner->destPort = kPGPike_CommonPort;
partner->virtualIP = setup->virtualIP;
partner->authStyle = setup->authStyle;
partner->encapsulateMode = setup->encapsulateMode;
partner->birthTime = PGPGetTime();
if( initiator )
err = pgpIKEBakeCookie( ike, setup->ipAddress, setup->localIPAddress,
&partner->initCookie[0] );
else
err = pgpIKEBakeCookie( ike, setup->ipAddress, setup->localIPAddress,
&partner->respCookie[0] );
CKERR;
partner->sharedKeySize = setup->sharedKeySize;
if( IsntNull( setup->sharedKey ) )
{
partner->sharedKey = PGPNewSecureData( ike->memMgr,
setup->sharedKeySize, kPGPMemoryMgrFlags_Clear );
if( IsntNull( partner->sharedKey ) )
pgpCopyMemory( setup->sharedKey,
partner->sharedKey,
setup->sharedKeySize );
else
{
err = kPGPError_OutOfMemory;
goto done;
}
}
if( IsntNull( setup->idData ) )
{
partner->idData = PGPNewData( ike->memMgr,
setup->idDataSize,
kPGPMemoryMgrFlags_Clear );
if( IsNull( partner->idData ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
partner->idDataSize = setup->idDataSize;
partner->idType = setup->idType;
pgpCopyMemory( setup->idData, partner->idData, partner->idDataSize );
}
if( initiator )
{
partner->pendList = PGPNewData( ike->memMgr,
sizeof(PGPikePendingDest),
kPGPMemoryMgrFlags_Clear );
if( IsNull( partner->pendList ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
partner->pendList->ipAddrStart = setup->ipAddrStart;
partner->pendList->ipMaskEnd = setup->ipMaskEnd;
partner->pendList->destIsRange = setup->destIsRange;
partner->pendList->ipPort = setup->ipPort;
partner->pendList->ipProtocol = setup->ipProtocol;
}
if( partner->authStyle != kPGPike_AS_HybridAuth )
{
err = pgpIKEGetCert( partner, kPGPike_MT_LocalPGPCert ); CKERR;
err = pgpIKEGetCert( partner, kPGPike_MT_LocalX509Cert ); CKERR;
}
/* we're all set, hook it into our partners list */
partner->nextPartner = ike->partner;
ike->partner = partner;
*partnerP = partner;
}
else
err = kPGPError_OutOfMemory;
done:
if( IsPGPError(err) && IsntNull( partner ) )
pgpIKEFreePartner( partner );
return err;
}
PGPError
pgpIKEBakeCookie(
PGPikeContextPriv * ike,
PGPUInt32 destAddress,
PGPUInt32 srcAddress,
PGPByte * outCookie )
{
PGPError err = kPGPError_NoErr;
PGPHashContextRef hash = kInvalidPGPHashContextRef;
PGPUInt16 port = kPGPike_CommonPort;
PGPTime now = PGPGetTime();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -