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

📄 pgptls.c

📁 pgp soucecode pgp soucecode
💻 C
📖 第 1 页 / 共 5 页
字号:
	*outBuffer	= NULL;
	*outBufferLen = 0;

	v2CipherSuiteLen = (inBuffer[0] << 8) | inBuffer[1];
	v2SessionIDLen = (inBuffer[2] << 8) | inBuffer[3];
	v2RandomLen = (inBuffer[4] << 8) | inBuffer[5];

	if( v2CipherSuiteLen + v2SessionIDLen + v2RandomLen + 6ul != inBufferLen )
	{
		err = kPGPError_BufferTooSmall;
		goto done;
	}

	/* 2 + 32 + 1 + (2 + # cipher suites * 2) + (1 + # compression methods) */
	v3HelloPacketLen = 38 + (v2CipherSuiteLen / 3) * 2;

	buffer = (PGPByte *) pgpContextMemAlloc(session->pgpContext, 
											v3HelloPacketLen + 4, 0 );
	if( IsNull( buffer ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}

	offset = 0;
	buffer[offset++] = kPGPtls_HT_ClientHello;

	/* Skip the packet length */
	packetLenOffset = offset;
	offset += 3;

	buffer[offset++] = session->sslv2MajorVersion;
	buffer[offset++] = session->sslv2MinorVersion;

	/* Copy over random data.  Use low 32 bytes of v2, right justified, */
	/*   zero filled. */
	pgpFillMemory(&buffer[offset], 32, 0);
	if( v2RandomLen <= 32 )
		pgpCopyMemory(&inBuffer[6 + v2CipherSuiteLen + v2SessionIDLen],
				   &buffer[offset + (32 - v2RandomLen)], v2RandomLen);
	else
		pgpCopyMemory(&inBuffer[6 + v2CipherSuiteLen + v2SessionIDLen],
				   &buffer[offset + 32], 32);
	offset += 32;

	/* Always use a zero session ID. */
	buffer[offset++] = 0;

	/* Hold a spot for the cipher suite length */
	cipherSuiteLenOffset = offset;
	offset += 2;

	/* Translate the cipher suites. */
	for( i = 0; i < v2CipherSuiteLen; i += 3 )
	{
		if( inBuffer[6 + i] == 0x00 )
		{
			buffer[offset++] = inBuffer[6 + i + 1];
			buffer[offset++] = inBuffer[6 + i + 2];
		}
		else if( inBuffer[6 + i] == 0x01 && inBuffer[6 + i + 1] == 0x00 &&
				 inBuffer[6 + i + 2] == 0x80 )
		{
			/* SSL_RSA_WITH_RC4_128_MD5 */
			buffer[offset++] = 0x00;
			buffer[offset++] = 0x04;
		}
		else if( inBuffer[6 + i] == 0x02 && inBuffer[6 + i + 1] == 0x00 &&
				 inBuffer[6 + i + 2] == 0x80 )
		{
			/* SSL_RSA_EXPORT_WITH_RC4_40_MD5 */
			buffer[offset++] = 0x00;
			buffer[offset++] = 0x03;
		}
		else if( inBuffer[6 + i] == 0x04 && inBuffer[6 + i + 1] == 0x00 &&
				 inBuffer[6 + i + 2] == 0x80 )
		{
			/* SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
			buffer[offset++] = 0x00;
			buffer[offset++] = 0x06;
		}
	}

	/* Now that we know the length, place it before the ciphers. */
	cipherSuiteLen = offset - cipherSuiteLenOffset - 2;
	buffer[cipherSuiteLenOffset] = cipherSuiteLen >> 8;
	buffer[cipherSuiteLenOffset + 1] = cipherSuiteLen & 0xff;

	/* Use zero compression methods. */
	buffer[offset++] = 0;

	/* Fill in the whole packet length */
	buffer[packetLenOffset] = (offset >> 16) & 0xff;
	buffer[packetLenOffset + 1] = (offset >> 8) & 0xff;
	buffer[packetLenOffset + 2] = offset & 0xff;

	*outBuffer = buffer;
	*outBufferLen = offset;
done:
	if( IsPGPError( err ) && IsntNull( buffer ) )
	{
		(void)pgpContextMemFree( session->pgpContext, buffer );
		*outBuffer = NULL;
		*outBufferLen = 0;
	}
	return err;
}
#endif

	PGPError
pgpTLSReceiveHandshakePacket(
	PGPtlsSessionPriv *	session,
	PGPByte *			outType,
	PGPByte **			outBuffer,
	PGPSize *			outLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				rcvdType;
	PGPByte *			buffer = NULL;
	PGPSize				rcvdLen = 0,
						pktLen = 0;
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
	PGPByte *			v2Buffer = NULL;
	PGPUInt32			v2BufferLen = 0;
#endif
	
	*outType	= 0;
	*outBuffer	= NULL;
	*outLength	= 0;
	
	if( session->handDataSize > 0 )
	{
		err = pgpTLSExtractHandData( session, &buffer, &rcvdLen );	CKERR;
		rcvdType = kPGPtls_RT_Handshake;
	}
	else
	{
nextPkt:
		err = pgpTLSReceiveRecordLayer( session, &rcvdType, &buffer, &rcvdLen );
	}
	if( IsPGPError( err ) || IsNull( buffer ) )
		goto done;
	if( rcvdType == kPGPtls_RT_Alert )
	{
		err = pgpTLSProcessAlert( session, buffer, rcvdLen ); CKERR;
		(void)pgpContextMemFree( session->pgpContext, buffer );
		buffer = NULL;
		goto nextPkt;
	}
	else if( rcvdType == kPGPtls_RT_ChangeCipherSpec )
	{
		pgpTLSNextState( session, kPGPtls_EV_ReceiveChangeCipherSpec );
		if( ( rcvdLen == 1 ) && ( buffer[0] == 1 ) &&
			( session->readActive == NULL ) &&
			( session->state != kPGPtls_FatalErrorState ) &&
			( session->isClientSide ? IsntNull( session->serverPending ) :
			IsntNull( session->clientPending ) ) )
		{
			err = pgpTLSActivateReadKeys( session ); CKERR;
			(void)pgpContextMemFree( session->pgpContext, buffer );
			buffer = NULL;
			goto nextPkt;
		}
		else
		{
			(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
										kPGPtls_AT_UnexpectedMessage );
			FATALTLS( kPGPError_TLSProtocolViolation );
		}
	}
	else if( rcvdType != kPGPtls_RT_Handshake )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
									kPGPtls_AT_UnexpectedMessage );
		FATALTLS( kPGPError_TLSProtocolViolation );
	}
	err = pgpTLSExtractHandData( session, &buffer, &rcvdLen );	CKERR;

#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
	if( session->sslv2Hello )
	{
		PGPByte *		v3Buffer;

		v2BufferLen = rcvdLen + 3;
		err = pgpConvertV2HelloToV3Hello(session, buffer, rcvdLen, &v3Buffer, 
										 &rcvdLen);	CKERR;

		v2Buffer = (PGPByte *) pgpContextMemAlloc(session->pgpContext,
												  v2BufferLen, 0 );
		if( IsNull( v2Buffer ) )
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}
		v2Buffer[0] = 0x01;
		v2Buffer[1] = session->sslv2MajorVersion;
		v2Buffer[2] = session->sslv2MinorVersion;
		pgpCopyMemory( buffer, &v2Buffer[3], v2BufferLen );
		(void)pgpContextMemFree( session->pgpContext, buffer );
		buffer = v3Buffer;
		/* Count the header info in the received size. */
		rcvdLen += 4;
	}
#endif

	pktLen = ( buffer[1] << 16 ) | ( buffer[2] << 8 ) | buffer[3];
	if( pktLen + 4 > rcvdLen )
	{
		/* handshake packet is fragmented */
		err = pgpTLSBufferHandData( session, buffer, rcvdLen );	CKERR;
		goto nextPkt;
	}
	if( pktLen + 4 < rcvdLen )
	{
		/* multiple handshake packets were in the record packet */
		err = pgpTLSBufferHandData( session, buffer + pktLen + 4,
									rcvdLen - pktLen - 4 );	CKERR;
	}
	if( buffer[0] != kPGPtls_HT_HelloRequest )
	{
		if( ( buffer[0] == kPGPtls_HT_Finished ) ||
			( buffer[0] == kPGPtls_HT_CertificateVerify ) )
		{
			if( PGPHashContextRefIsValid( session->lastHandSHA ) ||
				PGPHashContextRefIsValid( session->lastHandMD5 ) )
			{
				(void)pgpTLSSendAlert( session,	kPGPtls_AL_FatalAlert,
											kPGPtls_AT_UnexpectedMessage );
				FATALTLS( kPGPError_TLSProtocolViolation );
			}
			err = PGPCopyHashContext( session->handshakeSHA,
										&session->lastHandSHA);	CKERR;
			err = PGPCopyHashContext( session->handshakeMD5,
										&session->lastHandMD5);	CKERR;
		}
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
		if( session->sslv2Hello )
		{
			(void)PGPContinueHash( session->handshakeMD5, v2Buffer, v2BufferLen );
			(void)PGPContinueHash( session->handshakeSHA, v2Buffer, v2BufferLen );
		}
		else
		{
#endif
			(void)PGPContinueHash( session->handshakeMD5, buffer, pktLen + 4 );
			(void)PGPContinueHash( session->handshakeSHA, buffer, pktLen + 4 );
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
		}
#endif
	}

	*outType = buffer[0];
	*outBuffer = buffer;
	*outLength = pktLen;
	pgpCopyMemory( buffer + 4, buffer, pktLen );
done:
#ifdef PGPTLS_SSL_V2_CLIENT_HELLO
	session->sslv2Hello = 0;
	if( IsntNull( v2Buffer ) )
		(void)pgpContextMemFree( session->pgpContext, v2Buffer );
#endif
	if( IsPGPError( err ) && IsntNull( buffer ) )
		(void)pgpContextMemFree( session->pgpContext, buffer );
	return err;
}

	PGPError
pgpTLSProcessAlert(
	PGPtlsSessionPriv *	session,
	PGPByte *			inBuffer,
	PGPSize				inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte				alertType;
	PGPByte				alertLevel;
	
	if( inLength != 2 )
		FATALTLS( kPGPError_TLSProtocolViolation );
	alertLevel = inBuffer[0];
	alertType = inBuffer[1];
	
	/* Treat all alerts as fatal except close_notify and no_certificate */
	if( alertType == kPGPtls_AT_CloseNotify )
	{
		(void)pgpTLSSendAlert( session,	kPGPtls_AL_WarningAlert,
									kPGPtls_AT_CloseNotify );
		session->state = kPGPtls_ClosedState;
	}
	else if( alertType == kPGPtls_AT_NoCertificate )
	{
		pgpTLSNextState( session, kPGPtls_EV_ReceiveNoCertificate );
		if( !session->isClientSide )
			session->certRequested = FALSE;
	}
	else
	{
		session->fatalAlert = (PGPtlsAlert)alertType;
#ifdef PGPTLS_DEBUG
		pgpAssert( 0 );
#endif
		pgpTLSNextState( session, kPGPtls_EV_ReceiveFatalAlert );
	}
	if( session->state == kPGPtls_FatalErrorState )
		err = kPGPError_TLSAlertReceived;
	
done:
	return err;
}

	PGPError
pgpTLSSendRecordLayer(
	PGPtlsSessionPriv *	session,
	const PGPByte		inType,
	const PGPByte *		inBuffer,
	const PGPSize		inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte *			buffer = NULL;
	PGPSize				bufLen = 0,
						payloadLen = 0,
						padLen = 0;
	PGPInt32			serr = 0;
	
	PGPValidatePtr( inBuffer );
	if( inLength > kPGPtls_MaximumPacketSize )
	{
		err = kPGPError_BufferTooSmall;
		goto done;				/* non-fatal */
	}
	pgpAssert(	( inType == kPGPtls_RT_ChangeCipherSpec )	||
				( inType == kPGPtls_RT_Alert )				||
				( inType == kPGPtls_RT_Handshake )			||
				( inType == kPGPtls_RT_ApplicationData ) );

	if( IsntNull( session->writeActive ) )
	{
		if( PGPCBCContextRefIsValid( session->writeCipher ) )
		{
			padLen = (kPGPtls_CipherBlockSize -
				((inLength + session->hashSize + 1) %
					kPGPtls_CipherBlockSize ) );
			if( padLen == kPGPtls_CipherBlockSize )
				padLen = 0;
			bufLen += padLen + 1;
		}
		bufLen += session->hashSize;
	}
	bufLen += kPGPtls_RecordHeaderSize + inLength;
	payloadLen = bufLen - kPGPtls_RecordHeaderSize;
	buffer  = PGPNewData( session->memMgr, bufLen, kPGPMemoryMgrFlags_Clear );
	if( IsNull( buffer ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	buffer[0] = inType;
	buffer[1] = kPGPtls_MajorVersion;
	buffer[2] = session->minorVersion;
	PGPUInt16ToEndian( (PGPUInt16) payloadLen, kPGPBigEndian, &buffer[3] );
	pgpCopyMemory( inBuffer, &buffer[kPGPtls_RecordHeaderSize], inLength );
	if( IsntNull( session->writeActive ) )
	{
		err = pgpTLSCalculateMAC( session, TRUE, inType, inBuffer, inLength,
					buffer + inLength + kPGPtls_RecordHeaderSize ); CKERR;
		if( PGPCBCContextRefIsValid( session->writeCipher ) )
		{
			if( padLen )
				pgpFillMemory( buffer + inLength + session->hashSize +
								kPGPtls_RecordHeaderSize, padLen + 1, padLen );
			err = PGPCBCEncrypt( session->writeCipher,
								buffer + kPGPtls_RecordHeaderSize, payloadLen,
								buffer + kPGPtls_RecordHeaderSize );CKERR;
		}
	}
	
	err = pgpTLSSendQueueIdleInternal( session );
	if( err == kPGPError_TLSWouldBlock )
		serr = err;
	
	if( IsntPGPError( err ) && ( bufLen > 0 ) )
	{
		if( serr != kPGPError_TLSWouldBlock )
			serr = (session->tlsSendProc)( session->tlsSendUserData,
										buffer, (PGPInt32) bufLen );
		if( serr == kPGPError_TLSWouldBlock )
		{
			err = pgpTLSBufferSendData( session, buffer, bufLen ); CKERR;
			err = kPGPError_TLSWouldBlock;
		}
		else if( (PGPSize)serr != bufLen )
			FATALTLS( kPGPError_TLSUnexpectedClose );
	}
done:
	if( IsntNull( buffer ) )
		(void)PGPFreeData( buffer );
	return err;
}

	PGPError
pgpTLSSendHandshakePacket(
	PGPtlsSessionPriv *	session,
	const PGPByte		inType,
	const PGPByte *		inBuffer,
	const PGPSize		inLength )
{
	PGPError			err	= kPGPError_NoErr;
	PGPByte *			buffer = NULL;
	PGPByte				prefix[4];
	PGPUInt16			pktLen;
	
	pktLen = inLength + sizeof(prefix);
	prefix[0] = inType;
	prefix[1] = 0;	/* 24 bit length first byte */
	PGPUInt16ToEndian( (PGPUInt16) inLength, kPGPBigEndian, &prefix[2] );
	
	buffer = (PGPByte *) pgpContextMemAlloc( session->pgpContext, pktLen, 0 );
	if( IsNull( buffer ) )
	{
		err = kPGPError_OutOfMemory;
		goto done;
	}
	pgpCopyMemory( prefix, buffer, sizeof(prefix) );
	if( IsntNull( inBuffer ) )
		pgpCopyMemory( inBuffer, buffer + sizeof(prefix), inLength );
	
	if( inType != kPGPtls_HT_HelloRequest )
	{
		(void)PGPContinueHash(session->handshakeMD5, buffer, pktLen);
		(void)PGPContinueHash(session->handshakeSHA, buffer, pktLen);
	}

	err = pgpTLSSendRecordLayer( session, kPGPtls_RT_Handshake,
									buffer, pktLen ); CKERR;	
done:
	if( IsntNull( buffer ) )
		(void)pgpContextMemFree( session->pgpContext, buffer );
	return err;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -