Beispiel #1
0
/* ========== SERVER-FINISHED ========== */
static int ssl2_decode_server_finished(  DSSL_Session* sess, u_char* data, uint32_t len, uint32_t* processed )
{
	_ASSERT( processed && data && sess );

	if( len > sizeof( sess->session_id ) ) { return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH ); }

	/* set new session ID and add the session to the session cache */
	memset( sess->session_id, 0, sizeof(sess->session_id ) );
	memcpy( sess->session_id, data, len );
	ssls_store_session( sess );

	/* handshake is over, time to switch to application data protocol */
	sess->c_dec.state = SS_Established;
	sess->s_dec.state = SS_Established;
	ssls_handshake_done( sess );

	*processed = len;

	return DSSL_RC_OK;
}
Beispiel #2
0
/* ========== Handshake decoding function ========== */
int ssl3_decode_handshake_record( dssl_decoder_stack* stack, NM_PacketDir dir,
								 u_char* data, uint32_t len, uint32_t* processed )
{
	int rc = DSSL_E_UNSPECIFIED_ERROR;
	uint32_t recLen = 0;
	u_char hs_type = 0;
	u_char* org_data = data;
	DSSL_Session* sess = stack->sess;
	_ASSERT( processed != NULL );
	_ASSERT((sess->flags & SSF_SSLV2_CHALLENGE) == 0);

	if( sess->version == 0 )
	{
		return ssl_decode_first_client_hello( sess, data, len, processed );
	}

	if( len < SSL3_HANDSHAKE_HEADER_LEN ) return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );

	DEBUG_TRACE_BUF("handshake", data, len);
	recLen = (((int32_t)data[1]) << 16) | (((int32_t)data[2]) << 8) | data[3];
	hs_type = data[0];

	data += SSL3_HANDSHAKE_HEADER_LEN;
	len -= SSL3_HANDSHAKE_HEADER_LEN;

	if( len < recLen )return NM_ERROR( DSSL_E_SSL_INVALID_RECORD_LENGTH );

#ifdef NM_TRACE_SSL_HANDSHAKE
	DEBUG_TRACE2( "===>Decoding SSL v3 handshake: %s len: %d...", SSL3_HandshakeTypeToString( hs_type ), (int) recLen );
#endif

	switch( hs_type )
	{
	case SSL3_MT_HELLO_REQUEST:
		rc = ssl3_decode_dummy( sess, data, recLen );
		break;

	case SSL3_MT_CLIENT_HELLO:
		rc = ssl3_decode_client_hello( sess, data, recLen );
		break;

	case SSL3_MT_SERVER_HELLO:
		stack->state = SS_SeenServerHello;
		rc = ssl3_decode_server_hello( sess, data, recLen );
		break;

	case SSL3_MT_CERTIFICATE:
		if( dir == ePacketDirFromServer )
		{
			rc = ssl3_decode_server_certificate( sess, data, recLen );
		}
		else
		{
			rc = ssl3_decode_dummy( sess, data, recLen );
		}
		break;

	case SSL3_MT_SERVER_DONE:
		rc = ssl3_decode_dummy( sess, data, recLen );
		break;

	case SSL3_MT_CLIENT_KEY_EXCHANGE:
		rc = ssl3_decode_client_key_exchange( sess, data, recLen );
		break;

	case SSL3_MT_FINISHED:
		rc = (*sess->decode_finished_proc)( sess, dir, data, recLen );
		if( rc == DSSL_RC_OK ) {
			stack->state = SS_Established;
			ssls_handshake_done( sess );
		}
		break;
		
	case SSL3_MT_CERTIFICATE_STATUS:
		rc = ssl3_decode_dummy( sess, data, recLen );
		break;
	
	case SSL3_MT_SERVER_KEY_EXCHANGE:
		/*at this point it is clear that the session is not decryptable due to ephemeral keys usage.*/
		rc = NM_ERROR( DSSL_E_SSL_CANNOT_DECRYPT_EPHEMERAL );
		break;

	case SSL3_MT_CERTIFICATE_REQUEST:
		/* TODO: track CertificateRequest- client certificate / certificate verify */
		rc = ssl3_decode_dummy( sess, data, recLen );
		break;

	case SSL3_MT_CERTIFICATE_VERIFY:
		/* TODO: track CertificateRequest- client certificate / certificate verify */
		rc = ssl3_decode_dummy( sess, data, recLen );
		break;

	case SSL3_MT_NEWSESSION_TICKET:
		rc = ssl3_decode_new_session_ticket( sess, data, recLen );
		break;

	default:
		rc = NM_ERROR( DSSL_E_SSL_PROTOCOL_ERROR );
		break;
	}

	if( rc == DSSL_RC_OK )
	{
		*processed = recLen + SSL3_HANDSHAKE_HEADER_LEN;

		if( hs_type == SSL3_MT_CLIENT_HELLO ) 
		{
			ssl3_init_handshake_digests( sess );
		}

		if( hs_type != SSL3_MT_HELLO_REQUEST )
		{
			ssl3_update_handshake_digests( sess, org_data, *processed );
		}
	}

#ifdef NM_TRACE_SSL_HANDSHAKE
	if( rc == DSSL_RC_OK )
	{
		DEBUG_TRACE0( "OK\n" );
	}
	else
	{
		DEBUG_TRACE1( "Error! (%d)\n", (int)rc );
	}
#endif

	return rc;
}