📄 pgpike.c
字号:
/*____________________________________________________________________________
Copyright (C) 1999 Network Associates, Inc.
All rights reserved.
Platform independent state machine based implementation of
IETF RFC 2409: Internet Key Exchange protocol
$Id: pgpIKE.c,v 1.115.2.3 1999/06/16 03:31:20 wprice Exp $
____________________________________________________________________________*/
#include "pgpIKEPriv.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpMem.h"
#include "pgpEndianConversion.h"
#include "pgpHash.h"
#include "pgpHMAC.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
#endif
const PGPikeTransform kPGPike_DefaultIKETransforms[] =
{
{
kPGPike_AM_PreSharedKey,
kPGPike_HA_SHA1,
kPGPike_SC_CAST_CBC,
TRUE, kPGPike_GR_MODPFive
},
{
kPGPike_AM_PreSharedKey,
kPGPike_HA_MD5,
kPGPike_SC_3DES_CBC,
TRUE, kPGPike_GR_MODPTwo
},
{
kPGPike_AM_DSS_Sig,
kPGPike_HA_SHA1,
kPGPike_SC_CAST_CBC,
TRUE, kPGPike_GR_MODPFive
},
{
kPGPike_AM_DSS_Sig,
kPGPike_HA_SHA1,
kPGPike_SC_3DES_CBC,
TRUE, kPGPike_GR_MODPTwo
},
{
kPGPike_AM_RSA_Sig,
kPGPike_HA_SHA1,
kPGPike_SC_CAST_CBC,
TRUE, kPGPike_GR_MODPFive
},
{
kPGPike_AM_RSA_Sig,
kPGPike_HA_MD5,
kPGPike_SC_3DES_CBC,
TRUE, kPGPike_GR_MODPTwo
},
};
const PGPipsecTransform kPGPike_DefaultIPSECTransforms[] =
{
{ /* ESP, CAST, SHA1 */
TRUE, kPGPike_ET_CAST, 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, kPGPike_AA_HMAC_MD5, kPGPike_PM_None,
FALSE, kPGPike_AH_None, kPGPike_AA_None, kPGPike_PM_None,
FALSE, kPGPike_IC_None,
kPGPike_GR_None
},
{ /* ESP, 3DES, SHA, DEFLATE */
TRUE, kPGPike_ET_3DES, kPGPike_AA_HMAC_SHA, kPGPike_PM_None,
FALSE, kPGPike_AH_None, kPGPike_AA_None, kPGPike_PM_None,
TRUE, kPGPike_IC_Deflate,
kPGPike_GR_None
},
};
const PGPByte dhGenerator[1] = { 2 };
const char kPGPike_PGPVendorString1[] = "OpenPGP1";
const char kPGPike_PGPVendorString2[] = "0171";
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 = PGPGetContextMemoryMgr( 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.tripleDES = TRUE;
pContext->allowedAlgorithms.singleDES = FALSE;
pContext->allowedAlgorithms.espNULL = FALSE;
pContext->allowedAlgorithms.sha1 = 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;
*outRef = ( PGPikeContextRef ) pContext;
}
else
err = kPGPError_OutOfMemory;
done:
if( IsPGPError( err ) && IsntNull( *outRef ) )
{
pgpContextMemFree( context, pContext );
*outRef = NULL;
}
pgpAssertErrWithPtr( err, *outRef );
return err;
}
PGPError
PGPFreeIKEContext(
PGPikeContextRef ref )
{
PGPError err = kPGPError_NoErr;
PGPikeContextPriv * ike;
PGPValidatePtr( ref );
ike = (PGPikeContextPriv *)ref;
if( IsntNull( ike->pending ) )
{
PGPikeDestination * walkD,
* nextD;
pgpAssert( 0 );
/* REPORT THIS ASSERTION AND SUBMIT LOG */
for( walkD = ike->pending; IsntNull( walkD ); walkD = nextD )
{
nextD = walkD->nextD;
(void)PGPFreeData( walkD );
}
}
while( IsntNull( ike->partner ) )
(void)pgpIKEFreePartner( ike->partner );
while( IsntNull( ike->sa ) )
{
PGPikeSA * oldHead = ike->sa;
ike->sa = oldHead->nextSA;
(void)PGPFreeData( oldHead );
}
err = pgpContextMemFree( ike->pgpContext, ike->defaultIKEProps ); CKERR;
err = pgpContextMemFree( ike->pgpContext, ike->defaultIPSECProps ); CKERR;
err = pgpContextMemFree( ike->pgpContext, ref ); CKERR;
done:
return err;
}
PGPError
pgpIKEFreePartner(
PGPikePartner * partner )
{
PGPError err = kPGPError_NoErr;
PGPikePartner * cp,
* lp;
if( partner->ready )
{
err = pgpIKELocalAlert( partner->ike, partner->ipAddress,
kPGPike_AL_None, kPGPike_IA_DeadPhase1SA, FALSE );
}
/* delink ourself */
cp = partner->ike->partner; /* get head of list */
lp = NULL;
while( IsntNull( cp ) )
{
if( cp == partner )
{
if( IsntNull( lp ) )
lp->nextPartner = cp->nextPartner;
else
partner->ike->partner = cp->nextPartner;
break;
}
lp = cp;
cp = cp->nextPartner;
}
while( IsntNull( partner->exchanges ) )
{
err = pgpIKEFreeExchange( partner->exchanges ); CKERR;
}
if( IsntNull( partner->sharedKey ) )
{
err = PGPFreeData( partner->sharedKey ); CKERR;
}
if( PGPKeySetRefIsValid( partner->pgpAuthKey.baseKeySet ) )
{
err = PGPFreeKeySet( partner->pgpAuthKey.baseKeySet ); CKERR;
}
if( PGPKeySetRefIsValid( partner->x509AuthKey.baseKeySet ) )
{
err = PGPFreeKeySet( partner->x509AuthKey.baseKeySet ); CKERR;
}
if( IsntNull( partner->pgpAuthKey.pass ) )
{
err = PGPFreeData( partner->pgpAuthKey.pass ); CKERR;
}
if( IsntNull( partner->x509AuthKey.pass ) )
{
err = PGPFreeData( partner->x509AuthKey.pass ); CKERR;
}
if( IsntNull( partner->ipsecOpts.idData ) )
{
err = PGPFreeData( partner->ipsecOpts.idData ); CKERR;
}
if( PGPCBCContextRefIsValid( partner->cbc ) )
{
err = PGPFreeCBCContext( partner->cbc ); CKERR;
}
if( PGPKeySetRefIsValid( partner->remoteKeySet ) )
{
err = PGPFreeKeySet( partner->remoteKeySet ); CKERR;
}
err = PGPFreeData( partner );
done:
return err;
}
PGPError
pgpIKEFreeExchange(
PGPikeExchange * exchange )
{
PGPError err = kPGPError_NoErr;
PGPikeExchange * cn,
* ln;
PGPikeProposal * cp,
* lp = NULL;
if( IsNull( exchange ) )
goto done;
exchange->ike->numExchanges--;
/* delink ourself */
cn = exchange->partner->exchanges; /* get head of list */
ln = NULL;
while( IsntNull( cn ) )
{
if( cn == exchange )
{
if( IsntNull( ln ) )
ln->nextExchange = cn->nextExchange;
else
exchange->partner->exchanges = cn->nextExchange;
break;
}
ln = cn;
cn = cn->nextExchange;
}
cp = exchange->proposals;
while( IsntNull( cp ) )
{
lp = cp;
cp = cp->nextProposal;
(void)PGPFreeData( lp );
}
if( exchange->dhP != kPGPInvalidBigNumRef )
(void) PGPFreeBigNum( exchange->dhP );
if( exchange->dhG != kPGPInvalidBigNumRef )
(void) PGPFreeBigNum( exchange->dhG );
if( exchange->dhX != kPGPInvalidBigNumRef )
(void) PGPFreeBigNum( exchange->dhX );
if( exchange->dhYi != kPGPInvalidBigNumRef )
(void) PGPFreeBigNum( exchange->dhYi );
if( exchange->dhYr != kPGPInvalidBigNumRef )
(void) PGPFreeBigNum( exchange->dhYr );
if( IsntNull( exchange->gXY ) )
(void) PGPFreeData( exchange->gXY );
if( IsntNull( exchange->initSABody ) )
(void)PGPFreeData( exchange->initSABody );
if( IsntNull( exchange->idBody ) )
(void)PGPFreeData( exchange->idBody );
if( IsntNull( exchange->idRBody ) )
(void)PGPFreeData( exchange->idRBody );
if( IsntNull( exchange->lastPkt ) )
(void)PGPFreeData( exchange->lastPkt );
(void)PGPFreeData( exchange );
done:
return err;
}
PGPError
PGPikeProcessMessage(
PGPikeContextRef ref,
PGPikeMessageType msg,
void * data )
{
PGPError err = kPGPError_NoErr;
PGPikeContextPriv * ike;
PGPValidatePtr( ref );
ike = (PGPikeContextPriv *)ref;
switch( msg )
{
case kPGPike_MT_Idle:
err = pgpIKEIdle( ike );
break;
case kPGPike_MT_SARequest:
err = pgpIKEHandleSARequest( ike, (PGPikeMTSASetup *) data );
break;
case kPGPike_MT_SARekey:
err = pgpIKEHandleSAEvent( ike, FALSE, (PGPikeSA *) data );
break;
case kPGPike_MT_SADied:
err = pgpIKEHandleSAEvent( ike, TRUE, (PGPikeSA *) data );
break;
case kPGPike_MT_Packet:
err = pgpIKEHandlePacket( ike, (PGPikeMTPacket *) data );
#if PGPIKE_DEBUG
/*{
PGPUInt32 saCount = 0;
PGPikeSA * sa;
for( sa = ike->sa; IsntNull( sa ); sa = sa->nextSA )
saCount++;
pgpIKEDebugLog( ike, "\tsaCount: %d\n", saCount );
}*/
#endif
break;
case kPGPike_MT_Pref:
err = pgpIKESetPref( ike, (PGPikeMTPref *) data );
break;
case kPGPike_MT_SAKillAll:
{
PGPikeSA * sa,
* nextSA = NULL;
PGPikePartner * partner;
for( sa = ike->sa; IsntNull( sa ); sa = nextSA )
{
nextSA = sa->nextSA;
sa->activeIn = FALSE;
if( IsntPGPError( pgpIKEFindSAPartner( ike, sa, TRUE, &partner ) ) )
{
err = pgpIKEKillSA( &partner, sa );
}
else
{
err = (ike->msgProc)(
(PGPikeContextRef)ike, ike->userData,
kPGPike_MT_SADied, sa );
(void)pgpIKEFreeSA( ike, sa );
}
if( IsPGPError( err ) )
break;
}
break;
}
case kPGPike_MT_PolicyCheck:
case kPGPike_MT_SAEstablished:
case kPGPike_MT_LocalPGPCert:
case kPGPike_MT_LocalX509Cert:
case kPGPike_MT_RemoteCert:
case kPGPike_MT_Alert:
default:
err = kPGPError_ItemNotFound;/* these msgs are only sent FROM pgpIKE */
break;
}
if( IsPGPError( err ) )
{
if( err == kPGPError_UserAbort )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -