2020-01-22 08:58:50 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <winsock2.h>
|
|
|
|
|
#include <mswsock.h>
|
|
|
|
|
#include <inaddr.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "util.hh"
|
2020-01-28 07:47:04 +00:00
|
|
|
#include "crypto/crypto.hh"
|
2020-01-24 06:38:11 +00:00
|
|
|
#include "mzrtp/receiver.hh"
|
2020-01-22 08:58:50 +00:00
|
|
|
|
|
|
|
|
namespace kvz_rtp {
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
/* TODO: move to defines.hh */
|
2020-01-22 08:58:50 +00:00
|
|
|
typedef struct capabilities {
|
|
|
|
|
|
|
|
|
|
/* Supported ZRTP version */
|
|
|
|
|
uint32_t version;
|
|
|
|
|
|
|
|
|
|
/* ZID of this ZRTP instance */
|
|
|
|
|
uint8_t *zid;
|
|
|
|
|
|
|
|
|
|
/* Header of the supported algos etc. */
|
|
|
|
|
uint32_t header;
|
|
|
|
|
|
|
|
|
|
/* Supported hash algorithms (empty for us) */
|
|
|
|
|
std::vector<uint32_t> hash_algos;
|
|
|
|
|
|
|
|
|
|
/* Supported cipher algorithms (empty for us) */
|
|
|
|
|
std::vector<uint32_t> cipher_algos;
|
|
|
|
|
|
|
|
|
|
/* Supported authentication tag types (empty for us) */
|
|
|
|
|
std::vector<uint32_t> auth_tags;
|
|
|
|
|
|
|
|
|
|
/* Supported Key Agreement types (empty for us) */
|
|
|
|
|
std::vector<uint32_t> key_agreements;
|
|
|
|
|
|
|
|
|
|
/* Supported SAS types (empty for us) */
|
|
|
|
|
std::vector<uint32_t> sas_types;
|
|
|
|
|
} zrtp_capab_t;
|
|
|
|
|
|
2020-01-24 08:13:43 +00:00
|
|
|
/* DH exchange related information */
|
|
|
|
|
typedef struct zrtp_dh {
|
|
|
|
|
uint32_t retained1[2]; /* hash of retained shared secret 1 */
|
|
|
|
|
uint32_t retained2[2]; /* hash of retained shared secret 2 */
|
|
|
|
|
|
|
|
|
|
uint32_t aux_secret[2]; /* hash of auxiliary secret */
|
|
|
|
|
uint32_t pbx_secret[2]; /* hash of MiTM PBX secret */
|
|
|
|
|
} zrtp_dh_t;
|
|
|
|
|
|
2020-01-28 07:47:04 +00:00
|
|
|
/* One common crypto contex for all ZRTP functions */
|
|
|
|
|
typedef struct zrtp_crypto_ctx {
|
|
|
|
|
kvz_rtp::crypto::hmac::sha256 *hmac_sha256;
|
|
|
|
|
kvz_rtp::crypto::sha256 *sha256;
|
|
|
|
|
} zrtp_crypto_ctx_t;
|
|
|
|
|
|
|
|
|
|
/* TODO: voisiko näitä structeja järjestellä jotenkin järkevämmin? */
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
/* Collection of algorithms that are used by ZRTP
|
|
|
|
|
* (based on information gathered from Hello message) */
|
|
|
|
|
typedef struct zrtp_session {
|
2020-01-28 07:47:04 +00:00
|
|
|
uint32_t ssrc;
|
|
|
|
|
uint16_t seq;
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
uint32_t hash_algo;
|
|
|
|
|
uint32_t cipher_algo;
|
|
|
|
|
uint32_t auth_tag_type;
|
|
|
|
|
uint32_t key_agreement_type;
|
|
|
|
|
uint32_t sas_type;
|
2020-01-24 08:13:43 +00:00
|
|
|
|
2020-01-28 07:47:04 +00:00
|
|
|
/* Session capabilities (our and theirs) */
|
|
|
|
|
zrtp_capab_t capabilities; /* TODO: rename to ocapab */
|
|
|
|
|
zrtp_capab_t rcapab;
|
|
|
|
|
|
2020-01-28 08:53:29 +00:00
|
|
|
/* Hash value of initiator */
|
|
|
|
|
uint8_t hvi[32];
|
|
|
|
|
uint8_t remote_hvi[32];
|
|
|
|
|
|
2020-01-28 06:34:56 +00:00
|
|
|
/* Section 9 of RFC 6189 */
|
|
|
|
|
uint8_t hashes[4][32];
|
2020-01-28 07:47:04 +00:00
|
|
|
uint32_t remote_hashes[4][32];
|
|
|
|
|
|
|
|
|
|
uint64_t remote_macs[4];
|
2020-01-28 06:34:56 +00:00
|
|
|
|
2020-01-24 08:13:43 +00:00
|
|
|
zrtp_dh_t us;
|
|
|
|
|
zrtp_dh_t them;
|
2020-01-22 08:58:50 +00:00
|
|
|
|
2020-01-28 07:47:04 +00:00
|
|
|
/* Used by message classes */
|
|
|
|
|
zrtp_crypto_ctx_t cctx;
|
|
|
|
|
} zrtp_session_t;
|
2020-01-28 06:34:56 +00:00
|
|
|
|
2020-01-22 08:58:50 +00:00
|
|
|
class zrtp {
|
|
|
|
|
public:
|
|
|
|
|
zrtp();
|
|
|
|
|
~zrtp();
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
/* Initialize ZRTP session between us and remote
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_TIMEOUT if remote did not send messages in timely manner */
|
2020-01-22 08:58:50 +00:00
|
|
|
rtp_error_t init(uint32_t ssrc, socket_t& socket, sockaddr_in& addr);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
/* Set timeout for a socket, needed by backoff timers of ZRTP
|
|
|
|
|
*
|
|
|
|
|
* "timeout" tells the timeout in milliseconds
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_GENERIC_ERROR if timeout could not be set */
|
|
|
|
|
rtp_error_t set_timeout(size_t timeout);
|
|
|
|
|
|
|
|
|
|
/* Get our own capabilities, see struct capabilities above for more details */
|
|
|
|
|
zrtp_capab_t get_capabilities();
|
|
|
|
|
|
|
|
|
|
/* Generate zid for this ZRTP instance. ZID is a unique, 96-bit long ID */
|
2020-01-28 06:34:56 +00:00
|
|
|
void generate_zid();
|
|
|
|
|
|
2020-01-28 08:53:29 +00:00
|
|
|
/* Compare our and remote's hvi values to determine who is the initiator */
|
|
|
|
|
bool are_we_initiator(uint8_t *our_hvi, uint8_t *their_hvi);
|
|
|
|
|
|
2020-01-28 06:34:56 +00:00
|
|
|
/* Initialize the four session hashes defined in Section 9 of RFC 6189 */
|
|
|
|
|
void init_session_hashes();
|
2020-01-22 08:58:50 +00:00
|
|
|
|
|
|
|
|
/* Being the ZRTP session by sending a Hello message to remote,
|
2020-01-24 06:38:11 +00:00
|
|
|
* and responding to remote's Hello message using HelloAck message
|
2020-01-22 08:58:50 +00:00
|
|
|
*
|
|
|
|
|
* If session begins successfully, remote zrtp_capab_t are put into
|
|
|
|
|
* "remote_capab" for later use
|
|
|
|
|
*
|
2020-01-24 06:38:11 +00:00
|
|
|
* Return RTP_OK on success
|
2020-01-22 08:58:50 +00:00
|
|
|
* Return RTP_NOT_SUPPORTED if remote did not answer to our Hello messages */
|
|
|
|
|
rtp_error_t begin_session();
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
/* Select algorithms used by the session, exchange this information with remote
|
|
|
|
|
* and based on Commit messages, select roles for the participants (initiator/responder)
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK on success
|
|
|
|
|
* Return RTP_TIMEOUT if no message is received from remote before T2 expires */
|
|
|
|
|
rtp_error_t init_session(bool& initiator);
|
|
|
|
|
|
2020-01-24 08:13:43 +00:00
|
|
|
/* Perform Diffie-Hellman key exchange Part1 (responder)
|
|
|
|
|
* This message also acts as an ACK to Commit message */
|
|
|
|
|
rtp_error_t dh_part1();
|
|
|
|
|
|
|
|
|
|
/* Perform Diffie-Hellman key exchange Part2 (initiator)
|
|
|
|
|
* This message also acts as an ACK to DHPart1 message
|
|
|
|
|
*
|
|
|
|
|
* Return RTP_OK if DHPart2 was successful
|
|
|
|
|
* Return RTP_TIMEOUT if no message is received from remote before T2 expires */
|
|
|
|
|
rtp_error_t dh_part2();
|
|
|
|
|
|
2020-01-24 08:49:44 +00:00
|
|
|
/* TODO: */
|
|
|
|
|
rtp_error_t responder_finalize_session();
|
|
|
|
|
|
|
|
|
|
/* TODO: */
|
|
|
|
|
rtp_error_t initiator_finalize_session();
|
|
|
|
|
|
2020-01-22 08:58:50 +00:00
|
|
|
uint32_t ssrc_;
|
|
|
|
|
socket_t socket_;
|
|
|
|
|
sockaddr_in addr_;
|
|
|
|
|
|
|
|
|
|
/* Our own and remote capability structs */
|
|
|
|
|
zrtp_capab_t capab_;
|
|
|
|
|
zrtp_capab_t rcapab_;
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
kvz_rtp::zrtp_msg::receiver receiver_;
|
|
|
|
|
|
2020-01-28 07:47:04 +00:00
|
|
|
zrtp_crypto_ctx_t cctx_;
|
|
|
|
|
|
2020-01-24 06:38:11 +00:00
|
|
|
/* Initialized after Hello messages have been exchanged */
|
|
|
|
|
zrtp_session_t session_;
|
|
|
|
|
|
2020-01-22 08:58:50 +00:00
|
|
|
uint8_t *zid_;
|
|
|
|
|
};
|
|
|
|
|
};
|