Beispiel #1
0
int DSSL_SessionProcessData( DSSL_Session* sess, NM_PacketDir dir, u_char* data, uint32_t len )
{
	int rc = DSSL_RC_OK;
	dssl_decoder_stack* dec = NULL;

	if( dir == ePacketDirInvalid ) return NM_ERROR( DSSL_E_INVALID_PARAMETER );

	dec = (dir == ePacketDirFromClient) ? &sess->c_dec : &sess->s_dec;

	if( !sslc_is_decoder_stack_set( dec ) )
	{
		uint16_t ver = 0;
		int is_client = (dir == ePacketDirFromClient);
		if( is_client )
		{
			rc = ssl_detect_client_hello_version( data, len, &ver );
		}
		else
		{
			rc = ssl_detect_server_hello_version( data, len, &ver );
			/* update the client decoder after the server have declared the actual version 
			of the session */
			DEBUG_TRACE2("DSSL_SessionProcessData - sess->version: 0x%02X, ver is: 0x%02X\n", sess->version, ver);
			if( rc == DSSL_RC_OK && sess->version != ver )
			{
				sess->c_dec.version = ver;
				rc = dssl_decoder_stack_set( &sess->c_dec, sess, ver, 1 );
			}
			ssls_set_session_version( sess, ver );
		}

		if( rc == DSSL_RC_OK ) 
		{
			dec->version = ver;
			rc = dssl_decoder_stack_set( dec, sess, ver, is_client );
		}
	}

	if( rc == DSSL_RC_OK ) rc = dssl_decoder_stack_process( dec, dir, data, len );

	/* check if a session with a first-time automapped key failed */
	if( NM_IS_FAILED( rc ) && sess->flags & SSF_TEST_SSL_KEY )
	{
		if(sess->event_callback)
		{
			(*sess->event_callback)( sess->user_data, eSslMappedKeyFailed, sess->ssl_si );
		}
		DSSL_MoveServerToMissingKeyList( sess->env, sess->ssl_si );
		sess->ssl_si = NULL;
	}

	if( NM_IS_FAILED( rc ) && sess->error_callback && rc != DSSL_E_SSL_SERVER_KEY_UNKNOWN )
	{
		sess->error_callback( sess->user_data, rc );
	}

	return rc;
}
Beispiel #2
0
int dssl_decoder_process( dssl_decoder* d, NM_PacketDir dir, u_char* data, uint32_t len )
{
	uint32_t processed = 0;
	int rc = DSSL_RC_OK;

	if( !d->handler ) return NM_ERROR( DSSL_E_NOT_IMPL );
        fprintf(stderr, "\ntesting testing: %d", rc);

	if( d->buff_used_len > 0 ) 
	{
		rc = dssl_decoder_add_to_buffer( d, data, len );
		fprintf(stderr, "\ndssl dssl_decoder_add_to_buffer: %d", rc);

		if( rc == DSSL_RC_OK )
		{
			data = d->buff;
			len = d->buff_used_len; 
		}
	}

	while( rc == DSSL_RC_OK && processed < len )
	{
		uint32_t p = 0;
        fprintf(stderr, "\ntesting testing: %d", rc);
		rc = d->handler( d->handler_data, dir, data + processed, len - processed, &p );
		processed += p;

        fprintf(stderr, "\ntesting testing: %d", rc);
		/* can't be all ok and no data processed */
		if( p == 0 && rc == DSSL_RC_OK ) { rc = NM_ERROR( DSSL_E_UNSPECIFIED_ERROR ); }
		fprintf(stderr, "\nssl d->handler p==%p rc = %d\n",p, rc);
	}

	if( !NM_IS_FAILED( rc ) )
	{
		if( d->buff_used_len > 0 )
		{
			rc = dssl_decoder_shift_buffer( d, processed );
		}
		else if( processed < len )
		{
			rc = dssl_decoder_add_to_buffer( d, data + processed, len - processed );
		}
	}

	return rc;
}
Beispiel #3
0
static int ssl3_decode_server_hello( DSSL_Session* sess, u_char* data, uint32_t len )
{
	uint16_t server_version = 0;
	u_char* org_data = data;
	uint16_t session_id_len = 0;
	int session_id_match = 0;

	if( data[0] != 3 || data[1] > 3) return NM_ERROR( DSSL_E_SSL_UNKNOWN_VERSION );
	if( len < SSL3_SERVER_HELLO_MIN_LEN ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );

	/* Server Version */
	server_version = MAKE_UINT16( data[0], data[1] );
	if( sess->version == 0 || server_version < sess->version )
	{
		ssls_set_session_version( sess, server_version );
	}
	data+= 2;

	/* ServerRandom */
	_ASSERT_STATIC( sizeof(sess->server_random) == 32 );

	memcpy( sess->server_random, data, sizeof( sess->server_random ) );
	data+= 32;
	DEBUG_TRACE_BUF("server_random", sess->server_random, 32);


	/* session ID */
	_ASSERT_STATIC( sizeof(sess->session_id) == 32 );
	session_id_len = data[0];
	data++;

	if( session_id_len > 0 )
	{
		if ( session_id_len > 32 ) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );

		if( !IS_ENOUGH_LENGTH( org_data, len, data, session_id_len ) ) 
		{
			return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
		}

		if( sess->flags & SSF_CLIENT_SESSION_ID_SET 
			&& memcmp( sess->session_id, data, session_id_len ) == 0 )
		{
			session_id_match = 1;
		}
		else
		{
			sess->flags &= ~SSF_CLIENT_SESSION_ID_SET;
			memcpy( sess->session_id, data, session_id_len );
		}

		data += session_id_len;
	}

	/* Cipher Suite and Compression */
	if( !IS_ENOUGH_LENGTH( org_data, len, data, 3 ) ) 
	{
		return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	}

	sess->cipher_suite = MAKE_UINT16( data[0], data[1] );
	sess->compression_method = data[2];

	data += 3;
	sess->flags &= ~SSF_TLS_SERVER_SESSION_TICKET; /* clear server side TLS Session Ticket flag */
	/* Process SSL Extensions, if present */
	if(IS_ENOUGH_LENGTH( org_data, len, data, 2 )) 
	{
		int t_len = MAKE_UINT16(data[0], data[1]);
		data += 2;
		if(!IS_ENOUGH_LENGTH( org_data, len, data, t_len)) 
			return NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH);

		/* cycle through extension records */
		while(t_len >= 4)
		{
			int ext_type = MAKE_UINT16(data[0], data[1]); /* extension type */
			int ext_len = MAKE_UINT16(data[2], data[3]);
			#ifdef NM_TRACE_SSL_HANDSHAKE
				DEBUG_TRACE2( "\nSSL extension: %s len: %d", SSL3_ExtensionTypeToString( ext_type ), ext_len );
			#endif

			/* TLS Session Ticket extension found, set the flag */
			if( ext_type == 0x0023)
			{
				sess->flags |= SSF_TLS_SERVER_SESSION_TICKET;
			}

			data += ext_len + 4;
			if(data > org_data + len) return NM_ERROR(DSSL_E_SSL_INVALID_RECORD_LENGTH);
			t_len -= ext_len + 4;
		}
	}

	if( session_id_match )
	{
		if( sess->flags & SSF_TLS_SESSION_TICKET_SET)
		{
			int rc = ssls_init_from_tls_ticket( sess );
			if( NM_IS_FAILED( rc ) ) 
				return rc;
		}
		else
		{
			/* lookup session from the cache for stateful SSL renegotiation */
			int rc = ssls_lookup_session( sess );
			if( NM_IS_FAILED( rc ) ) 
				return rc;
		}
	}

	if( sess->flags & SSF_CLIENT_SESSION_ID_SET )
	{
		int rc = ssls_generate_keys( sess );
		if( NM_IS_FAILED( rc ) ) return rc;
	}

	return DSSL_RC_OK;
}