📄 pgpsecsh.c
字号:
session->localKey = inKeyObject;
err = PGPGetKeyDBObjBooleanProperty( session->localKey, kPGPKeyProperty_IsSecret, &secret ); CKERR;
err = PGPGetKeyDBObjBooleanProperty( session->localKey, kPGPKeyProperty_IsDisabled, &disabled ); CKERR;
err = PGPGetKeyDBObjBooleanProperty( session->localKey, kPGPKeyProperty_IsExpired, &expired ); CKERR;
err = PGPGetKeyDBObjBooleanProperty( session->localKey, kPGPKeyProperty_IsRevoked, &revoked ); CKERR;
err = PGPGetKeyDBObjBooleanProperty( session->localKey, kPGPKeyProperty_CanDecrypt, &canDecrypt ); CKERR;
if( !secret || disabled || expired || revoked || !canDecrypt )
{
err = kPGPError_SECSHKeyUnusable;
goto done;
}
err = PGPGetKeyDBObjNumericProperty( session->localKey, kPGPKeyProperty_AlgorithmID, &algID ); CKERR;
if( algID != kPGPPublicKeyAlgorithm_RSA )
{
err = kPGPError_SECSHKeyUnusable;
goto done;
}
err = pgpFindOptionArgs( optionList, kPGPOptionType_Passphrase, FALSE,
"%p%l", &passedPhrase, &passedLength ); CKERR;
if( IsNull( passedPhrase ) )
{
err = pgpFindOptionArgs( optionList, kPGPOptionType_Passkey, FALSE,
"%p%l", &passedPhrase, &passedLength ); CKERR;
session->localKeyPasskeyBuffer = PGPNewSecureData( session->memMgr,
passedLength,
kPGPMemoryMgrFlags_Clear );
if( IsNull( session->localKeyPasskeyBuffer ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
pgpCopyMemory( passedPhrase, session->localKeyPasskeyBuffer,
passedLength );
session->localKeyUsePasskey = TRUE;
}
else
{
session->localKeyPassphrase = PGPNewSecureData( session->memMgr,
passedLength + 1,
kPGPMemoryMgrFlags_Clear );
if( IsNull( session->localKeyPassphrase ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
pgpCopyMemory( passedPhrase, session->localKeyPassphrase,
passedLength );
session->localKeyPassphrase[passedLength] = '\0';
session->localKeyUsePasskey = FALSE;
}
done:
/* do not explicitly free passedPhrase, it is freed with the OptionList */
if( PGPOptionListRefIsValid( optionList ) )
PGPFreeOptionList( optionList );
return err;
}
PGPError
PGPsecshGetRemoteAuthenticatedKey(
PGPsecshSessionRef ref,
PGPKeyDBObjRef * outKey,
PGPKeyDBRef * outKeyDB )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPsecshSessionPriv *) ref;
if( IsntNull( outKey ) )
*outKey = kInvalidPGPKeyDBObjRef;
if( IsntNull( outKeyDB ) )
*outKeyDB = kInvalidPGPKeyDBRef;
if( session->state == kPGPsecsh_ReadyState )
{
PGPKeyDBObjRef hostKey = session->remoteHostKey;
PGPKeyDBRef hostDB = session->remoteHostKeyDB;
/* See if key is present on incoming keyset */
if( PGPKeySetRefIsValid( session->remoteHostLookupKeyset ) )
{
PGPByte hostKeyHash[20];
void * vbuf;
PGPSize vbufSize;
PGPKeyDBObjRef matchKey;
/* We look for key that matches in modulus/exponent */
PGPGetKeyDBObjAllocatedDataProperty( hostKey,
kPGPKeyProperty_KeyData, &vbuf, &vbufSize );
pgpFingerprint20HashBuf( session->pgpContext, vbuf, vbufSize,
hostKeyHash );
PGPFreeData( vbuf );
matchKey = pgpKeyDBFindKey20n( PGPPeekKeySetKeyDB( session->remoteHostLookupKeyset),
hostKeyHash );
if( PGPKeyDBObjRefIsValid( matchKey ) &&
PGPKeySetIsMember( matchKey, session->remoteHostLookupKeyset ) )
{
hostKey = matchKey;
hostDB = PGPPeekKeySetKeyDB( session->remoteHostLookupKeyset);
}
}
if( IsntNull( outKey ) )
*outKey = hostKey;
if( IsntNull( outKeyDB ) )
*outKeyDB = hostDB;
}
else
err = kPGPError_SECSHWrongState;
return err;
}
PGPError
PGPsecshExportPublicKey(
PGPKeyDBObjRef key,
char * userName,
char ** outBuffer,
PGPSize * outLength
)
{
PGPContextRef context;
PGPMemoryMgrRef mgr;
PGPBigNumRef mod, exp;
PGPUInt32 modbits, modlen;
PGPUInt32 expbits, explen;
PGPUInt32 alg;
void * vbuf;
PGPByte * dbuf;
PGPSize dbufLen;
char * buf;
PGPSize bufLen;
PGPUInt32 bufOff;
char tbuf[20];
PGPError err = kPGPError_NoErr;
PGPValidatePtr( key );
PGPValidatePtr( userName );
PGPValidatePtr( outBuffer );
PGPValidatePtr( outLength );
*outBuffer = NULL;
*outLength = 0;
err = PGPGetKeyDBObjNumericProperty( key,
kPGPKeyProperty_AlgorithmID, &alg ); CKERR;
if( alg != kPGPPublicKeyAlgorithm_RSA )
{
err = kPGPError_PublicKeyUnimplemented;
goto done;
}
context = PGPPeekKeyDBObjContext( key );
mgr = PGPPeekContextMemoryMgr( context );
PGPNewBigNum( context, FALSE, &mod );
PGPNewBigNum( context, FALSE, &exp );
PGPGetKeyDBObjAllocatedDataProperty( key, kPGPKeyProperty_KeyData,
&vbuf, &dbufLen );
dbuf = vbuf;
modbits = (dbuf[0]<<8) | dbuf[1];
modlen = (modbits + 7) / 8;
PGPBigNumInsertBigEndianBytes( mod, dbuf+2, 0, modlen );
expbits = (dbuf[modlen+2]<<8) | dbuf[modlen+3];
explen = (expbits + 7) / 8;
PGPBigNumInsertBigEndianBytes( exp, dbuf+2+modlen+2, 0, explen );
PGPFreeData( vbuf );
bufLen = 0;
bufLen += sprintf( tbuf, "%d ", modbits );
bufLen += sPrint10( context, NULL, exp ) + 1;
bufLen += sPrint10( context, NULL, mod ) + 1;
bufLen += strlen(userName) + 1;
buf = (PGPByte *)PGPNewData( mgr, bufLen, 0 );
CKNULL( buf );
bufOff = 0;
bufOff += sprintf( buf+bufOff, "%d ", modbits );
bufOff += sPrint10( context, buf+bufOff, exp );
buf[bufOff++] = ' ';
bufOff += sPrint10( context, buf+bufOff, mod );
buf[bufOff++] = ' ';
pgpCopyMemory( userName, buf+bufOff, strlen(userName) );
bufOff += strlen(userName);
buf[bufOff++] = '\0';
pgpAssert( bufOff == bufLen );
*outBuffer = buf;
*outLength = bufLen - 1; /* Don't count null */
PGPFreeBigNum( mod );
PGPFreeBigNum( exp );
done:
return err;
}
PGPError
PGPNewSECSHContext(
PGPContextRef context,
PGPsecshContextRef * outRef )
{
PGPError err = kPGPError_NoErr;
PGPsecshContextPriv * pContext;
PGPMemoryMgrRef memMgr;
PGPValidatePtr( context );
*outRef = NULL;
memMgr = PGPPeekContextMemoryMgr( context );
pContext = (PGPsecshContextPriv *) PGPNewData( memMgr,
sizeof(PGPsecshContextPriv),
kPGPMemoryMgrFlags_Clear );
if( IsntNull( pContext ) )
{
pContext->pgpContext = context;
*outRef = ( PGPsecshContextRef ) pContext;
}
else
err = kPGPError_OutOfMemory;
pgpAssertErrWithPtr( err, *outRef );
return err;
}
PGPError
PGPFreeSECSHContext(
PGPsecshContextRef ref )
{
PGPValidatePtr( ref );
return PGPFreeData(ref );
}
PGPError
PGPNewSECSHSession(
PGPsecshContextRef ref,
PGPsecshSessionRef * outRef )
{
PGPError err = kPGPError_NoErr;
PGPsecshContextPriv * pContext;
PGPsecshSessionPriv * session;
PGPMemoryMgrRef memMgr;
PGPValidatePtr( ref );
*outRef = NULL;
pContext = ( PGPsecshContextPriv * ) ref;
memMgr = PGPPeekContextMemoryMgr( pContext->pgpContext );
session = ( PGPsecshSessionPriv * ) PGPNewData( memMgr,
sizeof( PGPsecshSessionPriv ),
kPGPMemoryMgrFlags_Clear );
if( IsntNull( session ) )
{
session->pgpContext = pContext->pgpContext;
session->secshContext = pContext;
session->memMgr = memMgr;
session->state = kPGPsecsh_IdleState;
session->intState = 0;
session->isClientSide = TRUE;
session->blocking = TRUE;
session->encrypting = FALSE;
session->writeCipherCBC = kInvalidPGPCBCContextRef;
session->readCipherCBC = kInvalidPGPCBCContextRef;
session->writeCipherCFB = kInvalidPGPCFBContextRef;
session->readCipherCFB = kInvalidPGPCFBContextRef;
session->secshReceiveProc = NULL;
session->secshSendProc = NULL;
session->secshReceiveUserData = NULL;
session->secshSendUserData = NULL;
session->fatalAlert = kPGPsecsh_AT_None;
*outRef = ( PGPsecshSessionRef ) session;
}
else
err = kPGPError_OutOfMemory;
if( IsPGPError( err ) && IsntNull( session ) )
{
PGPFreeData( session );
*outRef = NULL;
}
pgpAssertErrWithPtr( err, *outRef );
return err;
}
PGPError
PGPFreeSECSHSession( PGPsecshSessionRef ref )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPsecshSessionPriv *) ref;
if( IsntNull( session->localKeyPassphrase ) )
(void)PGPFreeData( session->localKeyPassphrase );
if( IsntNull( session->localKeyPasskeyBuffer ) )
(void)PGPFreeData( session->localKeyPasskeyBuffer );
if( IsntNull( session->userName ) )
(void)PGPFreeData( session->userName );
if( IsntNull( session->hostName ) )
(void)PGPFreeData( session->hostName );
if( PGPKeyDBRefIsValid( session->remoteHostKeyDB ) )
(void)PGPFreeKeyDB( session->remoteHostKeyDB );
if( PGPKeyDBRefIsValid( session->remoteServerKeyDB ) )
(void)PGPFreeKeyDB( session->remoteServerKeyDB );
if( PGPCBCContextRefIsValid( session->writeCipherCBC ) )
(void)PGPFreeCBCContext( session->writeCipherCBC );
if( PGPCBCContextRefIsValid( session->readCipherCBC ) )
(void)PGPFreeCBCContext( session->readCipherCBC );
if( PGPCFBContextRefIsValid( session->writeCipherCFB ) )
(void)PGPFreeCFBContext( session->writeCipherCFB );
if( PGPCFBContextRefIsValid( session->readCipherCFB ) )
(void)PGPFreeCFBContext( session->readCipherCFB );
if( IsntNull( session->queuedSendData ) )
(void)PGPFreeData( session->queuedSendData );
if( IsntNull( session->rcvdRawData ) )
(void)PGPFreeData( session->rcvdRawData );
err = PGPFreeData( session );
return err;
}
PGPError
PGPsecshClose(
PGPsecshSessionRef ref,
PGPBoolean dontCache )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPsecshSessionPriv *) ref;
if( session->state == kPGPsecsh_ReadyState )
{
PGPByte closePkt[] = { 0, 0, 0, 0 };
(void) pgpSECSHSendPacket( session, kPGPsecsh_Msg_Disconnect,
closePkt, sizeof(closePkt) );
}
if( session->state != kPGPsecsh_FatalErrorState )
session->state = kPGPsecsh_ClosedState;
return err;
}
PGPError
PGPsecshSetReceiveCallback(
PGPsecshSessionRef ref,
PGPsecshReceiveProcPtr secshReceiveProc,
void * inData )
{
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
PGPValidatePtr( secshReceiveProc );
session = (PGPsecshSessionPriv *) ref;
session->secshReceiveProc = secshReceiveProc;
session->secshReceiveUserData = inData;
return kPGPError_NoErr;
}
PGPError
PGPsecshSetSendCallback(
PGPsecshSessionRef ref,
PGPsecshSendProcPtr secshSendProc,
void * inData )
{
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
PGPValidatePtr( secshSendProc );
session = (PGPsecshSessionPriv *) ref;
session->secshSendProc = secshSendProc;
session->secshSendUserData = inData;
return kPGPError_NoErr;
}
PGPError
PGPsecshReceive(
PGPsecshSessionRef ref,
PGPByte * outType,
void ** outBuffer,
PGPSize * bufferSize )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPByte pktType;
PGPByte * buffer = NULL;
PGPSize pktLen;
PGPValidatePtr( ref );
PGPValidatePtr( outBuffer );
session = (PGPsecshSessionPriv *) ref;
PGPValidatePtr( session->secshReceiveProc );
*outType = 0;
*outBuffer = NULL;
*bufferSize = 0;
if( session->state != kPGPsecsh_ReadyState )
{
err = kPGPError_SECSHWrongState;
goto done;
}
err = pgpSECSHReceivePacket( session, &pktType, &buffer, &pktLen ); CKERR;
*outType = pktType;
*outBuffer = buffer;
*bufferSize = pktLen;
done:
return err;
}
PGPError
PGPsecshSend(
PGPsecshSessionRef ref,
PGPByte pktType,
const void * inBuffer,
PGPSize inBufferLength )
{
PGPError err = kPGPError_NoErr;
PGPsecshSessionPriv * session;
PGPValidatePtr( ref );
PGPValidatePtr( inBuffer );
session = (PGPsecshSessionPriv *) ref;
PGPValidatePtr( session->secshSendProc );
if( session->state != kPGPsecsh_ReadyState )
{
err = kPGPError_SECSHWrongState;
goto done;
}
err = pgpSECSHSendPacket( session, pktType,
(PGPByte *)inBuffer, inBufferLength );
done:
return err;
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -