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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
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_.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;
|
||||
|
|
18
src/zrtp.hh
18
src/zrtp.hh
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue