summaryrefslogtreecommitdiff
path: root/modules/dtls_srtp
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2014-06-18 23:09:46 +0200
committerAlfred E. Heggestad <aeh@db.org>2014-06-18 23:09:46 +0200
commit5b5eb4e1000ab9f941904a2b9cdae2965f880d89 (patch)
tree57c2473a8789804ed30dd8b6927bd418d7e7ecba /modules/dtls_srtp
parent0ae450a912a16c2649c3d7e903828f2013af081c (diff)
dtls_srtp: use DTLS-api from libre v0.4.9
for the dtls_srtp module to compile, you now need libre v0.4.9 or later. also added note about dependency to libre v0.4.9 in README and Debian file
Diffstat (limited to 'modules/dtls_srtp')
-rw-r--r--modules/dtls_srtp/dtls.c212
-rw-r--r--modules/dtls_srtp/dtls_srtp.c243
-rw-r--r--modules/dtls_srtp/dtls_srtp.h40
-rw-r--r--modules/dtls_srtp/module.mk2
-rw-r--r--modules/dtls_srtp/srtp.c51
-rw-r--r--modules/dtls_srtp/tls_udp.c395
6 files changed, 213 insertions, 730 deletions
diff --git a/modules/dtls_srtp/dtls.c b/modules/dtls_srtp/dtls.c
index e502903..6b517f2 100644
--- a/modules/dtls_srtp/dtls.c
+++ b/modules/dtls_srtp/dtls.c
@@ -3,205 +3,27 @@
*
* Copyright (C) 2010 Creytiv.com
*/
-#define OPENSSL_NO_KRB5 1
-#include <openssl/ssl.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
+
#include <re.h>
#include <baresip.h>
#include "dtls_srtp.h"
-/* note: shadow struct in libre's tls module */
-struct tls {
- SSL_CTX *ctx;
- char *pass; /* password for private key */
- /* ... */
- EVP_PKEY *key;
- X509 *x;
-};
-
-
-static void destructor(void *data)
-{
- struct tls *tls = data;
-
- if (tls->ctx)
- SSL_CTX_free(tls->ctx);
-
- if (tls->x)
- X509_free(tls->x);
- if (tls->key)
- EVP_PKEY_free(tls->key);
-
- mem_deref(tls->pass);
-}
-
-
-static int cert_generate(X509 *x, EVP_PKEY *privkey, const char *aor,
- int expire_days)
-{
- X509_EXTENSION *ext;
- X509_NAME *subj;
- int ret;
- int err = ENOMEM;
-
- subj = X509_NAME_new();
- if (!subj)
- goto out;
-
- X509_set_version(x, 2);
-
- ASN1_INTEGER_set(X509_get_serialNumber(x), rand_u32());
-
- ret = X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC,
- (unsigned char *)aor,
- (int)strlen(aor), -1, 0);
- if (!ret)
- goto out;
-
- if (!X509_set_issuer_name(x, subj) ||
- !X509_set_subject_name(x, subj))
- goto out;
-
- X509_gmtime_adj(X509_get_notBefore(x), 0);
- X509_gmtime_adj(X509_get_notAfter(x), 60*60*24*expire_days);
-
- if (!X509_set_pubkey(x, privkey))
- goto out;
-
- ext = X509V3_EXT_conf_nid(NULL, NULL,
- NID_basic_constraints, "CA:FALSE");
- if (1 != X509_add_ext(x, ext, -1))
- goto out;
- X509_EXTENSION_free(ext);
-
- err = 0;
-
- out:
- if (subj)
- X509_NAME_free(subj);
-
- return err;
-}
-
-
-static int tls_gen_selfsigned_cert(struct tls *tls, const char *aor)
-{
- RSA *rsa;
- int err = ENOMEM;
-
- rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
- if (!rsa)
- goto out;
-
- tls->key = EVP_PKEY_new();
- if (!tls->key)
- goto out;
- if (!EVP_PKEY_set1_RSA(tls->key, rsa))
- goto out;
-
- tls->x = X509_new();
- if (!tls->x)
- goto out;
-
- if (cert_generate(tls->x, tls->key, aor, 365))
- goto out;
-
- /* Sign the certificate */
- if (!X509_sign(tls->x, tls->key, EVP_sha1()))
- goto out;
-
- err = 0;
-
- out:
- if (rsa)
- RSA_free(rsa);
-
- return err;
-}
-
-
-int dtls_alloc_selfsigned(struct tls **tlsp, const char *aor,
- const char *srtp_profiles)
-{
- struct tls *tls;
- int r, err;
-
- if (!tlsp || !aor)
- return EINVAL;
-
- tls = mem_zalloc(sizeof(*tls), destructor);
- if (!tls)
- return ENOMEM;
-
- SSL_library_init();
-
- tls->ctx = SSL_CTX_new(DTLSv1_method());
- if (!tls->ctx) {
- err = ENOMEM;
- goto out;
- }
-
-#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
- SSL_CTX_set_verify_depth(tls->ctx, 1);
-#endif
-
- SSL_CTX_set_read_ahead(tls->ctx, 1);
-
- /* Generate self-signed certificate */
- err = tls_gen_selfsigned_cert(tls, aor);
- if (err) {
- warning("dtls: failed to generate certificate (%s): %m\n",
- aor, err);
- goto out;
- }
-
- r = SSL_CTX_use_certificate(tls->ctx, tls->x);
- if (r != 1) {
- err = EINVAL;
- goto out;
- }
-
- r = SSL_CTX_use_PrivateKey(tls->ctx, tls->key);
- if (r != 1) {
- err = EINVAL;
- goto out;
- }
-
- if (0 != SSL_CTX_set_tlsext_use_srtp(tls->ctx, srtp_profiles)) {
- warning("dtls: could not enable SRTP for profiles '%s'\n",
- srtp_profiles);
- err = ENOSYS;
- goto out;
- }
-
- err = 0;
- out:
- if (err)
- mem_deref(tls);
- else
- *tlsp = tls;
-
- return err;
-}
-
-
int dtls_print_sha1_fingerprint(struct re_printf *pf, const struct tls *tls)
{
- uint8_t md[64];
- unsigned int i, len;
+ uint8_t md[20];
+ unsigned int i;
int err = 0;
- if (!pf || !tls)
+ if (!tls)
return EINVAL;
- len = sizeof(md);
- if (1 != X509_digest(tls->x, EVP_sha1(), md, &len))
- return ENOENT;
+ err = tls_fingerprint(tls, TLS_FINGERPRINT_SHA1, md, sizeof(md));
+ if (err)
+ return err;
- for (i=0; i<len; i++) {
- err |= re_hprintf(pf, "%s%02x", i==0?"":":", md[i]);
+ for (i=0; i<sizeof(md); i++) {
+ err |= re_hprintf(pf, "%s%02x", i==0 ? "" : ":", md[i]);
}
return err;
@@ -210,19 +32,19 @@ int dtls_print_sha1_fingerprint(struct re_printf *pf, const struct tls *tls)
int dtls_print_sha256_fingerprint(struct re_printf *pf, const struct tls *tls)
{
- uint8_t md[64];
- unsigned int i, len;
+ uint8_t md[32];
+ unsigned int i;
int err = 0;
- if (!pf || !tls)
+ if (!tls)
return EINVAL;
- len = sizeof(md);
- if (1 != X509_digest(tls->x, EVP_sha256(), md, &len))
- return ENOENT;
+ err = tls_fingerprint(tls, TLS_FINGERPRINT_SHA256, md, sizeof(md));
+ if (err)
+ return err;
- for (i=0; i<len; i++) {
- err |= re_hprintf(pf, "%s%02x", i==0?"":":", md[i]);
+ for (i=0; i<sizeof(md); i++) {
+ err |= re_hprintf(pf, "%s%02x", i==0 ? "" : ":", md[i]);
}
return err;
diff --git a/modules/dtls_srtp/dtls_srtp.c b/modules/dtls_srtp/dtls_srtp.c
index b25c143..2796080 100644
--- a/modules/dtls_srtp/dtls_srtp.c
+++ b/modules/dtls_srtp/dtls_srtp.c
@@ -41,7 +41,7 @@ struct menc_sess {
/* media */
struct dtls_srtp {
- struct sock sockv[2];
+ struct comp compv[2];
const struct menc_sess *sess;
struct sdp_media *sdpm;
struct tmr tmr;
@@ -72,13 +72,14 @@ static void destructor(void *arg)
tmr_cancel(&st->tmr);
for (i=0; i<2; i++) {
- struct sock *s = &st->sockv[i];
-
- mem_deref(s->uh_srtp);
- mem_deref(s->dtls);
- mem_deref(s->app_sock); /* must be freed last */
- mem_deref(s->tx);
- mem_deref(s->rx);
+ struct comp *c = &st->compv[i];
+
+ mem_deref(c->uh_srtp);
+ mem_deref(c->tls_conn);
+ mem_deref(c->dtls_sock);
+ mem_deref(c->app_sock); /* must be freed last */
+ mem_deref(c->tx);
+ mem_deref(c->rx);
}
mem_deref(st->sdpm);
@@ -87,75 +88,52 @@ static void destructor(void *arg)
static bool verify_fingerprint(const struct sdp_session *sess,
const struct sdp_media *media,
- struct dtls_flow *tc)
+ struct tls_conn *tc)
{
struct pl hash;
- char hashstr[32];
- uint8_t md_sdp[64];
+ uint8_t md_sdp[32], md_dtls[32];
size_t sz_sdp = sizeof(md_sdp);
- struct tls_fingerprint tls_fp;
+ size_t sz_dtls;
+ enum tls_fingerprint type;
+ int err;
if (sdp_fingerprint_decode(sdp_rattr(sess, media, "fingerprint"),
&hash, md_sdp, &sz_sdp))
return false;
- pl_strcpy(&hash, hashstr, sizeof(hashstr));
+ if (0 == pl_strcasecmp(&hash, "sha-1")) {
+ type = TLS_FINGERPRINT_SHA1;
+ sz_dtls = 20;
+ }
+ else if (0 == pl_strcasecmp(&hash, "sha-256")) {
+ type = TLS_FINGERPRINT_SHA256;
+ sz_dtls = 32;
+ }
+ else {
+ warning("dtls_srtp: unknown fingerprint '%r'\n", &hash);
+ return false;
+ }
- if (dtls_get_remote_fingerprint(tc, hashstr, &tls_fp)) {
- warning("dtls_srtp: could not get DTLS fingerprint\n");
+ err = tls_peer_fingerprint(tc, type, md_dtls, sizeof(md_dtls));
+ if (err) {
+ warning("dtls_srtp: could not get DTLS fingerprint (%m)\n",
+ err);
return false;
}
- if (sz_sdp != tls_fp.len || 0 != memcmp(md_sdp, tls_fp.md, sz_sdp)) {
- warning("dtls_srtp: %s fingerprint mismatch\n", hashstr);
- info("DTLS: %w\n", tls_fp.md, (size_t)tls_fp.len);
+ if (sz_sdp != sz_dtls || 0 != memcmp(md_sdp, md_dtls, sz_sdp)) {
+ warning("dtls_srtp: %r fingerprint mismatch\n", &hash);
info("SDP: %w\n", md_sdp, sz_sdp);
+ info("DTLS: %w\n", md_dtls, sz_dtls);
return false;
}
- info("dtls_srtp: verified %s fingerprint OK\n", hashstr);
+ info("dtls_srtp: verified %r fingerprint OK\n", &hash);
return true;
}
-static void dtls_established_handler(int err, struct dtls_flow *flow,
- const char *profile,
- const struct key *client_key,
- const struct key *server_key,
- void *arg)
-{
- struct sock *sock = arg;
- const struct dtls_srtp *ds = sock->ds;
-
- if (!verify_fingerprint(ds->sess->sdp, ds->sdpm, flow)) {
- warning("dtls_srtp: could not verify remote fingerprint\n");
- if (ds->sess->errorh)
- ds->sess->errorh(EPIPE, ds->sess->arg);
- return;
- }
-
- sock->negotiated = true;
-
- info("dtls_srtp: ---> DTLS-SRTP complete (%s/%s) Profile=%s\n",
- sdp_media_name(ds->sdpm),
- sock->is_rtp ? "RTP" : "RTCP", profile);
-
- err |= srtp_stream_add(&sock->tx, profile,
- ds->active ? client_key : server_key,
- true);
-
- err |= srtp_stream_add(&sock->rx, profile,
- ds->active ? server_key : client_key,
- false);
-
- err |= srtp_install(sock);
- if (err) {
- warning("dtls_srtp: srtp_install: %m\n", err);
- }
-}
-
-
static int session_alloc(struct menc_sess **sessp,
struct sdp_session *sdp, bool offerer,
menc_error_h *errorh, void *arg)
@@ -170,10 +148,10 @@ static int session_alloc(struct menc_sess **sessp,
if (!sess)
return ENOMEM;
- sess->sdp = mem_ref(sdp);
+ sess->sdp = mem_ref(sdp);
sess->offerer = offerer;
- sess->errorh = errorh;
- sess->arg = arg;
+ sess->errorh = errorh;
+ sess->arg = arg;
/* RFC 4145 */
err = sdp_session_set_lattr(sdp, true, "setup",
@@ -197,27 +175,113 @@ static int session_alloc(struct menc_sess **sessp,
}
-static int media_start_sock(struct sock *sock, struct sdp_media *sdpm)
+static void dtls_estab_handler(void *arg)
+{
+ struct comp *comp = arg;
+ const struct dtls_srtp *ds = comp->ds;
+ enum srtp_suite suite;
+ uint8_t cli_key[30], srv_key[30];
+ int err;
+
+ if (!verify_fingerprint(ds->sess->sdp, ds->sdpm, comp->tls_conn)) {
+ warning("dtls_srtp: could not verify remote fingerprint\n");
+ if (ds->sess->errorh)
+ ds->sess->errorh(EPIPE, ds->sess->arg);
+ return;
+ }
+
+ err = tls_srtp_keyinfo(comp->tls_conn, &suite,
+ cli_key, sizeof(cli_key),
+ srv_key, sizeof(srv_key));
+ if (err) {
+ warning("dtls_srtp: could not get SRTP keyinfo (%m)\n", err);
+ return;
+ }
+
+ comp->negotiated = true;
+
+ info("dtls_srtp: ---> DTLS-SRTP complete (%s/%s) Profile=%s\n",
+ sdp_media_name(ds->sdpm),
+ comp->is_rtp ? "RTP" : "RTCP", srtp_suite_name(suite));
+
+ err |= srtp_stream_add(&comp->tx, suite,
+ ds->active ? cli_key : srv_key, 30, true);
+ err |= srtp_stream_add(&comp->rx, suite,
+ ds->active ? srv_key : cli_key, 30, false);
+
+ err |= srtp_install(comp);
+ if (err) {
+ warning("dtls_srtp: srtp_install: %m\n", err);
+ }
+
+ /* todo: notify application that crypto is up and running */
+}
+
+
+static void dtls_close_handler(int err, void *arg)
+{
+ struct comp *comp = arg;
+
+ info("dtls_srtp: dtls-connection closed (%m)\n", err);
+
+ if (!comp->negotiated) {
+
+ if (comp->ds->sess->errorh)
+ comp->ds->sess->errorh(err, comp->ds->sess->arg);
+ }
+}
+
+
+static void dtls_conn_handler(const struct sa *peer, void *arg)
+{
+ struct comp *comp = arg;
+ int err;
+ (void)peer;
+
+ err = dtls_accept(&comp->tls_conn, tls, comp->dtls_sock,
+ dtls_estab_handler, NULL, dtls_close_handler, comp);
+ if (err) {
+ warning("dtls_srtp: dtls_accept failed (%m)\n", err);
+ return;
+ }
+}
+
+
+static int component_start(struct comp *comp, struct sdp_media *sdpm)
{
struct sa raddr;
int err = 0;
- if (!sock->app_sock || sock->negotiated || sock->dtls)
+ if (!comp->app_sock || comp->negotiated || comp->dtls_sock)
return 0;
- if (sock->is_rtp)
+ if (comp->is_rtp)
raddr = *sdp_media_raddr(sdpm);
else
sdp_media_raddr_rtcp(sdpm, &raddr);
- if (sa_isset(&raddr, SA_ALL)) {
+ err = dtls_listen(&comp->dtls_sock, NULL,
+ comp->app_sock, 2, LAYER_DTLS,
+ dtls_conn_handler, comp);
+ if (err) {
+ warning("dtls_srtp: dtls_listen failed (%m)\n", err);
+ return err;
+ }
- err = dtls_flow_alloc(&sock->dtls, tls, sock->app_sock,
- dtls_established_handler, sock);
- if (err)
- return err;
+ if (sa_isset(&raddr, SA_ALL)) {
- err = dtls_flow_start(sock->dtls, &raddr, sock->ds->active);
+ if (comp->ds->active && !comp->tls_conn) {
+
+ err = dtls_connect(&comp->tls_conn, tls,
+ comp->dtls_sock, &raddr,
+ dtls_estab_handler, NULL,
+ dtls_close_handler, comp);
+ if (err) {
+ warning("dtls_srtp: dtls_connect()"
+ " failed (%m)\n", err);
+ return err;
+ }
+ }
}
return err;
@@ -231,16 +295,16 @@ static int media_start(struct dtls_srtp *st, struct sdp_media *sdpm)
if (st->started)
return 0;
- debug("dtls_srtp: media_start: '%s' mux=%d, active=%d\n",
- sdp_media_name(sdpm), st->mux, st->active);
+ info("dtls_srtp: media=%s -- start DTLS %s\n",
+ sdp_media_name(sdpm), st->active ? "client" : "server");
if (!sdp_media_has_media(sdpm))
return 0;
- err = media_start_sock(&st->sockv[0], sdpm);
+ err = component_start(&st->compv[0], sdpm);
if (!st->mux)
- err |= media_start_sock(&st->sockv[1], sdpm);
+ err |= component_start(&st->compv[1], sdpm);
if (err)
return err;
@@ -283,14 +347,14 @@ static int media_alloc(struct menc_media **mp, struct menc_sess *sess,
st->sess = sess;
st->sdpm = mem_ref(sdpm);
- st->sockv[0].app_sock = mem_ref(rtpsock);
- st->sockv[1].app_sock = mem_ref(rtcpsock);
+ st->compv[0].app_sock = mem_ref(rtpsock);
+ st->compv[1].app_sock = mem_ref(rtcpsock);
for (i=0; i<2; i++)
- st->sockv[i].ds = st;
+ st->compv[i].ds = st;
- st->sockv[0].is_rtp = true;
- st->sockv[1].is_rtp = false;
+ st->compv[0].is_rtp = true;
+ st->compv[1].is_rtp = false;
if (err) {
mem_deref(st);
@@ -300,7 +364,7 @@ static int media_alloc(struct menc_media **mp, struct menc_sess *sess,
*mp = (struct menc_media *)st;
setup:
- st->mux = (rtpsock == rtcpsock);
+ st->mux = (rtpsock == rtcpsock) || (rtcpsock == NULL);
setup = sdp_rattr(st->sess->sdp, st->sdpm, "setup");
if (setup) {
@@ -369,9 +433,28 @@ static int module_init(void)
return ENOSYS;
}
- err = dtls_alloc_selfsigned(&tls, "dtls@baresip", srtp_profiles);
- if (err)
+ err = tls_alloc(&tls, TLS_METHOD_DTLSV1, NULL, NULL);
+ if (err) {
+ warning("dtls_srtp: failed to create DTLS context (%m)\n",
+ err);
+ return err;
+ }
+
+ err = tls_set_selfsigned(tls, "dtls@baresip");
+ if (err) {
+ warning("dtls_srtp: failed to self-sign certificate (%m)\n",
+ err);
return err;
+ }
+
+ tls_set_verify_client(tls);
+
+ err = tls_set_srtp(tls, srtp_profiles);
+ if (err) {
+ warning("dtls_srtp: failed to enable SRTP profile (%m)\n",
+ err);
+ return err;
+ }
menc_register(&dtls_srtpf);
menc_register(&dtls_srtp);
diff --git a/modules/dtls_srtp/dtls_srtp.h b/modules/dtls_srtp/dtls_srtp.h
index 6f85bf3..531134c 100644
--- a/modules/dtls_srtp/dtls_srtp.h
+++ b/modules/dtls_srtp/dtls_srtp.h
@@ -10,9 +10,10 @@ enum {
LAYER_DTLS = 20, /* must be above zero */
};
-struct sock {
- const struct dtls_srtp *ds;
- struct dtls_flow *dtls;
+struct comp {
+ const struct dtls_srtp *ds; /* parent */
+ struct dtls_sock *dtls_sock;
+ struct tls_conn *tls_conn;
struct srtp_stream *tx;
struct srtp_stream *rx;
struct udp_helper *uh_srtp;
@@ -21,39 +22,12 @@ struct sock {
bool is_rtp;
};
-struct key {
- uint8_t key[256];
- size_t key_len;
- uint8_t salt[256];
- size_t salt_len;
-};
-
-
/* dtls.c */
-int dtls_alloc_selfsigned(struct tls **tlsp, const char *aor,
- const char *srtp_profile);
int dtls_print_sha1_fingerprint(struct re_printf *pf, const struct tls *tls);
int dtls_print_sha256_fingerprint(struct re_printf *pf, const struct tls *tls);
/* srtp.c */
-int srtp_stream_add(struct srtp_stream **sp, const char *profile,
- const struct key *key, bool tx);
-int srtp_install(struct sock *sock);
-
-
-/* tls_udp.c */
-struct dtls_flow;
-
-typedef void (dtls_estab_h)(int err, struct dtls_flow *tc,
- const char *profile,
- const struct key *client_key,
- const struct key *server_key,
- void *arg);
-
-int dtls_flow_alloc(struct dtls_flow **flowp, struct tls *tls,
- struct udp_sock *us, dtls_estab_h *estabh, void *arg);
-int dtls_flow_start(struct dtls_flow *flow, const struct sa *peer,
- bool active);
-int dtls_get_remote_fingerprint(const struct dtls_flow *flow, const char *type,
- struct tls_fingerprint *fp);
+int srtp_stream_add(struct srtp_stream **sp, enum srtp_suite suite,
+ const uint8_t *key, size_t key_size, bool tx);
+int srtp_install(struct comp *comp);
diff --git a/modules/dtls_srtp/module.mk b/modules/dtls_srtp/module.mk
index 87dc952..2e9b6d5 100644
--- a/modules/dtls_srtp/module.mk
+++ b/modules/dtls_srtp/module.mk
@@ -5,7 +5,7 @@
#
MOD := dtls_srtp
-$(MOD)_SRCS += dtls_srtp.c dtls.c srtp.c tls_udp.c
+$(MOD)_SRCS += dtls_srtp.c srtp.c dtls.c
$(MOD)_LFLAGS += -lsrtp
include mk/mod.mk
diff --git a/modules/dtls_srtp/srtp.c b/modules/dtls_srtp/srtp.c
index b68ebc1..554a23d 100644
--- a/modules/dtls_srtp/srtp.c
+++ b/modules/dtls_srtp/srtp.c
@@ -89,7 +89,7 @@ static void destructor(void *arg)
static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
{
- struct sock *sock = arg;
+ struct comp *comp = arg;
err_status_t e;
int len;
(void)dst;
@@ -106,10 +106,10 @@ static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
}
if (is_rtcp_packet(mb)) {
- e = srtp_protect_rtcp(sock->tx->srtp, mbuf_buf(mb), &len);
+ e = srtp_protect_rtcp(comp->tx->srtp, mbuf_buf(mb), &len);
}
else {
- e = srtp_protect(sock->tx->srtp, mbuf_buf(mb), &len);
+ e = srtp_protect(comp->tx->srtp, mbuf_buf(mb), &len);
}
if (err_status_ok != e) {
@@ -129,7 +129,7 @@ static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
- struct sock *sock = arg;
+ struct comp *comp = arg;
err_status_t e;
int len;
(void)src;
@@ -140,10 +140,10 @@ static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
len = (int)mbuf_get_left(mb);
if (is_rtcp_packet(mb)) {
- e = srtp_unprotect_rtcp(sock->rx->srtp, mbuf_buf(mb), &len);
+ e = srtp_unprotect_rtcp(comp->rx->srtp, mbuf_buf(mb), &len);
}
else {
- e = srtp_unprotect(sock->rx->srtp, mbuf_buf(mb), &len);
+ e = srtp_unprotect(comp->rx->srtp, mbuf_buf(mb), &len);
}
if (e != err_status_ok) {
@@ -160,37 +160,38 @@ static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
}
-int srtp_stream_add(struct srtp_stream **sp, const char *profile,
- const struct key *key, bool tx)
+int srtp_stream_add(struct srtp_stream **sp, enum srtp_suite suite,
+ const uint8_t *key, size_t key_size, bool tx)
{
struct srtp_stream *s;
err_status_t e;
int err = 0;
- if (!sp || !key || key->key_len > SRTP_MAX_KEY_LEN)
+ if (!sp || !key || key_size > SRTP_MAX_KEY_LEN)
return EINVAL;
s = mem_zalloc(sizeof(*s), destructor);
if (!s)
return ENOMEM;
- memcpy(s->key, key->key, key->key_len);
- append_salt_to_key(s->key, (unsigned int)key->key_len,
- (unsigned char *)key->salt,
- (unsigned int)key->salt_len);
+ memcpy(s->key, key, sizeof(s->key));
/* note: policy and key must be on the heap */
- if (0 == str_casecmp(profile, "SRTP_AES128_CM_SHA1_80")) {
- crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtp);
- crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtcp);
- }
- else if (0 == str_casecmp(profile, "SRTP_AES128_CM_SHA1_32")) {
+ switch (suite) {
+
+ case SRTP_AES_CM_128_HMAC_SHA1_32:
crypto_policy_set_aes_cm_128_hmac_sha1_32(&s->policy.rtp);
crypto_policy_set_aes_cm_128_hmac_sha1_32(&s->policy.rtcp);
- }
- else {
- warning("srtp: unsupported profile: %s\n", profile);
+ break;
+
+ case SRTP_AES_CM_128_HMAC_SHA1_80:
+ crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtp);
+ crypto_policy_set_aes_cm_128_hmac_sha1_80(&s->policy.rtcp);
+ break;
+
+ default:
+ warning("srtp: unsupported crypto suite: %d\n", suite);
err = ENOSYS;
goto out;
}
@@ -217,11 +218,9 @@ int srtp_stream_add(struct srtp_stream **sp, const char *profile,
}
-int srtp_install(struct sock *sock)
+int srtp_install(struct comp *comp)
{
- return udp_register_helper(&sock->uh_srtp, sock->app_sock,
+ return udp_register_helper(&comp->uh_srtp, comp->app_sock,
LAYER_SRTP,
- send_handler,
- recv_handler,
- sock);
+ send_handler, recv_handler, comp);
}
diff --git a/modules/dtls_srtp/tls_udp.c b/modules/dtls_srtp/tls_udp.c
deleted file mode 100644
index 86a6b92..0000000
--- a/modules/dtls_srtp/tls_udp.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/**
- * @file dtls_srtp/tls_udp.c DTLS socket for DTLS-SRTP
- *
- * Copyright (C) 2010 Creytiv.com
- */
-
-#define OPENSSL_NO_KRB5 1
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <re.h>
-#include <baresip.h>
-#include "dtls_srtp.h"
-
-
-/* note: shadow struct in dtls.c */
-struct tls {
- SSL_CTX *ctx;
-};
-
-struct dtls_flow {
- struct udp_helper *uh;
- struct udp_sock *us;
- struct tls *tls;
- struct tmr tmr;
- struct sa peer;
- SSL *ssl;
- BIO *sbio_out;
- BIO *sbio_in;
- bool up;
- dtls_estab_h *estabh;
- void *arg;
-};
-
-
-static void check_timer(struct dtls_flow *flow);
-
-
-static int bio_create(BIO *b)
-{
- b->init = 1;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
-
- return 1;
-}
-
-
-static int bio_destroy(BIO *b)
-{
- if (!b)
- return 0;
-
- b->ptr = NULL;
- b->init = 0;
- b->flags = 0;
-
- return 1;
-}
-
-
-static int bio_write(BIO *b, const char *buf, int len)
-{
- struct dtls_flow *tc = b->ptr;
- struct mbuf *mb;
- enum {SPACE = 4}; /* sizeof TURN channel header */
- int err;
-
- mb = mbuf_alloc(SPACE + len);
- if (!mb)
- return -1;
-
- (void)mbuf_fill(mb, 0x00, SPACE);
- (void)mbuf_write_mem(mb, (void *)buf, len);
-
- mb->pos = SPACE;
-
- err = udp_send_helper(tc->us, &tc->peer, mb, tc->uh);
- if (err) {
- warning("dtls: udp_send_helper: %m\n", err);
- }
-
- mem_deref(mb);
-
- return err ? -1 : len;
-}
-
-
-static long bio_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
- (void)b;
- (void)num;
- (void)ptr;
-
- if (cmd == BIO_CTRL_FLUSH) {
- /* The OpenSSL library needs this */
- return 1;
- }
-
- return 0;
-}
-
-
-static struct bio_method_st bio_udp_send = {
- BIO_TYPE_SOURCE_SINK,
- "udp_send",
- bio_write,
- 0,
- 0,
- 0,
- bio_ctrl,
- bio_create,
- bio_destroy,
- 0
-};
-
-
-static int verify_callback(int ok, X509_STORE_CTX *ctx)
-{
- (void)ok;
- (void)ctx;
- return 1; /* We trust the certificate from peer */
-}
-
-
-#if defined (DTLS_CTRL_HANDLE_TIMEOUT) && defined(DTLS_CTRL_GET_TIMEOUT)
-static void timeout(void *arg)
-{
- struct dtls_flow *tc = arg;
-
- DTLSv1_handle_timeout(tc->ssl);
-
- check_timer(tc);
-}
-#endif
-
-
-static void check_timer(struct dtls_flow *tc)
-{
-#if defined (DTLS_CTRL_HANDLE_TIMEOUT) && defined (DTLS_CTRL_GET_TIMEOUT)
- struct timeval tv = {0, 0};
- long x;
-
- x = DTLSv1_get_timeout(tc->ssl, &tv);
-
- if (x) {
- uint64_t delay = tv.tv_sec * 1000 + tv.tv_usec / 1000;
-
- tmr_start(&tc->tmr, delay, timeout, tc);
- }
-
-#else
- (void)tc;
-#endif
-}
-
-
-static int get_srtp_key_info(const struct dtls_flow *tc, char *name, size_t sz,
- struct key *client_key, struct key *server_key)
-{
- SRTP_PROTECTION_PROFILE *sel;
- const char *keymatexportlabel = "EXTRACTOR-dtls_srtp";
- uint8_t exportedkeymat[1024], *p;
- int keymatexportlen;
- size_t kl = 128, sl = 112;
-
- sel = SSL_get_selected_srtp_profile(tc->ssl);
- if (!sel)
- return ENOENT;
-
- str_ncpy(name, sel->name, sz);
-
- kl /= 8;
- sl /= 8;
-
- keymatexportlen = (int)(kl + sl)*2;
- if (keymatexportlen != 60) {
- warning("dtls: expected 60 bits, but keying material is %d\n",
- keymatexportlen);
- return EINVAL;
- }
-
- if (!SSL_export_keying_material(tc->ssl, exportedkeymat,
- keymatexportlen,
- keymatexportlabel,
- strlen(keymatexportlabel),
- NULL, 0, 0)) {
- return ENOENT;
- }
-
- p = exportedkeymat;
-
- memcpy(client_key->key, p, kl); p += kl;
- memcpy(server_key->key, p, kl); p += kl;
- memcpy(client_key->salt, p, sl); p += sl;
- memcpy(server_key->salt, p, sl); p += sl;
-
- client_key->key_len = server_key->key_len = kl;
- client_key->salt_len = server_key->salt_len = sl;
-
- return 0;
-}
-
-
-static void destructor(void *arg)
-{
- struct dtls_flow *flow = arg;
-
- if (flow->ssl) {
- int r = SSL_shutdown(flow->ssl);
- if (r <= 0)
- ERR_clear_error();
-
- SSL_free(flow->ssl);
- }
-
- mem_deref(flow->uh);
- mem_deref(flow->us);
-
- tmr_cancel(&flow->tmr);
-}
-
-
-static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
-{
- struct dtls_flow *flow = arg;
- uint8_t b;
- int r, n;
-
- if (mbuf_get_left(mb) < 1)
- return false;
-
- /* ignore non-DTLS packets */
- b = mb->buf[mb->pos];
- if (b < 20 || b > 63)
- return false;
-
- if (!sa_cmp(src, &flow->peer, SA_ALL))
- return false;
-
- /* feed SSL data to the BIO */
- r = BIO_write(flow->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
- if (r <= 0)
- return true;
-
- n = SSL_read(flow->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
- if (n <= 0) {
- ERR_clear_error();
- }
-
- if (!flow->up && SSL_state(flow->ssl) == SSL_ST_OK) {
-
- struct key client_key, server_key;
- char profile[256];
- int err;
-
- flow->up = true;
-
- err = get_srtp_key_info(flow, profile, sizeof(profile),
- &client_key, &server_key);
- if (err) {
- warning("dtls: SRTP key info: %m\n", err);
- return true;
- }
-
- flow->estabh(0, flow, profile,
- &client_key, &server_key, flow->arg);
- }
-
- return true;
-}
-
-
-int dtls_flow_alloc(struct dtls_flow **flowp, struct tls *tls,
- struct udp_sock *us, dtls_estab_h *estabh, void *arg)
-{
- struct dtls_flow *flow;
- int err = ENOMEM;
-
- if (!flowp || !tls || !us || !estabh)
- return EINVAL;
-
- flow = mem_zalloc(sizeof(*flow), destructor);
- if (!flow)
- return ENOMEM;
-
- flow->tls = tls;
- flow->us = mem_ref(us);
- flow->estabh = estabh;
- flow->arg = arg;
-
- err = udp_register_helper(&flow->uh, us, LAYER_DTLS, NULL,
- recv_handler, flow);
- if (err)
- goto out;
-
- flow->ssl = SSL_new(tls->ctx);
- if (!flow->ssl) {
- ERR_clear_error();
- goto out;
- }
-
- flow->sbio_in = BIO_new(BIO_s_mem());
- if (!flow->sbio_in)
- goto out;
-
- flow->sbio_out = BIO_new(&bio_udp_send);
- if (!flow->sbio_out) {
- BIO_free(flow->sbio_in);
- goto out;
- }
- flow->sbio_out->ptr = flow;
-
- SSL_set_bio(flow->ssl, flow->sbio_in, flow->sbio_out);
-
- tmr_init(&flow->tmr);
-
- err = 0;
-
- out:
- if (err)
- mem_deref(flow);
- else
- *flowp = flow;
-
- return err;
-}
-
-
-int dtls_flow_start(struct dtls_flow *flow, const struct sa *peer, bool active)
-{
- int r, err = 0;
-
- if (!flow || !peer)
- return EINVAL;
-
- flow->peer = *peer;
-
- if (active) {
- r = SSL_connect(flow->ssl);
- if (r < 0) {
- int ssl_err = SSL_get_error(flow->ssl, r);
-
- ERR_clear_error();
-
- if (ssl_err != SSL_ERROR_WANT_READ) {
- warning("dtls: SSL_connect() failed"
- " (err=%d)\n", ssl_err);
- }
- }
-
- check_timer(flow);
- }
- else {
- SSL_set_accept_state(flow->ssl);
-
- SSL_set_verify_depth(flow->ssl, 0);
- SSL_set_verify(flow->ssl,
- SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
- verify_callback);
- }
-
- return err;
-}
-
-
-static const EVP_MD *type2evp(const char *type)
-{
- if (0 == str_casecmp(type, "SHA-1"))
- return EVP_sha1();
- else if (0 == str_casecmp(type, "SHA-256"))
- return EVP_sha256();
- else
- return NULL;
-}
-
-
-int dtls_get_remote_fingerprint(const struct dtls_flow *flow, const char *type,
- struct tls_fingerprint *fp)
-{
- X509 *x;
-
- if (!flow || !fp)
- return EINVAL;
-
- x = SSL_get_peer_certificate(flow->ssl);
- if (!x)
- return EPROTO;
-
- fp->len = sizeof(fp->md);
- if (1 != X509_digest(x, type2evp(type), fp->md, &fp->len))
- return ENOENT;
-
- return 0;
-}