⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgptls.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -