Store all sent and received messages to zrtp_session_t
This way we can calculate the hash checksums when at once instead of updating it in different places.
This commit is contained in:
parent
caebde67c4
commit
407344cf0a
|
@ -49,6 +49,11 @@ kvz_rtp::zrtp_msg::commit::commit(zrtp_session_t& session)
|
||||||
hmac_sha256.final(mac_full);
|
hmac_sha256.final(mac_full);
|
||||||
|
|
||||||
memcpy(&msg->mac, mac_full, sizeof(uint64_t));
|
memcpy(&msg->mac, mac_full, sizeof(uint64_t));
|
||||||
|
|
||||||
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.l_msg.commit.first = len_;
|
||||||
|
session.l_msg.commit.second = (kvz_rtp::zrtp_msg::zrtp_commit *)new uint8_t[len_];
|
||||||
|
memcpy(session.l_msg.commit.second, msg, len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
kvz_rtp::zrtp_msg::commit::~commit()
|
kvz_rtp::zrtp_msg::commit::~commit()
|
||||||
|
@ -104,5 +109,10 @@ rtp_error_t kvz_rtp::zrtp_msg::commit::parse_msg(kvz_rtp::zrtp_msg::receiver& re
|
||||||
memcpy(session.remote_hvi, msg->hvi, 32);
|
memcpy(session.remote_hvi, msg->hvi, 32);
|
||||||
memcpy(session.remote_hashes[3], msg->hash, 32);
|
memcpy(session.remote_hashes[3], msg->hash, 32);
|
||||||
|
|
||||||
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.r_msg.commit.first = len;
|
||||||
|
session.r_msg.commit.second = (kvz_rtp::zrtp_msg::zrtp_commit *)new uint8_t[len];
|
||||||
|
memcpy(session.r_msg.commit.second, msg, len);
|
||||||
|
|
||||||
return RTP_OK;
|
return RTP_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,11 @@ namespace kvz_rtp {
|
||||||
|
|
||||||
namespace zrtp_msg {
|
namespace zrtp_msg {
|
||||||
|
|
||||||
|
struct zrtp_confirm;
|
||||||
|
struct zrtp_commit;
|
||||||
|
struct zrtp_hello;
|
||||||
|
struct zrtp_dh;
|
||||||
|
|
||||||
PACKED_STRUCT(zrtp_header) {
|
PACKED_STRUCT(zrtp_header) {
|
||||||
uint8_t version:4;
|
uint8_t version:4;
|
||||||
uint16_t unused:12;
|
uint16_t unused:12;
|
||||||
|
|
|
@ -8,9 +8,18 @@
|
||||||
#define ZRTP_DH_PART1 "DHPart1 "
|
#define ZRTP_DH_PART1 "DHPart1 "
|
||||||
#define ZRTP_DH_PART2 "DHPart2 "
|
#define ZRTP_DH_PART2 "DHPart2 "
|
||||||
|
|
||||||
kvz_rtp::zrtp_msg::dh_key_exchange::dh_key_exchange(zrtp_session_t& session)
|
kvz_rtp::zrtp_msg::dh_key_exchange::dh_key_exchange(zrtp_session_t& session, int part)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Create ZRTP Commit message!");
|
const char *strs[2][2] = {
|
||||||
|
{
|
||||||
|
ZRTP_DH_PART1, "Responder"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ZRTP_DH_PART2, "Initiator"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG_DEBUG("Create ZRTP DHPart%d message", part);
|
||||||
|
|
||||||
frame_ = kvz_rtp::frame::alloc_zrtp_frame(sizeof(zrtp_dh));
|
frame_ = kvz_rtp::frame::alloc_zrtp_frame(sizeof(zrtp_dh));
|
||||||
rframe_ = kvz_rtp::frame::alloc_zrtp_frame(sizeof(zrtp_dh));
|
rframe_ = kvz_rtp::frame::alloc_zrtp_frame(sizeof(zrtp_dh));
|
||||||
|
@ -32,30 +41,6 @@ kvz_rtp::zrtp_msg::dh_key_exchange::dh_key_exchange(zrtp_session_t& session)
|
||||||
msg->msg_start.length = len_ - sizeof(zrtp_header);
|
msg->msg_start.length = len_ - sizeof(zrtp_header);
|
||||||
msg->crc = 0;
|
msg->crc = 0;
|
||||||
|
|
||||||
session.cctx.sha256->update((uint8_t *)msg, msg->msg_start.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
kvz_rtp::zrtp_msg::dh_key_exchange::~dh_key_exchange()
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Freeing DHPartN message...");
|
|
||||||
|
|
||||||
(void)kvz_rtp::frame::dealloc_frame(frame_);
|
|
||||||
(void)kvz_rtp::frame::dealloc_frame(rframe_);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtp_error_t kvz_rtp::zrtp_msg::dh_key_exchange::set_role(zrtp_session_t& session, int part)
|
|
||||||
{
|
|
||||||
zrtp_dh *msg = (zrtp_dh *)frame_;
|
|
||||||
|
|
||||||
const char *strs[2][2] = {
|
|
||||||
{
|
|
||||||
ZRTP_DH_PART1, "Responder"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ZRTP_DH_PART2, "Initiator"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
memcpy(&msg->msg_start.msgblock, strs[part - 1][0], 8);
|
memcpy(&msg->msg_start.msgblock, strs[part - 1][0], 8);
|
||||||
memcpy(msg->hash, session.hashes[1], 32);
|
memcpy(msg->hash, session.hashes[1], 32);
|
||||||
|
|
||||||
|
@ -100,7 +85,23 @@ rtp_error_t kvz_rtp::zrtp_msg::dh_key_exchange::set_role(zrtp_session_t& session
|
||||||
|
|
||||||
memcpy(msg->mac, mac_full, 8);
|
memcpy(msg->mac, mac_full, 8);
|
||||||
|
|
||||||
return RTP_OK;
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.l_msg.dh.first = len_;
|
||||||
|
session.l_msg.dh.second = (kvz_rtp::zrtp_msg::zrtp_dh *)new uint8_t[len_];
|
||||||
|
memcpy(session.l_msg.dh.second, msg, len_);
|
||||||
|
}
|
||||||
|
|
||||||
|
kvz_rtp::zrtp_msg::dh_key_exchange::dh_key_exchange(struct zrtp_dh *dh)
|
||||||
|
{
|
||||||
|
(void)dh;
|
||||||
|
}
|
||||||
|
|
||||||
|
kvz_rtp::zrtp_msg::dh_key_exchange::~dh_key_exchange()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Freeing DHPartN message...");
|
||||||
|
|
||||||
|
(void)kvz_rtp::frame::dealloc_frame(frame_);
|
||||||
|
(void)kvz_rtp::frame::dealloc_frame(rframe_);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtp_error_t kvz_rtp::zrtp_msg::dh_key_exchange::send_msg(socket_t& socket, sockaddr_in& addr)
|
rtp_error_t kvz_rtp::zrtp_msg::dh_key_exchange::send_msg(socket_t& socket, sockaddr_in& addr)
|
||||||
|
@ -150,5 +151,10 @@ rtp_error_t kvz_rtp::zrtp_msg::dh_key_exchange::parse_msg(kvz_rtp::zrtp_msg::rec
|
||||||
session.s2 = nullptr;
|
session.s2 = nullptr;
|
||||||
session.s3 = nullptr;
|
session.s3 = nullptr;
|
||||||
|
|
||||||
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.r_msg.dh.first = len;
|
||||||
|
session.r_msg.dh.second = (kvz_rtp::zrtp_msg::zrtp_dh *)new uint8_t[len];
|
||||||
|
memcpy(session.r_msg.dh.second, msg, len);
|
||||||
|
|
||||||
return RTP_OK;
|
return RTP_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@ namespace kvz_rtp {
|
||||||
|
|
||||||
class dh_key_exchange {
|
class dh_key_exchange {
|
||||||
public:
|
public:
|
||||||
dh_key_exchange(zrtp_session_t& session);
|
dh_key_exchange(zrtp_session_t& session, int part);
|
||||||
|
dh_key_exchange(struct zrtp_dh *dh);
|
||||||
~dh_key_exchange();
|
~dh_key_exchange();
|
||||||
|
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
|
@ -33,9 +34,6 @@ namespace kvz_rtp {
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
rtp_error_t parse_msg(kvz_rtp::zrtp_msg::receiver& receiver, zrtp_session_t& session);
|
rtp_error_t parse_msg(kvz_rtp::zrtp_msg::receiver& receiver, zrtp_session_t& session);
|
||||||
|
|
||||||
/* TODO: */
|
|
||||||
rtp_error_t set_role(zrtp_session_t& session, int part);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
kvz_rtp::frame::zrtp_frame *frame_;
|
kvz_rtp::frame::zrtp_frame *frame_;
|
||||||
kvz_rtp::frame::zrtp_frame *rframe_;
|
kvz_rtp::frame::zrtp_frame *rframe_;
|
||||||
|
|
|
@ -62,6 +62,11 @@ kvz_rtp::zrtp_msg::hello::hello(zrtp_session_t& session)
|
||||||
hmac_sha256.final(mac_full);
|
hmac_sha256.final(mac_full);
|
||||||
|
|
||||||
memcpy(&msg->mac, mac_full, sizeof(uint64_t));
|
memcpy(&msg->mac, mac_full, sizeof(uint64_t));
|
||||||
|
|
||||||
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.l_msg.hello.first = len_;
|
||||||
|
session.l_msg.hello.second = (kvz_rtp::zrtp_msg::zrtp_hello *)new uint8_t[len_];
|
||||||
|
memcpy(session.l_msg.hello.second, msg, len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
kvz_rtp::zrtp_msg::hello::~hello()
|
kvz_rtp::zrtp_msg::hello::~hello()
|
||||||
|
@ -142,7 +147,10 @@ rtp_error_t kvz_rtp::zrtp_msg::hello::parse_msg(kvz_rtp::zrtp_msg::receiver& rec
|
||||||
memcpy(&session.remote_macs[0], &msg->mac, 8);
|
memcpy(&session.remote_macs[0], &msg->mac, 8);
|
||||||
memcpy(&session.remote_hashes[3], msg->hash, 32);
|
memcpy(&session.remote_hashes[3], msg->hash, 32);
|
||||||
|
|
||||||
session.cctx.sha256->update((uint8_t *)msg, msg->msg_start.length);
|
/* Finally make a copy of the message and save it for later use */
|
||||||
|
session.r_msg.hello.first = len;
|
||||||
|
session.r_msg.hello.second = (kvz_rtp::zrtp_msg::zrtp_hello *)new uint8_t[len];
|
||||||
|
memcpy(session.r_msg.hello.second, msg, len);
|
||||||
|
|
||||||
return RTP_OK;
|
return RTP_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
#pragma once
|
/* #pragma once */
|
||||||
|
#ifndef UTIL_HH_2USO9BF5
|
||||||
|
#define UTIL_HH_2USO9BF5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
@ -198,3 +202,5 @@ static inline std::string generate_string(size_t length)
|
||||||
std::generate_n(str.begin(), length, randchar);
|
std::generate_n(str.begin(), length, randchar);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
#endif /* UTIL_HH_2USO9BF5 */
|
||||||
|
|
||||||
|
|
49
src/zrtp.cc
49
src/zrtp.cc
|
@ -164,7 +164,6 @@ rtp_error_t kvz_rtp::zrtp::init_session(bool& initiator)
|
||||||
session_.auth_tag_type = HS32;
|
session_.auth_tag_type = HS32;
|
||||||
session_.key_agreement_type = DH3k;
|
session_.key_agreement_type = DH3k;
|
||||||
session_.sas_type = B32;
|
session_.sas_type = B32;
|
||||||
session_.hvi[0] = kvz_rtp::random::generate_32();
|
|
||||||
|
|
||||||
int type = 0;
|
int type = 0;
|
||||||
size_t rto = 0;
|
size_t rto = 0;
|
||||||
|
@ -227,12 +226,10 @@ rtp_error_t kvz_rtp::zrtp::init_session(bool& initiator)
|
||||||
rtp_error_t kvz_rtp::zrtp::dh_part1()
|
rtp_error_t kvz_rtp::zrtp::dh_part1()
|
||||||
{
|
{
|
||||||
rtp_error_t ret = RTP_OK;
|
rtp_error_t ret = RTP_OK;
|
||||||
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_);
|
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_, 1);
|
||||||
size_t rto = 150;
|
size_t rto = 150;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
dhpart.set_role(session_, 1);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
set_timeout(rto);
|
set_timeout(rto);
|
||||||
|
|
||||||
|
@ -267,9 +264,7 @@ rtp_error_t kvz_rtp::zrtp::dh_part2()
|
||||||
int type = 0;
|
int type = 0;
|
||||||
size_t rto = 0;
|
size_t rto = 0;
|
||||||
rtp_error_t ret = RTP_OK;
|
rtp_error_t ret = RTP_OK;
|
||||||
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_);
|
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_, 2);
|
||||||
|
|
||||||
dhpart.set_role(session_, 2);
|
|
||||||
|
|
||||||
if ((ret = dhpart.parse_msg(receiver_, session_)) != RTP_OK) {
|
if ((ret = dhpart.parse_msg(receiver_, session_)) != RTP_OK) {
|
||||||
LOG_ERROR("Failed to parse DHPart1 Message!");
|
LOG_ERROR("Failed to parse DHPart1 Message!");
|
||||||
|
@ -391,34 +386,30 @@ rtp_error_t kvz_rtp::zrtp::init(uint32_t ssrc, socket_t& socket, sockaddr_in& ad
|
||||||
session_.capabilities = get_capabilities();
|
session_.capabilities = get_capabilities();
|
||||||
session_.capabilities.zid = zid_;
|
session_.capabilities.zid = zid_;
|
||||||
|
|
||||||
/* Now that our session parameters have been created, we can create
|
|
||||||
* DHPart2 message which is used, in conjunction with Hello message,
|
|
||||||
* to create the hash value of initiator (hvi) for Commit message
|
|
||||||
*
|
|
||||||
* dh_key_exchange() creates a DHPart2 message but this messages
|
|
||||||
* is used by both parties so responder will update the Message
|
|
||||||
* Block type in dh_part1() function once the execution gets
|
|
||||||
* there
|
|
||||||
*
|
|
||||||
* dh_key_exchange() will update crypto context's sha256 object */
|
|
||||||
auto dh_msg = kvz_rtp::zrtp_msg::dh_key_exchange(session_);
|
|
||||||
dh_msg.set_role(session_, 2);
|
|
||||||
|
|
||||||
/* Begin session by exchanging Hello and HelloACK messages.
|
/* Begin session by exchanging Hello and HelloACK messages.
|
||||||
*
|
*
|
||||||
* After begin_session() we know what remote is capable of
|
* After begin_session() we know what remote is capable of
|
||||||
* and whether we are compatible implementations
|
* and whether we are compatible implementations */
|
||||||
*
|
|
||||||
* begin_session() will update crypto context's sha256 object */
|
|
||||||
if ((ret = begin_session()) != RTP_OK) {
|
if ((ret = begin_session()) != RTP_OK) {
|
||||||
LOG_ERROR("Session initialization failed, ZRTP cannot be used!");
|
LOG_ERROR("Session initialization failed, ZRTP cannot be used!");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin_session() has updated current sha256 value with Hello message.
|
/* After begin_session() we have remote's Hello message and we can craft
|
||||||
* We can now obtain the digest of DHPart2 and Hello to get our hvi
|
* DHPart2 in the hopes that we're the Initiator.
|
||||||
* which is used in the next step when creating Commit message */
|
*
|
||||||
cctx_.sha256->final(session_.hvi);
|
* If this assumption proves to be false, we just discard the message
|
||||||
|
* and create DHPart1.
|
||||||
|
*
|
||||||
|
* Commit message contains hash value of initiator (hvi) which is the
|
||||||
|
* the hashed value of Initiators DHPart2 message and Responder's Hello
|
||||||
|
* message. This should be calculated now because the next step is choosing
|
||||||
|
* the the roles for participants. */
|
||||||
|
auto dh_msg = kvz_rtp::zrtp_msg::dh_key_exchange(session_, 2);
|
||||||
|
|
||||||
|
cctx_.sha256->update((uint8_t *)session_.l_msg.dh.second, session_.l_msg.dh.first);
|
||||||
|
cctx_.sha256->update((uint8_t *)session_.r_msg.hello.second, session_.r_msg.hello.first);
|
||||||
|
cctx_.sha256->final((uint8_t *)session_.hvi);
|
||||||
|
|
||||||
/* We're here which means that remote respond to us and sent a Hello message
|
/* We're here which means that remote respond to us and sent a Hello message
|
||||||
* with same version number as ours. This means that the implementations are
|
* with same version number as ours. This means that the implementations are
|
||||||
|
@ -442,6 +433,8 @@ rtp_error_t kvz_rtp::zrtp::init(uint32_t ssrc, socket_t& socket, sockaddr_in& ad
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: calculate shared secret here? */
|
||||||
|
|
||||||
if ((ret = initiator_finalize_session()) != RTP_OK) {
|
if ((ret = initiator_finalize_session()) != RTP_OK) {
|
||||||
LOG_ERROR("Failed to finalize session using Confirm2");
|
LOG_ERROR("Failed to finalize session using Confirm2");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -455,6 +448,8 @@ rtp_error_t kvz_rtp::zrtp::init(uint32_t ssrc, socket_t& socket, sockaddr_in& ad
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: calculate shared secret here? */
|
||||||
|
|
||||||
if ((ret = responder_finalize_session()) != RTP_OK) {
|
if ((ret = responder_finalize_session()) != RTP_OK) {
|
||||||
LOG_ERROR("Failed to finalize session using Confirm1/Conf2ACK");
|
LOG_ERROR("Failed to finalize session using Confirm1/Conf2ACK");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
18
src/zrtp.hh
18
src/zrtp.hh
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "util.hh"
|
|
||||||
#include "crypto/crypto.hh"
|
#include "crypto/crypto.hh"
|
||||||
|
#include "mzrtp/defines.hh"
|
||||||
#include "mzrtp/receiver.hh"
|
#include "mzrtp/receiver.hh"
|
||||||
|
|
||||||
namespace kvz_rtp {
|
namespace kvz_rtp {
|
||||||
|
@ -74,6 +74,13 @@ namespace kvz_rtp {
|
||||||
kvz_rtp::crypto::dh *dh;
|
kvz_rtp::crypto::dh *dh;
|
||||||
} zrtp_crypto_ctx_t;
|
} zrtp_crypto_ctx_t;
|
||||||
|
|
||||||
|
typedef struct zrtp_messages {
|
||||||
|
std::pair<size_t, struct kvz_rtp::zrtp_msg::zrtp_confirm *> confirm;
|
||||||
|
std::pair<size_t, struct kvz_rtp::zrtp_msg::zrtp_commit *> commit;
|
||||||
|
std::pair<size_t, struct kvz_rtp::zrtp_msg::zrtp_hello *> hello;
|
||||||
|
std::pair<size_t, struct kvz_rtp::zrtp_msg::zrtp_dh *> dh;
|
||||||
|
} zrtp_messages_t;
|
||||||
|
|
||||||
/* TODO: voisiko näitä structeja järjestellä jotenkin järkevämmin? */
|
/* TODO: voisiko näitä structeja järjestellä jotenkin järkevämmin? */
|
||||||
|
|
||||||
/* Collection of algorithms that are used by ZRTP
|
/* Collection of algorithms that are used by ZRTP
|
||||||
|
@ -125,6 +132,12 @@ namespace kvz_rtp {
|
||||||
|
|
||||||
/* Used by message classes */
|
/* Used by message classes */
|
||||||
zrtp_crypto_ctx_t cctx;
|
zrtp_crypto_ctx_t cctx;
|
||||||
|
|
||||||
|
/* Pointers to messages sent by us and messages received from remote.
|
||||||
|
* These are just to calculate various hash values */
|
||||||
|
zrtp_messages_t l_msg;
|
||||||
|
zrtp_messages_t r_msg;
|
||||||
|
|
||||||
} zrtp_session_t;
|
} zrtp_session_t;
|
||||||
|
|
||||||
class zrtp {
|
class zrtp {
|
||||||
|
@ -190,6 +203,9 @@ namespace kvz_rtp {
|
||||||
* Return RTP_TIMEOUT if no message is received from remote before T2 expires */
|
* Return RTP_TIMEOUT if no message is received from remote before T2 expires */
|
||||||
rtp_error_t dh_part2();
|
rtp_error_t dh_part2();
|
||||||
|
|
||||||
|
/* TODO: */
|
||||||
|
rtp_error_t calculate_shared_secret();
|
||||||
|
|
||||||
/* TODO: */
|
/* TODO: */
|
||||||
rtp_error_t responder_finalize_session();
|
rtp_error_t responder_finalize_session();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue