summaryrefslogtreecommitdiff
path: root/modules/dtls_srtp/tls_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/dtls_srtp/tls_udp.c')
-rw-r--r--modules/dtls_srtp/tls_udp.c395
1 files changed, 0 insertions, 395 deletions
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;
-}