/*---------------------------------------------------------------------------*/ 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; }
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; }
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 }
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; }
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; }
/*----------------------------------------------------------------------------*/ 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; }