📄 pgptls.c
字号:
PGPFreeTLSSession( PGPtlsSessionRef ref )
{
PGPError err = kPGPError_NoErr;
PGPtlsSessionPriv * session;
PGPValidatePtr( ref );
session = (PGPtlsSessionPriv *) ref;
if( session->state == kPGPtls_ClosedState )
{
/* Cache the session if applicable */
/* ##### */
}
if( IsntNull( session->localKeyPassphrase ) )
(void)PGPFreeData( session->localKeyPassphrase );
if( IsntNull( session->localKeyPasskeyBuffer ) )
(void)PGPFreeData( session->localKeyPasskeyBuffer );
if( PGPKeySetRefIsValid( session->remoteKeySet ) )
(void)PGPFreeKeySet( session->remoteKeySet );
if( PGPHashContextRefIsValid( session->handshakeSHA ) )
(void)PGPFreeHashContext( session->handshakeSHA );
if( PGPHashContextRefIsValid( session->handshakeMD5 ) )
(void)PGPFreeHashContext( session->handshakeMD5 );
if( PGPHashContextRefIsValid( session->lastHandSHA ) )
(void)PGPFreeHashContext( session->lastHandSHA );
if( PGPHashContextRefIsValid( session->lastHandMD5 ) )
(void)PGPFreeHashContext( session->lastHandMD5 );
if( PGPHashContextRefIsValid( session->innerMACHash ) )
(void)PGPFreeHashContext( session->innerMACHash );
if( PGPHashContextRefIsValid( session->outerMACHash ) )
(void)PGPFreeHashContext( session->outerMACHash );
if( PGPCBCContextRefIsValid( session->writeCipher ) )
(void)PGPFreeCBCContext( session->writeCipher );
if( PGPCBCContextRefIsValid( session->readCipher ) )
(void)PGPFreeCBCContext( session->readCipher );
if( IsntNull( session->writeActive ) )
{
if( PGPHMACContextRefIsValid( session->writeActive->hmac ) )
(void)PGPFreeHMACContext( session->writeActive->hmac );
(void)PGPFreeData( session->writeActive );
}
if( IsntNull( session->readActive ) )
{
if( PGPHMACContextRefIsValid( session->readActive->hmac ) )
(void)PGPFreeHMACContext( session->readActive->hmac );
(void)PGPFreeData( session->readActive );
}
if( IsntNull( session->clientPending ) )
(void)PGPFreeData( session->clientPending );
if( IsntNull( session->serverPending ) )
(void)PGPFreeData( session->serverPending );
if( IsntNull( session->queuedSendData ) )
(void)PGPFreeData( session->queuedSendData );
if( IsntNull( session->rcvdRawData ) )
(void)PGPFreeData( session->rcvdRawData );
if( IsntNull( session->rcvdAppData ) )
(void)PGPFreeData( session->rcvdAppData );
if( IsntNull( session->rcvdHandData ) )
(void)PGPFreeData( session->rcvdHandData );
if( session->dhP != kPGPInvalidBigNumRef )
{
err = PGPFreeBigNum( session->dhP );
pgpAssertNoErr( err );
}
if( session->dhG != kPGPInvalidBigNumRef )
{
err = PGPFreeBigNum( session->dhG );
pgpAssertNoErr( err );
}
if( session->dhYs != kPGPInvalidBigNumRef )
{
err = PGPFreeBigNum( session->dhYs );
pgpAssertNoErr( err );
}
if( session->dhX != kPGPInvalidBigNumRef )
{
err = PGPFreeBigNum( session->dhX );
pgpAssertNoErr( err );
}
if( session->dhYc != kPGPInvalidBigNumRef )
{
err = PGPFreeBigNum( session->dhYc );
pgpAssertNoErr( err );
}
if( IsntNull( session->cipherSuites ) )
(void)PGPFreeData( session->cipherSuites );
err = pgpContextMemFree( session->pgpContext, session );
return err;
}
PGPError
pgpTLSBufferRawData(
PGPtlsSessionPriv * session,
PGPByte * rawData,
PGPSize rawDataSize )
{
PGPError err = kPGPError_NoErr;
err = pgpContextMemRealloc( session->pgpContext,
(void **) &session->rcvdRawData,
session->rawDataSize + rawDataSize, 0 ); CKERR;
pgpCopyMemory( rawData, session->rcvdRawData + session->rawDataSize,
rawDataSize );
session->rawDataSize += rawDataSize;
done:
return err;
}
PGPError
pgpTLSExtractRawData(
PGPtlsSessionPriv * session,
PGPByte * rawData,
PGPSize * rawDataSize )
{
PGPError err = kPGPError_NoErr;
PGPSize maxSize = *rawDataSize;
*rawDataSize = 0;
if( ( maxSize > 0 ) && ( session->rawDataSize > 0 ) )
{
if( maxSize > session->rawDataSize )
maxSize = session->rawDataSize;
pgpCopyMemory( session->rcvdRawData, rawData, maxSize );
*rawDataSize = maxSize;
pgpCopyMemory( session->rcvdRawData + maxSize,
session->rcvdRawData, session->rawDataSize - maxSize );
session->rawDataSize -= maxSize;
err = pgpContextMemRealloc( session->pgpContext,
(void **) &session->rcvdRawData,
session->rawDataSize, 0 ); CKERR;
}
done:
return err;
}
PGPError
pgpTLSBufferHandData(
PGPtlsSessionPriv * session,
PGPByte * handData,
PGPSize handDataSize )
{
PGPError err = kPGPError_NoErr;
err = pgpContextMemRealloc( session->pgpContext,
(void **) &session->rcvdHandData,
session->handDataSize + handDataSize, 0 ); CKERR;
pgpCopyMemory( handData, session->rcvdHandData + session->handDataSize,
handDataSize );
session->handDataSize += handDataSize;
done:
return err;
}
PGPError
pgpTLSExtractHandData(
PGPtlsSessionPriv * session,
PGPByte ** handData,
PGPSize * handDataSize )
{
PGPError err = kPGPError_NoErr;
if( session->handDataSize > 0 )
{
err = pgpContextMemRealloc( session->pgpContext,
(void **) handData,
*handDataSize + session->handDataSize, 0 ); CKERR;
pgpCopyMemory( *handData, *handData + session->handDataSize, *handDataSize );
pgpCopyMemory( session->rcvdHandData, *handData, session->handDataSize );
*handDataSize += session->handDataSize;
session->handDataSize = 0;
}
done:
return err;
}
PGPError
pgpTLSBufferSendData(
PGPtlsSessionPriv * session,
PGPByte * sendData,
PGPSize sendDataSize )
{
PGPError err = kPGPError_NoErr;
err = pgpContextMemRealloc( session->pgpContext,
(void **) &session->queuedSendData,
session->queuedSendSize + sendDataSize, 0 ); CKERR;
pgpCopyMemory( sendData, session->queuedSendData + session->queuedSendSize,
sendDataSize );
session->queuedSendSize += sendDataSize;
done:
return err;
}
PGPError
pgpTLSReceiveRecordLayer(
PGPtlsSessionPriv * session,
PGPByte * outType,
PGPByte ** outBuffer,
PGPSize * outLength )
{
PGPError err = kPGPError_NoErr;
PGPError rerr = kPGPError_NoErr;
PGPByte header[kPGPtls_RecordHeaderSize];
PGPByte * buffer = NULL;
PGPSize rcvd;
PGPUInt16 length;
PGPInt32 bytesRead;
*outType = 0;
*outBuffer = NULL;
*outLength = 0;
rcvd = kPGPtls_RecordHeaderSize;
err = pgpTLSExtractRawData( session, header, &rcvd ); CKERR;
for(; rcvd < kPGPtls_RecordHeaderSize; rcvd += bytesRead)
{
bytesRead = (session->tlsReceiveProc)( session->tlsReceiveUserData,
header + rcvd,
(PGPInt32)( kPGPtls_RecordHeaderSize - rcvd ) );
if( bytesRead < 0 )
{
if( bytesRead != kPGPError_TLSWouldBlock )
{
FATALTLS( kPGPError_TLSUnexpectedClose );
}
else
{
rerr = kPGPError_TLSWouldBlock;
bytesRead = 0;
}
}
if( bytesRead == 0 )
{
if( session->blocking )
{
FATALTLS( kPGPError_TLSUnexpectedClose );
}
else
{
if( rcvd )
{
err = pgpTLSBufferRawData( session, header, rcvd ); CKERR;
if(rerr == kPGPError_TLSWouldBlock)
/* check to see if receive call returned a blocking error */
{
err = kPGPError_TLSWouldBlock;
}
}
else if(rerr == kPGPError_TLSWouldBlock)
/* check for blocking error */
{
err = kPGPError_TLSWouldBlock;
}
goto done;
}
}
}
pgpAssert( rcvd == kPGPtls_RecordHeaderSize );
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
/* Check for SSLv2 packet. */
if( ( session->state == kPGPtls_HandshakeState ) &&
( (header[0] & 0x80) == 0x80 ) && ( header[2] == 0x01 ) )
{
PGPByte sslv2LenHi;
PGPByte sslv2LenLo;
PGPUInt16 sslv2Len;
/* Grab the v2 length packet, subtract 3, put it back in 2 bytes. */
sslv2LenHi = header[0] & 0x7f;
sslv2LenLo = header[1];
sslv2Len = (sslv2LenHi << 8) | sslv2LenLo;
sslv2Len -= 3;
sslv2LenHi = sslv2Len >> 8;
sslv2LenLo = sslv2Len & 0x00ff;
header[0] = kPGPtls_RT_Handshake;
header[1] = header[3]; /* Major Version */
header[2] = header[4]; /* Minor Version */
header[3] = sslv2LenHi;
header[4] = sslv2LenLo;
session->sslv2Hello = 1;
session->sslv2MajorVersion = header[1];
session->sslv2MinorVersion = header[2];
}
#endif
switch( header[0] )
{
case kPGPtls_RT_ChangeCipherSpec:
case kPGPtls_RT_Alert:
case kPGPtls_RT_Handshake:
case kPGPtls_RT_ApplicationData:
break;
default:
/* Unknown Record Type, illegal, abort protocol */
(void)pgpTLSSendAlert( session, kPGPtls_AL_FatalAlert,
kPGPtls_AT_UnexpectedMessage );
FATALTLS( kPGPError_TLSProtocolViolation );
}
if( header[1] != kPGPtls_MajorVersion )
{
(void)pgpTLSSendAlert( session, kPGPtls_AL_FatalAlert,
kPGPtls_AT_ProtocolVersion );
FATALTLS( kPGPError_TLSVersionUnsupported );
}
length = PGPEndianToUInt16( kPGPBigEndian, &header[3] );
if( length <= 0 || length > kPGPtls_MaximumPacketSize )
{
(void)pgpTLSSendAlert( session, kPGPtls_AL_FatalAlert,
kPGPtls_AT_DecodeError );
FATALTLS( kPGPError_TLSProtocolViolation );
}
buffer = (PGPByte *) pgpContextMemAlloc(session->pgpContext, length, 0 );
if( IsNull( buffer ) )
{
err = kPGPError_OutOfMemory;
goto done;
}
rcvd = length;
err = pgpTLSExtractRawData( session, buffer, &rcvd ); CKERR;
for(; rcvd < length; rcvd += bytesRead)
{
bytesRead = (session->tlsReceiveProc)( session->tlsReceiveUserData,
buffer + rcvd, (PGPInt32)( length - rcvd ) );
if( bytesRead < 0 )
{
if( bytesRead != kPGPError_TLSWouldBlock )
{
(void)pgpContextMemFree( session->pgpContext, buffer );
buffer = NULL;
FATALTLS( kPGPError_TLSUnexpectedClose );
}
else
{
bytesRead = 0;
rerr = kPGPError_TLSWouldBlock;
}
}
if( bytesRead == 0 )
{
if( session->blocking )
{
FATALTLS( kPGPError_TLSUnexpectedClose );
}
else
{
if( rcvd )
{
err = pgpTLSBufferRawData( session, header,
kPGPtls_RecordHeaderSize );CKERR;
err = pgpTLSBufferRawData( session, buffer, rcvd ); CKERR;
}
if(rerr == kPGPError_TLSWouldBlock)
err = kPGPError_TLSWouldBlock;
(void)pgpContextMemFree( session->pgpContext, buffer );
buffer = NULL;
goto done;
}
}
}
pgpAssert( rcvd == length );
if( IsntNull( session->readActive ) )
{
PGPByte macCheck[32];
if( PGPCBCContextRefIsValid( session->readCipher ) )
{
err = PGPCBCDecrypt( session->readCipher, buffer, length, buffer );
CKERR;
length -= ( buffer[length - 1] + 1 );
}
length -= session->hashSize;
if( length > kPGPtls_MaximumPacketSize )
{
(void)pgpTLSSendAlert( session, kPGPtls_AL_FatalAlert,
kPGPtls_AT_DecodeError );
FATALTLS( kPGPError_TLSProtocolViolation );
}
err = pgpTLSCalculateMAC( session, FALSE, header[0], buffer, length,
macCheck ); CKERR;
if( !pgpMemoryEqual( macCheck, buffer + length, session->hashSize ) )
{
(void)pgpTLSSendAlert( session, kPGPtls_AL_FatalAlert,
kPGPtls_AT_BadRecordMAC );
FATALTLS( kPGPError_TLSProtocolViolation );
}
}
*outType = header[0];
*outBuffer = buffer;
*outLength = length;
done:
if( IsPGPError( err ) && IsntNull( buffer ) )
{
(void)pgpContextMemFree( session->pgpContext, buffer );
*outBuffer = NULL;
}
return err;
}
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
PGPError
pgpConvertV2HelloToV3Hello(
PGPtlsSessionPriv * session,
PGPByte * inBuffer,
PGPSize inBufferLen,
PGPByte ** outBuffer,
PGPSize * outBufferLen )
{
PGPError err = kPGPError_NoErr;
PGPUInt32 i;
PGPUInt32 offset;
PGPByte * buffer = NULL;
PGPUInt32 packetLenOffset;
PGPUInt16 v2CipherSuiteLen;
PGPUInt16 v2SessionIDLen;
PGPUInt16 v2RandomLen;
PGPUInt32 v3HelloPacketLen;
PGPUInt32 cipherSuiteLenOffset;
PGPUInt16 cipherSuiteLen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -