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:
Aaro Altonen 2020-01-29 12:10:53 +02:00
parent caebde67c4
commit 407344cf0a
8 changed files with 105 additions and 61 deletions

View File

@ -49,6 +49,11 @@ kvz_rtp::zrtp_msg::commit::commit(zrtp_session_t& session)
hmac_sha256.final(mac_full);
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()
@ -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_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;
}

View File

@ -6,6 +6,11 @@ namespace kvz_rtp {
namespace zrtp_msg {
struct zrtp_confirm;
struct zrtp_commit;
struct zrtp_hello;
struct zrtp_dh;
PACKED_STRUCT(zrtp_header) {
uint8_t version:4;
uint16_t unused:12;

View File

@ -8,9 +8,18 @@
#define ZRTP_DH_PART1 "DHPart1 "
#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));
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->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->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);
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)
@ -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.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;
}

View File

@ -24,7 +24,8 @@ namespace kvz_rtp {
class dh_key_exchange {
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();
/* TODO: */
@ -33,9 +34,6 @@ namespace kvz_rtp {
/* TODO: */
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:
kvz_rtp::frame::zrtp_frame *frame_;
kvz_rtp::frame::zrtp_frame *rframe_;

View File

@ -62,6 +62,11 @@ kvz_rtp::zrtp_msg::hello::hello(zrtp_session_t& session)
hmac_sha256.final(mac_full);
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()
@ -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_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;
}

View File

@ -1,4 +1,8 @@
#pragma once
/* #pragma once */
#ifndef UTIL_HH_2USO9BF5
#define UTIL_HH_2USO9BF5
#ifdef _WIN32
#include <winsock2.h>
@ -198,3 +202,5 @@ static inline std::string generate_string(size_t length)
std::generate_n(str.begin(), length, randchar);
return str;
}
#endif /* UTIL_HH_2USO9BF5 */

View File

@ -164,7 +164,6 @@ rtp_error_t kvz_rtp::zrtp::init_session(bool& initiator)
session_.auth_tag_type = HS32;
session_.key_agreement_type = DH3k;
session_.sas_type = B32;
session_.hvi[0] = kvz_rtp::random::generate_32();
int type = 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 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;
int type = 0;
dhpart.set_role(session_, 1);
for (int i = 0; i < 10; ++i) {
set_timeout(rto);
@ -267,9 +264,7 @@ rtp_error_t kvz_rtp::zrtp::dh_part2()
int type = 0;
size_t rto = 0;
rtp_error_t ret = RTP_OK;
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_);
dhpart.set_role(session_, 2);
auto dhpart = kvz_rtp::zrtp_msg::dh_key_exchange(session_, 2);
if ((ret = dhpart.parse_msg(receiver_, session_)) != RTP_OK) {
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.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.
*
* After begin_session() we know what remote is capable of
* and whether we are compatible implementations
*
* begin_session() will update crypto context's sha256 object */
* and whether we are compatible implementations */
if ((ret = begin_session()) != RTP_OK) {
LOG_ERROR("Session initialization failed, ZRTP cannot be used!");
return ret;
}
/* begin_session() has updated current sha256 value with Hello message.
* We can now obtain the digest of DHPart2 and Hello to get our hvi
* which is used in the next step when creating Commit message */
cctx_.sha256->final(session_.hvi);
/* After begin_session() we have remote's Hello message and we can craft
* DHPart2 in the hopes that we're the Initiator.
*
* 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
* 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;
}
/* TODO: calculate shared secret here? */
if ((ret = initiator_finalize_session()) != RTP_OK) {
LOG_ERROR("Failed to finalize session using Confirm2");
return ret;
@ -455,6 +448,8 @@ rtp_error_t kvz_rtp::zrtp::init(uint32_t ssrc, socket_t& socket, sockaddr_in& ad
return ret;
}
/* TODO: calculate shared secret here? */
if ((ret = responder_finalize_session()) != RTP_OK) {
LOG_ERROR("Failed to finalize session using Confirm1/Conf2ACK");
return ret;

View File

@ -11,8 +11,8 @@
#include <vector>
#include "util.hh"
#include "crypto/crypto.hh"
#include "mzrtp/defines.hh"
#include "mzrtp/receiver.hh"
namespace kvz_rtp {
@ -74,6 +74,13 @@ namespace kvz_rtp {
kvz_rtp::crypto::dh *dh;
} 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? */
/* Collection of algorithms that are used by ZRTP
@ -125,6 +132,12 @@ namespace kvz_rtp {
/* Used by message classes */
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;
class zrtp {
@ -190,6 +203,9 @@ namespace kvz_rtp {
* Return RTP_TIMEOUT if no message is received from remote before T2 expires */
rtp_error_t dh_part2();
/* TODO: */
rtp_error_t calculate_shared_secret();
/* TODO: */
rtp_error_t responder_finalize_session();