Пример #1
0
/*---------------------------------------------------------------------------*/
zrtp_status_t _zrtp_machine_process_commit(zrtp_stream_t* stream, zrtp_rtp_info_t* packet)
{	
	zrtp_packet_Commit_t *commit = (zrtp_packet_Commit_t*) packet->message;
	
	switch (stream->mode)
	{
	case ZRTP_STREAM_MODE_DH:
		zrtp_zstrncpyc( ZSTR_GV(stream->protocol->cc->peer_hv),
						(const char*)commit->hv,
						ZRTP_HV_SIZE);
		break;
	case ZRTP_STREAM_MODE_PRESHARED:		
		zrtp_zstrncpyc( ZSTR_GV(stream->protocol->cc->peer_hv),
						(const char*)commit->hv + ZRTP_HV_NONCE_SIZE,
						ZRTP_HV_NONCE_SIZE);
	case ZRTP_STREAM_MODE_MULT:
		zrtp_zstrncpyc( ZSTR_GV(stream->protocol->cc->peer_hv),
						(const char*)commit->hv,
						ZRTP_HV_NONCE_SIZE);
		break;
	default: break;
	}

	/* Copy Commit packet for further hashing */
	zrtp_memcpy(&stream->messages.peer_commit, commit, zrtp_ntoh16(commit->hdr.length)*4);
    
    return zrtp_status_ok;
}
Пример #2
0
static int verify_sas(struct re_printf *pf, void *arg)
{
	const struct cmd_arg *carg = arg;
	(void)pf;

	if (str_isset(carg->prm)) {
		char rzid[ZRTP_STRING16] = "";
		zrtp_status_t s;
		zrtp_string16_t remote_zid = ZSTR_INIT_EMPTY(remote_zid);

		if (str_len(carg->prm) != 24) {
			warning("zrtp: invalid remote ZID (%s)\n", carg->prm);
			return EINVAL;
		}

		(void) str2hex(carg->prm, (int) str_len(carg->prm),
			       rzid, sizeof(rzid));
		zrtp_zstrncpyc(ZSTR_GV(remote_zid), (const char*)rzid,
			       sizeof(zrtp_zid_t));

		s = zrtp_cache_set_verified(zrtp_global->cache,
					    ZSTR_GV(remote_zid),
					    true);
		if (s == zrtp_status_ok)
			info("zrtp: SAS for peer %s verified\n", carg->prm);
		else {
			warning("zrtp: zrtp_cache_set_verified"
				" failed (status = %d)\n", s);
			return EINVAL;
		}
	}

	return 0;
}
Пример #3
0
void zrtp_config_defaults(zrtp_config_t* config)
{
	zrtp_memset(config, 0, sizeof(zrtp_config_t));
	
	zrtp_memcpy(config->client_id, "ZRTP def. peer", 15);
	config->lic_mode = ZRTP_LICENSE_MODE_PASSIVE;
	
	ZSTR_SET_EMPTY(config->def_cache_path);
	zrtp_zstrncpyc(ZSTR_GV(config->def_cache_path), "./zrtp_def_cache_path.dat", 25);

	config->cache_auto_store = 1; /* cache auto flushing should be enabled by default */

#if (defined(ZRTP_USE_BUILTIN_CACHE) && (ZRTP_USE_BUILTIN_CACHE == 1))
	config->cb.cache_cb.on_init					= zrtp_def_cache_init;
	config->cb.cache_cb.on_down					= zrtp_def_cache_down;
	config->cb.cache_cb.on_put					= zrtp_def_cache_put;
	config->cb.cache_cb.on_put_mitm				= zrtp_def_cache_put_mitm;
	config->cb.cache_cb.on_get					= zrtp_def_cache_get;
	config->cb.cache_cb.on_get_mitm				= zrtp_def_cache_get_mitm;
	config->cb.cache_cb.on_set_verified			= zrtp_def_cache_set_verified;
	config->cb.cache_cb.on_get_verified			= zrtp_def_cache_get_verified;
	config->cb.cache_cb.on_reset_since			= zrtp_def_cache_reset_since;
	config->cb.cache_cb.on_presh_counter_set	= zrtp_def_cache_set_presh_counter;
	config->cb.cache_cb.on_presh_counter_get	= zrtp_def_cache_get_presh_counter;
#endif

#if (defined(ZRTP_USE_BUILTIN_SCEHDULER) && (ZRTP_USE_BUILTIN_SCEHDULER == 1))
	config->cb.sched_cb.on_init					= zrtp_def_scheduler_init;
	config->cb.sched_cb.on_down					= zrtp_def_scheduler_down;
	config->cb.sched_cb.on_call_later			= zrtp_def_scheduler_call_later;
	config->cb.sched_cb.on_cancel_call_later	= zrtp_def_scheduler_cancel_call_later;
	config->cb.sched_cb.on_wait_call_later		= zrtp_def_scheduler_wait_call_later;
#endif
}
Пример #4
0
zrtp_status_t zrtp_session_get(zrtp_session_t *session, zrtp_session_info_t *info)
{
	int i=0;
	if (!session || !info) {
		return zrtp_status_bad_param;
	}
	
	zrtp_memset(info, 0, sizeof(zrtp_session_info_t));
	
	ZSTR_SET_EMPTY(info->peer_clientid);
	ZSTR_SET_EMPTY(info->peer_version);
	ZSTR_SET_EMPTY(info->zid);
	ZSTR_SET_EMPTY(info->peer_zid);	
	ZSTR_SET_EMPTY(info->sas1);
	ZSTR_SET_EMPTY(info->sasbin);
	ZSTR_SET_EMPTY(info->sas2);
	ZSTR_SET_EMPTY(info->auth_name);
	ZSTR_SET_EMPTY(info->cipher_name);
	ZSTR_SET_EMPTY(info->hash_name);
	ZSTR_SET_EMPTY(info->sas_name);
	ZSTR_SET_EMPTY(info->pk_name);
	
	info->id = session->id;
	zrtp_zstrcpy(ZSTR_GV(info->zid), ZSTR_GV(session->zid));
	zrtp_zstrcpy(ZSTR_GV(info->peer_zid), ZSTR_GV(session->peer_zid));
	
	for (i=0; i<ZRTP_MAX_STREAMS_PER_SESSION; i++) {
		zrtp_stream_t* full_stream = &session->streams[i];
		if ((full_stream->state > ZRTP_STATE_ACTIVE) && !ZRTP_IS_STREAM_FAST(full_stream))
		{
			zrtp_zstrcpyc(ZSTR_GV(info->pk_name), zrtp_pkt2str[full_stream->pubkeyscheme->base.id-1]);
			
			zrtp_zstrncpyc( ZSTR_GV(info->peer_clientid),
						   (const char*)full_stream->messages.peer_hello.cliend_id, 16);
			zrtp_zstrncpyc( ZSTR_GV(info->peer_version),
						   (const char*)full_stream->messages.peer_hello.version, 4);
			
			info->secrets_ttl = full_stream->cache_ttl;
		}
	}
	
	info->sas_is_ready = (session->zrtpsess.length > 0) ? 1 : 0;
	if (info->sas_is_ready) {
		zrtp_zstrcpy(ZSTR_GV(info->sas1), ZSTR_GV(session->sas1));
		zrtp_zstrcpy(ZSTR_GV(info->sas2), ZSTR_GV(session->sas2));
		zrtp_zstrcpy(ZSTR_GV(info->sasbin), ZSTR_GV(session->sasbin));
		info->sas_is_base256 = (ZRTP_SAS_BASE256 == session->sasscheme->base.id);
		
		info->sas_is_verified = 0;
		if (session->zrtp->cb.cache_cb.on_get_verified) {
			session->zrtp->cb.cache_cb.on_get_verified( ZSTR_GV(session->zid),
													    ZSTR_GV(session->peer_zid),
													    &info->sas_is_verified);
		}

		zrtp_zstrcpyc(ZSTR_GV(info->hash_name), zrtp_hash2str[session->hash->base.id-1]);
		zrtp_zstrcpyc(ZSTR_GV(info->cipher_name), zrtp_cipher2str[session->blockcipher->base.id-1]);
		zrtp_zstrcpyc(ZSTR_GV(info->auth_name), zrtp_atl2str[session->authtaglength->base.id-1]);
		zrtp_zstrcpyc(ZSTR_GV(info->sas_name), zrtp_sas2str[session->sasscheme->base.id-1]);
		
		info->cached_flags	= session->secrets.cached_curr;
		info->matches_flags= session->secrets.matches_curr;
		info->wrongs_flags	= session->secrets.wrongs_curr;
	}
	
	return zrtp_status_ok;
}
Пример #5
0
zrtp_status_t zrtp_init(zrtp_config_t* config, zrtp_global_t** zrtp)
{
    zrtp_global_t* new_zrtp;
    zrtp_status_t s = zrtp_status_ok;
	
	ZRTP_LOG(3, (_ZTU_,"INITIALIZING LIBZRTP...\n"));
	
	/* Print out configuration setting */
	zrtp_print_env_settings(config);
	
	new_zrtp = zrtp_sys_alloc(sizeof(zrtp_global_t));
	if (!new_zrtp) {
		return zrtp_status_alloc_fail;
    }	
	zrtp_memset(new_zrtp, 0, sizeof(zrtp_global_t));
		
	/*
	 * Apply configuration according to the config
	 */		
	new_zrtp->lic_mode = config->lic_mode;	
	new_zrtp->is_mitm = config->is_mitm;
	ZSTR_SET_EMPTY(new_zrtp->def_cache_path);
	zrtp_zstrcpy(ZSTR_GV(new_zrtp->def_cache_path), ZSTR_GV(config->def_cache_path));
	zrtp_memcpy(&new_zrtp->cb, &config->cb, sizeof(zrtp_callback_t));
	new_zrtp->cache_auto_store = config->cache_auto_store;
        
	ZSTR_SET_EMPTY(new_zrtp->client_id);
	zrtp_memset(new_zrtp->client_id.buffer, ' ', sizeof(zrtp_client_id_t));
	zrtp_zstrncpyc( ZSTR_GV(new_zrtp->client_id),
					(const char*)config->client_id,
					sizeof(zrtp_client_id_t));
	
    /*
	 * General Initialization
	 */
	init_mlist(&new_zrtp->sessions_head);
	
    zrtp_mutex_init(&new_zrtp->sessions_protector);   
	
    init_mlist(&new_zrtp->hash_head);
    init_mlist(&new_zrtp->cipher_head);
    init_mlist(&new_zrtp->atl_head);
    init_mlist(&new_zrtp->pktype_head);
    init_mlist(&new_zrtp->sas_head);

    /* Init RNG context */	
	s = zrtp_init_rng(new_zrtp);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! zrtp_init_rng() failed:%s.\n", zrtp_log_status2str(s)));
		return zrtp_status_rng_fail;
	}
   	
	/* Initialize SRTP engine */
	s =  zrtp_srtp_init(new_zrtp);
	if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! zrtp_srtp_init() failed:<%s>\n", zrtp_log_status2str(s)));
		return zrtp_status_fail;
    }    

	if (new_zrtp->cb.cache_cb.on_init)  {
		s = new_zrtp->cb.cache_cb.on_init(new_zrtp);
		if (zrtp_status_ok != s) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! cache on_init() callback failed <%s>\n", zrtp_log_status2str(s)));
			zrtp_srtp_down(new_zrtp);
			return zrtp_status_fail;
		}
	}
	
	if (new_zrtp->cb.sched_cb.on_init)  {
		s = new_zrtp->cb.sched_cb.on_init(new_zrtp);
		if (zrtp_status_ok != s) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! scheduler on_init() callback failed <%s>\n", zrtp_log_status2str(s)));
			zrtp_srtp_down(new_zrtp);
			return zrtp_status_fail;
		}
	}
	
	/* Load default crypto-components */
    zrtp_prepare_pkt(new_zrtp);
    zrtp_defaults_sas(new_zrtp);
    zrtp_defaults_pkt(new_zrtp);
    zrtp_defaults_atl(new_zrtp);
    zrtp_defaults_aes_cipher(new_zrtp);
    zrtp_defaults_hash(new_zrtp);

	*zrtp = new_zrtp;
	
	ZRTP_LOG(3, (_ZTU_,"INITIALIZING LIBZRTP - DONE\n"));
    return  s;
}
Пример #6
0
/*----------------------------------------------------------------------------*/
zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
								zrtp_profile_t* profile,
								zrtp_zid_t zid,
								zrtp_signaling_role_t role,
								zrtp_session_t **session)
{
    uint32_t i = 0;
	zrtp_status_t s = zrtp_status_fail;
	zrtp_session_t* new_session = NULL;
        
    if (!zrtp) {
    	return zrtp_status_bad_param;
    }
	
	new_session = zrtp_sys_alloc(sizeof(zrtp_session_t));
	if (!new_session) {
		return zrtp_status_alloc_fail;		
	}
    
    zrtp_memset(new_session, 0, sizeof(zrtp_session_t));
	new_session->id = zrtp->sessions_count++;
	
	{
		zrtp_uchar32_t buff;
		ZRTP_LOG(3, (_ZTU_,"START SESSION INITIALIZATION. sID=%u.\n", new_session->id));
		ZRTP_LOG(3, (_ZTU_,"ZID=%s.\n", hex2str((const char*)zid, sizeof(zrtp_uchar12_t), (char*)buff, sizeof(buff)) ));
	}
	
	do {	
	/*
	 * Apply profile for the stream context: set flags and prepare Hello packet.
	 * If profile structure isn't provided, generate default.
	 */	 
    if (!profile) {
		ZRTP_LOG(1, (_ZTU_,"Profile in NULL - loading default one.\n"));
		zrtp_profile_defaults(&new_session->profile, zrtp);		
    } else {
		ZRTP_LOG(1, (_ZTU_,"Loading User's profile:\n"));
		if (zrtp_status_ok != zrtp_profile_check(profile, zrtp)) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! Can't apply wrong profile to the session sID=%u.\n", new_session->id));
			break;
		}
		
		/* Adjust user's settings: force SHA-384 hash for ECDH-384P */
		if (zrtp_profile_find(profile, ZRTP_CC_PKT, ZRTP_PKTYPE_EC384P) > 0) {
			ZRTP_LOG(3, (_ZTU_,"User wants ECDH384 - auto-adjust profile to use SHA-384.\n"));
			profile->hash_schemes[0] = ZRTP_HASH_SHA384;
			profile->hash_schemes[1] = ZRTP_HASH_SHA256;
			profile->hash_schemes[2] = 0;
		}		
		
		zrtp_memcpy(&new_session->profile, profile, sizeof(zrtp_profile_t));
		
		{
		int i;
		ZRTP_LOG(3, (_ZTU_,"   allowclear: %s\n", profile->allowclear?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_,"   autosecure: %s\n", profile->autosecure?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_," disclose_bit: %s\n", profile->disclose_bit?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_," signal. role: %s\n", zrtp_log_sign_role2str(role)));	
		ZRTP_LOG(3, (_ZTU_,"          TTL: %u\n", profile->cache_ttl));
				
		ZRTP_LOG(3, (_ZTU_,"  SAS schemes: "));
		i=0;
		while (profile->sas_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_SAS, profile->sas_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"     Ciphers: "));
		i=0;
		while (profile->cipher_types[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_CIPHER, profile->cipher_types[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"   PK schemes: "));
		i=0;
		while (profile->pk_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_PKT, profile->pk_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"          ATL: "));
		i=0;
		while (profile->auth_tag_lens[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_ATL, profile->auth_tag_lens[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"      Hashes: "));
		i=0;
		while (profile->hash_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_HASH, profile->hash_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n"));
		}
	}

	/* Set ZIDs */
	ZSTR_SET_EMPTY(new_session->zid);
    ZSTR_SET_EMPTY(new_session->peer_zid);
	zrtp_zstrncpyc(ZSTR_GV(new_session->zid), (const char*)zid, sizeof(zrtp_zid_t));	

	new_session->zrtp = zrtp;
	new_session->signaling_role = role;
	new_session->mitm_alert_detected = 0;

	/*
	 * Allocate memory for holding secrets and initialize with random values.
	 * Actual values will be written from the cache at the beginning of the protocol.
	 */
	new_session->secrets.rs1 = _zrtp_alloc_shared_secret(new_session);
	new_session->secrets.rs2 = _zrtp_alloc_shared_secret(new_session);	
	new_session->secrets.auxs = _zrtp_alloc_shared_secret(new_session);
	new_session->secrets.pbxs = _zrtp_alloc_shared_secret(new_session);

	if ( !new_session->secrets.rs1 || !new_session->secrets.rs2 ||
		 !new_session->secrets.auxs || !new_session->secrets.pbxs) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! Can't allocate shared secrets sID=%u\n.", new_session->id));
		s = zrtp_status_alloc_fail;
		break;
	}

	/* Initialize SAS values */	
	ZSTR_SET_EMPTY(new_session->sas1);
	ZSTR_SET_EMPTY(new_session->sas2);
	ZSTR_SET_EMPTY(new_session->sasbin);
	ZSTR_SET_EMPTY(new_session->zrtpsess);
    
    /* Clear all stream structures */
    for (i=0; i<ZRTP_MAX_STREAMS_PER_SESSION ; i++) {
		new_session->streams[i].state		= ZRTP_STATE_NONE;
		new_session->streams[i].prev_state	= ZRTP_STATE_NONE;
		new_session->streams[i].mode		= ZRTP_STREAM_MODE_UNKN;
    }
        
    /* Initialize synchronization objects */
	s = zrtp_mutex_init(&new_session->streams_protector);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! can't initialize Stream protector. sID=%u.\n", new_session->id));
		break;
	}	
	s = zrtp_mutex_init(&new_session->init_protector);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! can't initialize Init protector. sID=%u.\n", new_session->id));
		break;
	}		
	
	s = zrtp_status_ok;
	} while (0);
	
	if (zrtp_status_ok != s) {
		zrtp_sys_free(new_session);
		return s;
	}

    /* Add new session to the global list */    
    zrtp_mutex_lock(zrtp->sessions_protector);
    mlist_add(&zrtp->sessions_head, &new_session->_mlist);
    zrtp_mutex_unlock(zrtp->sessions_protector);
    
	*session = new_session;
	
    ZRTP_LOG(3, (_ZTU_,"Session initialization - DONE. sID=%u.\n\n", new_session->id));

    return zrtp_status_ok;
}