summaryrefslogtreecommitdiff
path: root/modules/gzrtp/stream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gzrtp/stream.cpp')
-rw-r--r--modules/gzrtp/stream.cpp281
1 files changed, 76 insertions, 205 deletions
diff --git a/modules/gzrtp/stream.cpp b/modules/gzrtp/stream.cpp
index b367112..d09ca3b 100644
--- a/modules/gzrtp/stream.cpp
+++ b/modules/gzrtp/stream.cpp
@@ -11,12 +11,10 @@
#include <libzrtpcpp/ZRtp.h>
#include <libzrtpcpp/ZrtpStateClass.h>
-#include <srtp/CryptoContext.h>
-#include <srtp/CryptoContextCtrl.h>
-#include <srtp/SrtpHandler.h>
#include "session.h"
#include "stream.h"
+#include "srtp.h"
// A burst of SRTP/SRTCP errors enough to display a warning
@@ -67,7 +65,28 @@ static enum pkt_type get_packet_type(const struct mbuf *mb)
ZRTPConfig::ZRTPConfig(const struct conf *conf, const char *conf_dir)
{
+#ifdef GZRTP_USE_RE_SRTP
+ // Standard ciphers only
+ zrtp.clear();
+
+ zrtp.addAlgo(HashAlgorithm, zrtpHashes.getByName(s256));
+
+ zrtp.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes3));
+ zrtp.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName(aes1));
+
+ zrtp.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec25));
+ zrtp.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh3k));
+ zrtp.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(ec38));
+ zrtp.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(dh2k));
+ zrtp.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName(mult));
+
+ zrtp.addAlgo(SasType, zrtpSasTypes.getByName(b32));
+
+ zrtp.addAlgo(AuthLength, zrtpAuthLengths.getByName(hs32));
+ zrtp.addAlgo(AuthLength, zrtpAuthLengths.getByName(hs80));
+#else
zrtp.setStandardConfig();
+#endif
str_ncpy(client_id, "baresip/gzrtp", sizeof(client_id));
@@ -87,37 +106,37 @@ SRTPStat::SRTPStat(const Stream *st, bool srtcp, uint64_t threshold)
}
-void SRTPStat::update(int32_t ret_code, bool quiet)
+void SRTPStat::update(int ret_code, bool quiet)
{
const char *err_msg;
uint64_t *burst;
- // SrtpHandler::unprotect/unprotectCtrl return codes
+ // Srtp::unprotect/unprotect_ctrl return codes
switch (ret_code) {
- case 1:
+ case 0:
++m_ok;
m_decode_burst = 0;
m_auth_burst = 0;
m_replay_burst = 0;
return;
- case 0:
+ case EBADMSG:
++m_decode;
burst = &m_decode_burst;
err_msg = "packet decode error";
break;
- case -1:
+ case EAUTH:
++m_auth;
burst = &m_auth_burst;
err_msg = "authentication failed";
break;
- case -2:
+ case EALREADY:
++m_replay;
burst = &m_replay_burst;
err_msg = "replay check failed";
break;
default:
- warning("zrtp: Unknown return code from unprotect: %d\n",
- ret_code);
+ warning("zrtp: %s unprotect failed: %m\n",
+ (m_control)? "SRTCP" : "SRTP", ret_code);
return;
}
@@ -156,10 +175,8 @@ Stream::Stream(int& err, const ZRTPConfig& config, Session *session,
, m_uh_rtp(NULL)
, m_uh_rtcp(NULL)
, m_media_type(media_type)
- , m_send_cc(NULL)
- , m_recv_cc(NULL)
- , m_send_cc_ctrl(NULL)
- , m_recv_cc_ctrl(NULL)
+ , m_send_srtp(NULL)
+ , m_recv_srtp(NULL)
, m_srtp_stat(this, false, SRTP_ERR_BURST_THRESHOLD)
, m_srtcp_stat(this, true, SRTP_ERR_BURST_THRESHOLD)
{
@@ -275,7 +292,7 @@ void Stream::stop()
// thus make sure we have a second retained shared secret available.
// Refer to RFC 6189bis, chapter 4.6.1 50 packets are about 1 second
// of audio data
- if (!m_zrtp->isMultiStream() && m_recv_cc && m_srtp_stat.ok() < 20) {
+ if (!m_zrtp->isMultiStream() && m_recv_srtp && m_srtp_stat.ok() < 20) {
debug("zrtp: Stream <%s>: received too few valid SRTP "
"packets (%u), storing RS2\n",
@@ -288,17 +305,11 @@ void Stream::stop()
m_zrtp->stopZrtp();
- delete m_send_cc;
- m_send_cc = NULL;
+ delete m_send_srtp;
+ m_send_srtp = NULL;
- delete m_recv_cc;
- m_recv_cc = NULL;
-
- delete m_send_cc_ctrl;
- m_send_cc_ctrl = NULL;
-
- delete m_recv_cc_ctrl;
- m_recv_cc_ctrl = NULL;
+ delete m_recv_srtp;
+ m_recv_srtp = NULL;
debug("zrtp: Stream <%s> stopped\n", media_name());
}
@@ -341,59 +352,30 @@ bool Stream::udp_helper_send(int *err, struct sa *src, struct mbuf *mb)
enum pkt_type ptype = get_packet_type(mb);
size_t len = mbuf_get_left(mb);
- size_t newlen = 0;
- bool rc = false;
+ int rerr = 0;
- if (ptype == PKT_TYPE_RTCP && m_send_cc_ctrl && len > 8) {
+ if (ptype == PKT_TYPE_RTCP && m_send_srtp && len > 8) {
- int32_t extra = (mbuf_get_space(mb) > len)?
- mbuf_get_space(mb) - len : 0;
-
- if (m_send_cc_ctrl->getTagLength() + 4 +
- m_send_cc_ctrl->getMkiLength() > extra) {
- warning("zrtp: Stream <%s>: No space left for SRTCP "
- "packet\n", media_name());
- *err = ENOMEM;
- return true;
- }
-
- rc = SrtpHandler::protectCtrl(m_send_cc_ctrl, mbuf_buf(mb),
- len, &newlen);
+ rerr = m_send_srtp->protect_ctrl(mb);
}
- else if (ptype == PKT_TYPE_RTP && m_send_cc && len > RTP_HEADER_SIZE) {
-
- int32_t extra = (mbuf_get_space(mb) > len)?
- mbuf_get_space(mb) - len : 0;
-
- if (m_send_cc->getTagLength() +
- m_send_cc->getMkiLength() > extra) {
- warning("zrtp: Stream <%s>: No space left for SRTP "
- "packet\n", media_name());
- *err = ENOMEM;
- return true;
- }
+ else if (ptype == PKT_TYPE_RTP && m_send_srtp &&
+ len > RTP_HEADER_SIZE) {
- rc = SrtpHandler::protect(m_send_cc, mbuf_buf(mb),
- len, &newlen);
+ rerr = m_send_srtp->protect(mb);
}
else
return false;
- if (!rc) {
- warning("zrtp: protect/protectCtrl failed, len: %u\n", len);
+ if (rerr) {
+ warning("zrtp: protect/protect_ctrl failed (len=%u): %m\n",
+ len, rerr);
+
+ if (rerr == ENOMEM)
+ *err = rerr;
// drop
return true;
}
- if (newlen > mbuf_get_space(mb)) {
- // this should never happen
- error_msg("zrtp: udp_helper_send: length > space (%u > %u)\n",
- newlen, mbuf_get_space(mb));
- abort();
- }
-
- mb->end = mb->pos + newlen;
-
return false;
}
@@ -415,39 +397,27 @@ bool Stream::udp_helper_recv(struct sa *src, struct mbuf *mb)
return false;
enum pkt_type ptype = get_packet_type(mb);
- size_t len = mbuf_get_left(mb);
- size_t newlen = 0;
- uint32_t rc;
-
- if (ptype == PKT_TYPE_RTCP && m_recv_cc_ctrl) {
+ int err = 0;
- rc = SrtpHandler::unprotectCtrl(m_recv_cc_ctrl, mbuf_buf(mb),
- len, &newlen);
+ if (ptype == PKT_TYPE_RTCP && m_recv_srtp) {
- m_srtcp_stat.update(rc);
+ err = m_recv_srtp->unprotect_ctrl(mb);
- if (rc != 1)
- // drop
- return true;
+ m_srtcp_stat.update(err);
}
- else if (ptype == PKT_TYPE_RTP && m_recv_cc) {
+ else if (ptype == PKT_TYPE_RTP && m_recv_srtp) {
- rc = SrtpHandler::unprotect(m_recv_cc, mbuf_buf(mb),
- len, &newlen, NULL);
+ err = m_recv_srtp->unprotect(mb);
- m_srtp_stat.update(rc);
+ m_srtp_stat.update(err);
- if (rc == 1) {
+ if (!err) {
// Got a good SRTP, check state and if in WaitConfAck
// (an Initiator state) then simulate a conf2Ack,
// refer to RFC 6189, chapter 4.6, last paragraph
if (m_zrtp->inState(WaitConfAck))
m_zrtp->conf2AckSecure();
}
- else {
- // drop
- return true;
- }
}
else if (ptype == PKT_TYPE_ZRTP) {
return recv_zrtp(mb);
@@ -455,7 +425,9 @@ bool Stream::udp_helper_recv(struct sa *src, struct mbuf *mb)
else
return false;
- mb->end = mb->pos + newlen;
+ if (err)
+ // drop
+ return true;
return false;
}
@@ -607,124 +579,27 @@ void Stream::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode)
bool Stream::srtpSecretsReady(SrtpSecret_t* secrets, EnableSecurity part)
{
- CryptoContext *cc = NULL;
- CryptoContextCtrl *cc_ctrl = NULL;
- int cipher;
- int authn;
- int auth_key_len;
- const uint8_t *key, *salt;
- uint32_t key_len, salt_len;
+ Srtp *s;
+ int err = 0;
debug("zrtp: Stream <%s>: secrets are ready for %s\n",
media_name(),
(part == ForSender)? "sender" : "receiver");
- switch (secrets->authAlgorithm) {
- case Sha1:
- authn = SrtpAuthenticationSha1Hmac;
- auth_key_len = 20;
- break;
- case Skein:
- authn = SrtpAuthenticationSkeinHmac;
- auth_key_len = 32;
- break;
- default:
- return false;
- }
-
- switch (secrets->symEncAlgorithm) {
- case Aes:
- cipher = SrtpEncryptionAESCM;
- break;
- case TwoFish:
- cipher = SrtpEncryptionTWOCM;
- break;
- default:
- return false;
- }
-
- if (part == ForSender) {
- // To encrypt packets: intiator uses initiator keys,
- // responder uses responder keys
- if (secrets->role == Initiator) {
- key = secrets->keyInitiator;
- key_len = secrets->initKeyLen / 8;
- salt = secrets->saltInitiator;
- salt_len = secrets->initSaltLen / 8;
- }
- else {
- key = secrets->keyResponder;
- key_len = secrets->respKeyLen / 8;
- salt = secrets->saltResponder;
- salt_len = secrets->respSaltLen / 8;
- }
- }
- else if (part == ForReceiver) {
- // To decrypt packets: intiator uses responder keys,
- // responder initiator keys
- if (secrets->role == Initiator) {
- key = secrets->keyResponder;
- key_len = secrets->respKeyLen / 8;
- salt = secrets->saltResponder;
- salt_len = secrets->respSaltLen / 8;
- }
- else {
- key = secrets->keyInitiator;
- key_len = secrets->initKeyLen / 8;
- salt = secrets->saltInitiator;
- salt_len = secrets->initSaltLen / 8;
- }
- }
- else {
+ s = new Srtp(err, secrets, part);
+ if (!s || err) {
+ warning("zrtp: Stream <%s>: Srtp creation failed: %m\n",
+ media_name(), err);
+ delete s;
return false;
}
- cc = new CryptoContext(
- 0, // SSRC (used for lookup)
- 0, // Roll-Over-Counter (ROC)
- 0L, // keyderivation << 48,
- cipher, // encryption algo
- authn, // authtentication algo
- (uint8_t *)key, // Master Key
- key_len, // Master Key length
- (uint8_t *)salt, // Master Salt
- salt_len, // Master Salt length
- key_len, // encryption keyl
- auth_key_len, // authentication key len
- salt_len, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag lenA
-
- cc_ctrl = new CryptoContextCtrl(
- 0, // SSRC (used for lookup)
- cipher, // encryption algo
- authn, // authtentication algo
- (uint8_t *)key, // Master Key
- key_len, // Master Key length
- (uint8_t *)salt, // Master Salt
- salt_len, // Master Salt length
- key_len, // encryption keyl
- auth_key_len, // authentication key len
- salt_len, // session salt len
- secrets->srtpAuthTagLen / 8); // authentication tag lenA
-
- if (!cc || !cc_ctrl) {
- delete cc;
- delete cc_ctrl;
-
+ if (part == ForSender)
+ m_send_srtp = s;
+ else if (part == ForReceiver)
+ m_recv_srtp = s;
+ else
return false;
- }
-
- cc->deriveSrtpKeys(0L);
- cc_ctrl->deriveSrtcpKeys();
-
- if (part == ForSender) {
- m_send_cc = cc;
- m_send_cc_ctrl = cc_ctrl;
- }
- else {
- m_recv_cc = cc;
- m_recv_cc_ctrl = cc_ctrl;
- }
return true;
}
@@ -737,17 +612,13 @@ void Stream::srtpSecretsOff(EnableSecurity part)
(part == ForSender)? "sender" : "receiver");
if (part == ForSender) {
- delete m_send_cc;
- delete m_send_cc_ctrl;
- m_send_cc = NULL;
- m_send_cc_ctrl = NULL;
+ delete m_send_srtp;
+ m_send_srtp = NULL;
}
if (part == ForReceiver) {
- delete m_recv_cc;
- delete m_recv_cc_ctrl;
- m_recv_cc = NULL;
- m_recv_cc_ctrl = NULL;
+ delete m_recv_srtp;
+ m_recv_srtp = NULL;
}
}