Exemplo n.º 1
0
void DSSL_SessionDeInit( DSSL_Session* s )
{
#ifdef NM_TRACE_SSL_SESSIONS
	DEBUG_TRACE0( "DSSL_SessionDeInit\n" );
#endif

	if( s->env ) DSSL_EnvOnSessionClosing( s->env, s );

	dssl_decoder_stack_deinit( &s->c_dec );
	dssl_decoder_stack_deinit( &s->s_dec );

	ssls_free_extension_data(s);

	EVP_MD_CTX_cleanup( &s->handshake_digest_md5 );
	EVP_MD_CTX_cleanup( &s->handshake_digest_sha );
}
Exemplo n.º 2
0
static int ssl3_decode_client_hello( DSSL_Session* sess, u_char* data, uint32_t len )
{
	u_char* org_data = data;
	int t_len = 0;

	/* record the handshake start time */
	sess->handshake_start = sess->last_packet->pcap_header.ts;

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

	/* 2 bytes client version */
	sess->client_version = MAKE_UINT16( data[0], data[1] );
	ssls_set_session_version( sess, MAKE_UINT16( data[0], data[1] ) );

	data+= 2;

	/* make sure */
	if( data + 32 > org_data + len ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );

	/* 32 bytes ClientRandom */
	memcpy( sess->client_random, data, 32 );
	data+= 32;
	DEBUG_TRACE_BUF("client_random", sess->client_random, 32);

	/* check session ID length */
	if( data[0] > 32 ) return NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );

	if( data[0] > 0 )
	{
		/* Session ID set */
		if( data + data[0] > org_data + len ) 
			return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );

		memcpy( sess->session_id, data+1, data[0] );
		sess->flags |= SSF_CLIENT_SESSION_ID_SET;

		data += data[0] + 1;
	}
	else
	{
		/* no Session ID */
		sess->flags &= ~SSF_CLIENT_SESSION_ID_SET;
		++data;
	}

	/* Cypher Suites */
	if(data + 1 >= org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	t_len = MAKE_UINT16(data[0], data[1]) + 2; /* cypher suites + cypher sute length size */

	data += t_len; /* skip cypher suites */

	/* Compression Method */
	if(data >= org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	if(data + data[0] + 1 > org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	t_len = data[0] + 1;

	data += t_len; /* skip compression methods */

	/* Extensions */

	/* clear all previous extension fields */
	ssls_free_extension_data(sess);

	if(data >= org_data + len) return DSSL_RC_OK;

	if(data + 2 > org_data + len) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );
	t_len = MAKE_UINT16(data[0], data[1]);

	data += 2; /* positon at the beginning of the first extension record, if any*/

	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 */
		if( ext_type == 0x0023)
		{
			/* non empty ticket passed, store it */
			if(ext_len > 0)
			{
				sess->flags |= SSF_TLS_SESSION_TICKET_SET;
				sess->session_ticket = (u_char*) malloc(ext_len);
				if(sess->session_ticket == NULL) return NM_ERROR(DSSL_E_OUT_OF_MEMORY);
				memcpy(sess->session_ticket, data+4, ext_len);
				sess->session_ticket_len = ext_len;
			}
		}

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

	return DSSL_RC_OK;
}