📄 pgpsecsh.c
字号:
PGPFreePrivateKeyContext( privKeyCon );
privKeyCon = kInvalidPGPPrivateKeyContextRef;
if( bufSize > 32 )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
payload = (PGPByte *)PGPNewData( session->memMgr, kPGPsecsh_SessionIDSize, 0 );
CKNULL( payload );
err = PGPNewHashContext( session->pgpContext, kPGPHashAlgorithm_MD5,
&handshakeMD5 ); CKERR;
PGPContinueHash( handshakeMD5, decryptBuf, bufSize );
PGPContinueHash( handshakeMD5, session->sessionID, kPGPsecsh_SessionIDSize );
PGPFinalizeHash( handshakeMD5, payload );
PGPFreeHashContext( handshakeMD5 );
handshakeMD5 = kInvalidPGPHashContextRef;
err = pgpSECSHSendPacket( session, kPGPsecsh_CMsg_AuthRSAResponse,
payload, kPGPsecsh_SessionIDSize ); CKERR;
done:
if( IsntNull( payload ) )
PGPFreeData( payload );
if( IsntNull( decryptBuf ) )
PGPFreeData( decryptBuf );
if( PGPPrivateKeyContextRefIsValid( privKeyCon ) )
PGPFreePrivateKeyContext( privKeyCon );
if( PGPHashContextRefIsValid( handshakeMD5 ) )
PGPFreeHashContext( handshakeMD5 );
return err;
}
PGPError
pgpSECSHReceivePublicKey(
PGPsecshSessionPriv * session,
const PGPByte * inBuffer,
PGPSize inLength )
{
PGPError err = kPGPError_NoErr;
PGPHashContextRef handshakeMD5 = kInvalidPGPHashContextRef;
PGPUInt16 pktInx = 0;
PGPUInt32 sbits;
PGPUInt32 hbits;
PGPUInt16 sKeyOff;
PGPUInt16 hKeyOff;
PGPSize ilen;
/* First read cookie */
if( (PGPSize)(pktInx + kPGPsecsh_CookieSize) > inLength )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
pgpCopyMemory( (PGPByte *)inBuffer+pktInx, session->cookie, kPGPsecsh_CookieSize );
pktInx += kPGPsecsh_CookieSize;
/* Server key bits */
if( pktInx + sizeof(PGPUInt32) > inLength )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
sbits = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
pktInx += sizeof(PGPUInt32);
/* Server key data */
err = sDataToPGPKey( session, (PGPByte *)inBuffer+pktInx, inLength-pktInx,
&ilen, &session->remoteServerKeyDB,
&session->remoteServerKey ); CKERR;
pktInx += ilen;
sKeyOff = pktInx - (sbits+7)/8;
/* Host key bits */
if( pktInx + sizeof(PGPUInt32) > inLength )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
hbits = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
pktInx += sizeof(PGPUInt32);
/* Server key data */
err = sDataToPGPKey( session, (PGPByte *)inBuffer+pktInx, inLength-pktInx,
&ilen, &session->remoteHostKeyDB,
&session->remoteHostKey ); CKERR;
pktInx += ilen;
hKeyOff = pktInx - (hbits+7)/8;
/* Protocol flags, cipher mask, auth mask */
if( pktInx + 3*sizeof(PGPUInt32) > inLength )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
session->remoteProtocolFlags = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx);
pktInx += sizeof(PGPUInt32);
session->cipherMask = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
pktInx += sizeof(PGPUInt32);
session->authMask = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
pktInx += sizeof(PGPUInt32);
/* Calculate session ID */
err = PGPNewHashContext( session->pgpContext, kPGPHashAlgorithm_MD5,
&handshakeMD5 ); CKERR;
PGPContinueHash( handshakeMD5, inBuffer+hKeyOff, (hbits+7)/8 );
PGPContinueHash( handshakeMD5, inBuffer+sKeyOff, (sbits+7)/8 );
PGPContinueHash( handshakeMD5, session->cookie, kPGPsecsh_CookieSize );
PGPFinalizeHash( handshakeMD5, session->sessionID );
PGPFreeHashContext( handshakeMD5 );
handshakeMD5 = kInvalidPGPHashContextRef;
err = PGPNewPublicKeyContext( session->remoteServerKey,
kPGPPublicKeyMessageFormat_PKCS1,
&session->remoteServerKeyContext ); CKERR;
err = PGPNewPublicKeyContext( session->remoteHostKey,
kPGPPublicKeyMessageFormat_PKCS1,
&session->remoteHostKeyContext ); CKERR;
err = pgpSECSHSendSessionKey( session ); CKERR;
done:
if( PGPHashContextRefIsValid( handshakeMD5 ) )
PGPFreeHashContext( handshakeMD5 );
return err;
}
PGPError
pgpSECSHReceiveRSAChallenge(
PGPsecshSessionPriv * session,
const PGPByte * inBuffer,
PGPSize inLength )
{
PGPError err = kPGPError_NoErr;
PGPByte * rsaChallenge = NULL;
PGPUInt16 pktInx = 0;
PGPUInt16 chalBits;
PGPSize chalSize;
chalBits = (inBuffer[pktInx] << 8) + inBuffer[pktInx+1];
chalSize = (chalBits + 7) / 8;
pktInx += 2;
if( inLength != (PGPSize) (chalSize + pktInx) )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_DecodeError );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
rsaChallenge = (PGPByte *)PGPNewData( session->memMgr, chalSize, 0 );
CKNULL( rsaChallenge );
pgpCopyMemory( inBuffer+pktInx, rsaChallenge, chalSize );
err = pgpSECSHSendRSAResponse( session, rsaChallenge, chalSize ); CKERR;
done:
if( IsntNull( rsaChallenge ) )
PGPFreeData( rsaChallenge );
return err;
}
PGPError
pgpSECSHReceiveDebug(
PGPsecshSessionPriv * session,
const PGPByte * inBuffer,
PGPSize inLength )
{
PGPError err = kPGPError_NoErr;
PGPUInt16 pktInx = 0;
PGPUInt32 strCount;
/* Read count of characters */
strCount = PGPEndianToUInt32( kPGPBigEndian, inBuffer+pktInx );
pktInx += sizeof(PGPUInt32);
if( strCount > inLength - pktInx )
strCount = inLength - pktInx;
#if PGP_DEBUG
{
char *str = PGPNewData( session->memMgr, strCount+1, 0 );
pgpCopyMemory( inBuffer+pktInx, str, strCount );
str[strCount] = 0;
pgpDebugFmtMsg((pgpaFmtPrefix, "SECSH debug message: %s\n", str ));
PGPFreeData( str );
}
#endif
return err;
}
/* Receive a success/failure message. State has already changed. */
PGPError
pgpSECSHReceiveSuccessFail(
PGPsecshSessionPriv * session,
const PGPByte * inBuffer,
PGPSize inLength )
{
(void) inBuffer;
(void) inLength;
if( session->intState == 2 )
pgpSECSHSendUserName( session );
else if( session->intState == 3 )
pgpSECSHSendRSAChallengeRequest( session );
else
pgpAssert( 0 );
return kPGPError_NoErr;
}
PGPError
pgpSECSHAlert(
PGPsecshSessionPriv * session,
PGPByte level,
PGPsecshAlert type )
{
PGPError err = kPGPError_NoErr;
if( level == kPGPsecsh_AL_FatalAlert )
{
session->state = kPGPsecsh_FatalErrorState;
session->fatalAlert = type;
}
return err;
}
PGPInt8
pgpSECSHPacketToEvent(
PGPByte packetType )
{
PGPInt8 event = 0;
switch( packetType )
{
case kPGPsecsh_SMsg_PublicKey:
event = kPGPsecsh_EV_ReceiveServerPublicKey;
break;
case kPGPsecsh_SMsg_AuthRSAChallenge:
event = kPGPsecsh_EV_ReceiveRSAChallenge;
break;
case kPGPsecsh_SMsg_Success:
event = kPGPsecsh_EV_ReceiveSuccess;
break;
case kPGPsecsh_SMsg_Failure:
event = kPGPsecsh_EV_ReceiveFailure;
break;
case kPGPsecsh_SMsg_Debug:
event = kPGPsecsh_EV_ReceiveDebug;
break;
default:
event = kPGPsecsh_EV_ReceiveUnknownPacket;
break;
}
return event;
}
PGPError
pgpSECSHClientHandshake(
PGPsecshSessionPriv * session )
{
PGPError err = kPGPError_NoErr;
PGPByte pktType;
PGPByte * packet = NULL;
PGPSize pktLen;
PGPInt8 newState;
PGPByte serverMajor;
PGPByte serverMinor;
PGPBoolean handshaking = TRUE;
if( ( session->state == kPGPsecsh_IdleState ) ||
( session->state == kPGPsecsh_ReadyState ) )
{
session->state = kPGPsecsh_HandshakeState;
err = pgpSECSHReceiveServerVersion( session, &serverMajor,
&serverMinor );
if( IsPGPError( err ) )
goto done;
if( serverMajor > 1 )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_UnsupportedVersion );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
err = pgpSECSHSendRawData( session, SECSHID, strlen( SECSHID ) );
if( IsPGPError( err ) )
goto done;
}
while( handshaking &&
IsntPGPError( err = pgpSECSHReceivePacket( session,
&pktType, &packet, &pktLen ) ) && IsntNull( packet ) )
{
newState = pgpSECSHNextState( session, pgpSECSHPacketToEvent( pktType ) );
if( newState == -2 )
{
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_UnexpectedMessage );
FATALSECSH( kPGPError_SECSHProtocolViolation );
}
else if( newState == -1 )
{
/* do nothing */
}
else if( newState == SECSHNUMCLIENTSTATES )
{
session->state = kPGPsecsh_ReadyState;
handshaking = FALSE;
}
else switch( pktType )
{
case kPGPsecsh_SMsg_PublicKey:
err = pgpSECSHReceivePublicKey( session, packet, pktLen );
break;
case kPGPsecsh_SMsg_Success:
case kPGPsecsh_SMsg_Failure:
err = pgpSECSHReceiveSuccessFail( session, packet, pktLen );
break;
case kPGPsecsh_SMsg_AuthRSAChallenge:
err = pgpSECSHReceiveRSAChallenge( session, packet, pktLen );
break;
case kPGPsecsh_SMsg_Debug:
err = pgpSECSHReceiveDebug( session, packet, pktLen );
break;
default:
pgpAssert( 0 );
}
(void)PGPFreeData( packet );
packet = NULL;
if( IsPGPError( err ) )
goto done;
if( !session->blocking )
break;
}
done:
if( IsntNull( packet ) )
(void)PGPFreeData( packet );
return err;
}
PGPError
PGPsecshHandshake(
PGPsecshSessionRef ref )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPsecshSessionPriv *) ref;
PGPValidatePtr( session->secshReceiveProc );
PGPValidatePtr( session->secshSendProc );
if( ( session->state != kPGPsecsh_ReadyState ) &&
( session->state != kPGPsecsh_IdleState ) &&
( ( session->state != kPGPsecsh_HandshakeState ) ||
session->blocking ) )
{
err = kPGPError_SECSHWrongState;
goto done;
}
/*
if( session->isClientSide )
err = pgpSECSHClientHandshake( session );
else
err = pgpSECSHServerHandshake( session );
*/
err = pgpSECSHClientHandshake( session );
if(err == kPGPError_SECSHWouldBlock)
return kPGPError_NoErr;
if( IsPGPError( err ) && session->state != kPGPsecsh_FatalErrorState )
(void)pgpSECSHAlert( session, kPGPsecsh_AL_FatalAlert,
kPGPsecsh_AT_InternalError );
done:
return err;
}
PGPError
PGPsecshSetProtocolOptions(
PGPsecshSessionRef ref,
PGPsecshFlags options,
PGPsecshProtocolFlags pflags )
{
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPsecshSessionPriv *) ref;
if( options & kPGPsecshFlags_ServerSide )
session->isClientSide = FALSE;
if( options & kPGPsecshFlags_ClientSide )
session->isClientSide = TRUE;
if( options & kPGPsecshFlags_NonBlockingIO )
session->blocking = FALSE;
session->localProtocolFlags = (PGPUInt32) pflags;
return kPGPError_NoErr;
}
static const PGPOptionType sSECSHOptionSet[] =
{
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey
};
PGPError
PGPsecshSetLocalPrivateKey(
PGPsecshSessionRef ref,
char * inUserName,
PGPKeyDBObjRef inKeyObject,
char * inHostName,
PGPKeySetRef inHostKeys,
PGPOptionListRef firstOption,
... )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPBoolean secret,
disabled,
revoked,
expired,
canDecrypt;
PGPInt32 algID;
void *passedPhrase = NULL;
PGPSize passedLength;
PGPOptionListRef optionList = kInvalidPGPOptionListRef;
va_list args;
PGPUInt32 userNameLen;
PGPUInt32 hostNameLen;
PGPValidatePtr( ref );
PGPValidatePtr( inKeyObject );
session = (PGPsecshSessionPriv *) ref;
userNameLen = strlen( inUserName );
session->userName = (char *)PGPNewData( session->memMgr, userNameLen, 0 );
CKNULL( session->userName );
pgpCopyMemory( inUserName, session->userName, userNameLen+1 );
hostNameLen = strlen( inHostName );
session->hostName = (char *)PGPNewData( session->memMgr, hostNameLen, 0 );
CKNULL( session->hostName );
pgpCopyMemory( inHostName, session->hostName, hostNameLen+1 );
session->remoteHostLookupKeyset = inHostKeys;
va_start( args, firstOption );
optionList = pgpBuildOptionListArgs(session->pgpContext,
FALSE, firstOption, args);
va_end( args );
pgpAssert( pgpOptionListIsValid( optionList ) );
err = pgpGetOptionListError( optionList ); CKERR;
err = pgpCheckOptionsInSet( optionList, sSECSHOptionSet,
sizeof(sSECSHOptionSet) / sizeof(PGPOptionType) ); CKERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -