コード例 #1
0
ファイル: ssl_decode.c プロジェクト: Correlsense/libdssl
int ssl3_change_cipher_spec_decoder( void* decoder_stack, NM_PacketDir dir,
		u_char* data, uint32_t len, uint32_t* processed )
{
	dssl_decoder_stack* stack = (dssl_decoder_stack*) decoder_stack;

	/* unused parameters */
	dir;

	/* check packet data to comply to CSS protocol */
	if( len != 1 ) return NM_ERROR( NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ) );
	if(data[0] != 1 ) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );

	*processed = 1;

	return dssl_decoder_stack_flip_cipher( stack );
}
コード例 #2
0
ファイル: ssl2_decode_hs.c プロジェクト: Raz0r/libdssl
/* ========== CLIENT-MASTER-KEY ========== */
static int ssl2_decode_client_master_key(  DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	int rc = DSSL_RC_OK;
	uint16_t clearKeyLen = 0;
	uint16_t encKeyLen = 0;
	uint16_t keyArgLen = 0;
	u_char* pClearKey = NULL;
	u_char* pEncKey = NULL;
	u_char* pKeyArg = NULL;

	_ASSERT( processed && data && sess );
	if( len < SSL20_CLIENT_MASTER_KEY_MIN_LEN ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	/* CIPHER-KIND - convert to 2 byte DSSL_Session::cipher_suite */
	rc = DSSL_ConvertSSL2CipherSuite( data, &sess->cipher_suite );

	/* CLEAR-KEY-LENGTH, ENCRYPTED-KEY-LENGTH, KEY-ARG-LENGTH */
	if( rc == DSSL_RC_OK )
	{
		clearKeyLen = MAKE_UINT16( data[3], data[4] );
		encKeyLen = MAKE_UINT16( data[5], data[6] );
		keyArgLen = MAKE_UINT16( data[7], data[8] );

		if( len != (uint32_t)clearKeyLen + encKeyLen + keyArgLen + SSL20_CLIENT_MASTER_KEY_MIN_LEN )
		{
			rc = NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
		}

		*processed = len;

	}
	
	/* reconstitute the master secret */
	if( rc == DSSL_RC_OK )
	{
		EVP_PKEY *pk = NULL;

		pClearKey = data + SSL20_CLIENT_MASTER_KEY_MIN_LEN;
		pEncKey = pClearKey + clearKeyLen;
		pKeyArg = pEncKey + encKeyLen;

		if( clearKeyLen ) { memcpy( sess->master_secret, pClearKey, clearKeyLen ); }

		pk = ssls_get_session_private_key( sess );
		
		/* if SSL server key is not found, try to find a matching one from the key pool */
		if(pk == NULL) 
		{
			u_char buff[1024];
			_ASSERT( sess->last_packet);

			memcpy(buff, pEncKey, encKeyLen);
			pk = ssls_try_ssl_keys( sess, pEncKey, encKeyLen );

			/* if a matching key found, register it with the server IP:port */
			if(pk != NULL)
			{
				if( ssls_register_ssl_key( sess, pk ) == DSSL_RC_OK)
				{
					/* ssls_register_ssl_key clones the key, query the key back */
					//pk = ssls_get_session_private_key( sess );
				}
				else
				{
					pk = NULL;
				}
			}
		}

		if( pk )
		{
			uint32_t encLen2 = RSA_private_decrypt( encKeyLen, pEncKey, 
					sess->master_secret + clearKeyLen, pk->pkey.rsa, RSA_PKCS1_PADDING );

			if( clearKeyLen + encLen2 >= sizeof( sess->master_secret ) )
			{
				rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
			}

			sess->master_key_len = clearKeyLen + encLen2;
		}
		else
		{
			rc = NM_ERROR( DSSL_E_SSL_SERVER_KEY_UNKNOWN );
			ssls_register_missing_key_server( sess );
		}
	}

	/* generate session keys */
	if( rc == DSSL_RC_OK )
	{
		rc = ssls2_generate_keys( sess, pKeyArg, keyArgLen );
	}

	/* turn on new ciphers */
	if( rc == DSSL_RC_OK ) 
	{
		rc = dssl_decoder_stack_flip_cipher( &sess->c_dec );
		if (rc == DSSL_RC_OK ) { rc = dssl_decoder_stack_flip_cipher( &sess->s_dec ); }
	}

	return rc;
}
コード例 #3
0
ファイル: ssl2_decode_hs.c プロジェクト: Raz0r/libdssl
/* ========== SERVER-HELLO ========== */
static int ssl2_decode_server_hello( DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	int rc = DSSL_RC_OK;
	uint16_t certLen = 0;
	uint16_t cipherSpecLen = 0;
	uint16_t connectionIdLen = 0;
	int session_id_hit = 0;

	_ASSERT( processed && data && sess );

	if( len < SSL20_SERVER_HELLO_MIN_LEN ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	/* check SESSION-ID-HIT */
	session_id_hit = data[0];

	/* decode CERTIFICATE-TYPE */
	if( rc == DSSL_RC_OK && (data[1] && data[1] != SSL2_CT_X509_CERTIFICATE) ) 
	{
		rc = NM_ERROR( DSSL_E_SSL2_INVALID_CERTIFICATE_TYPE ); 
	}

	/* SERVER-VERSION*/	 /* TODO: add server version check */

	/* CERTIFICATE-LENGTH, CIPHER-SPECS-LENGTH, CONNECTION-ID-LENGTH */
	if( rc == DSSL_RC_OK )
	{
		certLen = MAKE_UINT16( data[4], data[5] );
		cipherSpecLen = MAKE_UINT16( data[6], data[7] );
		connectionIdLen = MAKE_UINT16( data[8], data[9] );

		if( (uint32_t)certLen + cipherSpecLen + connectionIdLen + SSL20_SERVER_HELLO_MIN_LEN != len )
		{
			rc = NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
		}
		else if( connectionIdLen < 16 || connectionIdLen > 32 )
		{
			rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
		}

		if( rc == DSSL_RC_OK ) 
		{
			u_char* connIdData = data + SSL20_SERVER_HELLO_MIN_LEN + certLen + cipherSpecLen;
			sess->server_connection_id_len = connectionIdLen; 
			memset( sess->server_random, 0, sizeof(sess->server_random) );
			memcpy( sess->server_random, connIdData, connectionIdLen );
		}
	}

	/* TODO: Check the certificate to match what DSSL has been initialized with */
	if( rc == DSSL_RC_OK )
	{
	}

	if( session_id_hit )
	{
		if( sess->flags & SSF_CLIENT_SESSION_ID_SET )
		{
			rc = ssls_lookup_session( sess );
			/* re-generate the session keys and turn on ciphers right away */
			if( rc == DSSL_RC_OK)
			{
				rc = ssls2_generate_keys( sess, sess->ssl2_key_arg, sess->ssl2_key_arg_len );
			}
			/* turn on new ciphers */
			if( rc == DSSL_RC_OK ) 
			{
				rc = dssl_decoder_stack_flip_cipher( &sess->c_dec );
				if (rc == DSSL_RC_OK ) { rc = dssl_decoder_stack_flip_cipher( &sess->s_dec ); }
			}
		}
		else
		{
			/* client didn't send the session id */
			rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
		}
	}


	if( rc == DSSL_RC_OK )
	{
		*processed = certLen + cipherSpecLen + connectionIdLen + SSL20_SERVER_HELLO_MIN_LEN;
	}

	return rc;
}