Coverage Report

Created: 2025-08-24 06:53

/src/rtpproxy/modules/dtls_gw/rtpp_dtls_conn.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2022 Sippy Software, Inc., http://www.sippysoft.com
3
 * Copyright (C) 2010 Alfred E. Heggestad
4
 * Copyright (C) 2010 Creytiv.com
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 *
27
 */
28
29
#include <sys/socket.h>
30
#include <stddef.h>
31
#include <stdint.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include <openssl/ssl.h>
36
#include <openssl/err.h>
37
#include <openssl/srtp.h>
38
39
#include <srtp2/srtp.h>
40
41
#include "config_pp.h"
42
43
#include "rtpp_module.h"
44
#include "rtpp_debug.h"
45
#include "rtpp_cfg.h"
46
#include "rtpp_log.h"
47
#include "rtpp_log_obj.h"
48
#include "rtpp_netio_async.h"
49
#include "rtpp_codeptr.h"
50
#include "rtpp_refcnt.h"
51
#include "rtpp_str.h"
52
#include "rtpp_stream.h"
53
#include "rtp.h"
54
#include "rtpp_time.h"
55
#include "rtp_packet.h"
56
#include "rtpp_packetops.h"
57
#include "rtpp_proc_async.h"
58
#include "rtpp_threads.h"
59
#include "rtpp_ssrc.h"
60
#include "rtpp_timed.h"
61
#include "rtpp_timed_task.h"
62
#include "rtpp_codeptr.h"
63
#include "advanced/packet_processor.h"
64
#include "advanced/pproc_manager.h"
65
#include "rtpp_refproxy.h"
66
#include "rtpp_weakref.h"
67
68
#include "rtpp_dtls_util.h"
69
#include "rtpp_dtls_conn.h"
70
71
enum rdc_state {
72
    RDC_INIT,
73
    RDC_CONNECTING,
74
    RDC_UP,
75
    RDC_DEAD
76
};
77
78
enum srtp_suite {
79
    SRTP_AES_CM_128_HMAC_SHA1_32,
80
    SRTP_AES_CM_128_HMAC_SHA1_80,
81
    SRTP_F8_128_HMAC_SHA1_32,
82
    SRTP_F8_128_HMAC_SHA1_80,
83
    SRTP_AES_256_CM_HMAC_SHA1_32,
84
    SRTP_AES_256_CM_HMAC_SHA1_80,
85
    SRTP_AES_128_GCM,
86
    SRTP_AES_256_GCM,
87
};
88
89
DEFINE_RAW_METHOD(set_srtp_policy, void, srtp_crypto_policy_t *);
90
91
struct srtp_crypto_suite {
92
    const char *can_name;
93
    int key_size;
94
    int iv_size;
95
    int tag_size;
96
    srtp_sec_serv_t sec_serv;
97
    set_srtp_policy_t set_srtp_policy;
98
};
99
100
const struct srtp_crypto_suite srtp_suites [] = {
101
    [SRTP_AES_CM_128_HMAC_SHA1_32] = {.can_name = "AES_CM_128_HMAC_SHA1_32",
102
      .sec_serv = sec_serv_conf_and_auth, .key_size = (128 / 8),
103
      .iv_size = (112 / 8), .tag_size = (32 / 8),
104
      .set_srtp_policy = srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32},
105
    [SRTP_AES_CM_128_HMAC_SHA1_80] = {.can_name = "AES_CM_128_HMAC_SHA1_80",
106
      .sec_serv = sec_serv_conf_and_auth, .key_size = (128 / 8),
107
      .iv_size = (112 / 8), .tag_size = (80 / 8),
108
      .set_srtp_policy = srtp_crypto_policy_set_rtp_default},
109
    [SRTP_F8_128_HMAC_SHA1_32] = {.can_name = "F8_128_HMAC_SHA1_32",
110
      .sec_serv = sec_serv_conf_and_auth, .key_size = (128 / 8),
111
      .iv_size = (112 / 8), .tag_size = (32 / 8)},
112
    [SRTP_F8_128_HMAC_SHA1_80] = {.can_name = "F8_128_HMAC_SHA1_80",
113
      .sec_serv = sec_serv_conf_and_auth, .key_size = (128 / 8),
114
      .iv_size = (112 / 8), .tag_size = (80 / 8)},
115
    [SRTP_AES_256_CM_HMAC_SHA1_32] = {.can_name = "AES_256_CM_HMAC_SHA1_32",
116
      .sec_serv = sec_serv_conf_and_auth, .key_size = (256 / 8),
117
      .iv_size = (112 / 8), .tag_size = (32 / 8),
118
      .set_srtp_policy = srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32},
119
    [SRTP_AES_256_CM_HMAC_SHA1_80] = {.can_name = "AES_256_CM_HMAC_SHA1_80",
120
      .sec_serv = sec_serv_conf_and_auth, .key_size = (256 / 8),
121
      .iv_size = (112 / 8), .tag_size = (80 / 8),
122
      .set_srtp_policy = srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80},
123
    [SRTP_AES_128_GCM] = {.can_name = "AES_128_GCM",
124
      .sec_serv = sec_serv_conf_and_auth, .key_size = (128 / 8),
125
      .iv_size = (96 / 8), .tag_size = (128 / 8),
126
      .set_srtp_policy = srtp_crypto_policy_set_aes_gcm_128_16_auth},
127
    [SRTP_AES_256_GCM] = {.can_name = "AES_256_GCM",
128
      .sec_serv = sec_serv_conf_and_auth, .key_size = (256 / 8),
129
      .iv_size = (96 / 8), .tag_size = (128 / 8),
130
      .set_srtp_policy = srtp_crypto_policy_set_aes_gcm_256_16_auth}
131
};
132
133
struct rtpp_dtls_conn_priv {
134
    struct rtpp_dtls_conn pub;
135
    uint64_t dtls_strm_id;
136
    struct rtpp_timed *timed_cf;
137
    struct rtpp_weakref *streams_wrt;
138
    pthread_mutex_t state_lock;
139
    enum rdc_state state;
140
    enum rtpp_dtls_mode mode;
141
    SSL *ssl_ctx;
142
    srtp_t srtp_ctx_out;
143
    srtp_t srtp_ctx_in;
144
    BIO_METHOD *biomet;
145
    BIO *sbio_out;
146
    BIO *sbio_in;
147
    char fingerprint[FP_DIGEST_STRBUF_LEN];
148
    uint32_t ssrc;
149
    struct rtpp_timed_task *ttp;
150
    struct rtpp_minfo *mself;
151
};
152
153
static BIO_METHOD *bio_method_udp(void);
154
static int tls_accept(struct rtpp_dtls_conn_priv *);
155
static int tls_connect(struct rtpp_dtls_conn_priv *);
156
static int check_timer(struct rtpp_dtls_conn_priv *);
157
158
enum {
159
    MTU_DEFAULT  = 1400,
160
    MTU_FALLBACK = 548,
161
};
162
163
static void rtpp_dtls_conn_dtls_recv(struct rtpp_dtls_conn *,
164
  const struct rtp_packet *);
165
static struct res_loc rtpp_dtls_conn_rtp_send(struct rtpp_dtls_conn *,
166
  struct pkt_proc_ctx *);
167
static struct res_loc rtpp_dtls_conn_srtp_recv(struct rtpp_dtls_conn *,
168
  struct pkt_proc_ctx *);
169
static enum rtpp_dtls_mode rtpp_dtls_conn_setmode(struct rtpp_dtls_conn *,
170
  const struct rdc_peer_spec *rdfsp);
171
static void rtpp_dtls_conn_godead(struct rtpp_dtls_conn *);
172
173
static int tls_srtp_keyinfo(SSL *, const struct srtp_crypto_suite **,
174
  uint8_t *, size_t, uint8_t *, size_t, struct rtpp_log *);
175
static int tls_peer_fingerprint(SSL *, char *, size_t);
176
177
DEFINE_SMETHODS(rtpp_dtls_conn,
178
    .dtls_recv = &rtpp_dtls_conn_dtls_recv,
179
    .rtp_send = &rtpp_dtls_conn_rtp_send,
180
    .srtp_recv = &rtpp_dtls_conn_srtp_recv,
181
    .setmode = &rtpp_dtls_conn_setmode,
182
    .godead = &rtpp_dtls_conn_godead,
183
);
184
185
static void
186
rtpp_dtls_conn_dtor(struct rtpp_dtls_conn_priv *pvt)
187
28.7k
{
188
189
28.7k
    if (pvt->srtp_ctx_in != NULL)
190
0
        srtp_dealloc(pvt->srtp_ctx_in);
191
28.7k
    if (pvt->srtp_ctx_out != NULL)
192
0
        srtp_dealloc(pvt->srtp_ctx_out);
193
28.7k
    pthread_mutex_destroy(&pvt->state_lock);
194
    /* BIO_free(pvt->sbio_out); <- done by SSL_free() */
195
    /* BIO_free(pvt->sbio_in); <- done by SSL_free() */
196
28.7k
    SSL_free(pvt->ssl_ctx);
197
28.7k
    BIO_meth_free(pvt->biomet);
198
28.7k
}
199
200
struct rtpp_dtls_conn *
201
rtpp_dtls_conn_ctor(const struct rtpp_cfg *cfsp, SSL_CTX *ctx,
202
  struct rtpp_stream *dtls_strmp, struct rtpp_minfo *mself)
203
28.7k
{
204
28.7k
    struct rtpp_dtls_conn_priv *pvt;
205
206
28.7k
    pvt = mod_rzmalloc(sizeof(*pvt), PVT_RCOFFS(pvt));
207
28.7k
    if (pvt == NULL) {
208
0
        goto e0;
209
0
    }
210
28.7k
    pvt->biomet = bio_method_udp();
211
28.7k
    if (pvt->biomet == NULL) {
212
0
        ERR_clear_error();
213
0
        goto e1;
214
0
    }
215
28.7k
    pvt->ssl_ctx = SSL_new(ctx);
216
28.7k
    if (pvt->ssl_ctx == NULL) {
217
0
        ERR_clear_error();
218
0
        goto e2;
219
0
    }
220
28.7k
    pvt->sbio_in = BIO_new(BIO_s_mem());
221
28.7k
    if (pvt->sbio_in == NULL) {
222
0
        ERR_clear_error();
223
0
        goto e3;
224
0
    }
225
28.7k
    pvt->sbio_out = BIO_new(pvt->biomet);
226
28.7k
    if (pvt->sbio_out == NULL) {
227
0
        ERR_clear_error();
228
0
        goto e4;
229
0
    }
230
28.7k
    if (pthread_mutex_init(&pvt->state_lock, NULL) != 0) {
231
0
        goto e5;
232
0
    }
233
28.7k
    BIO_set_data(pvt->sbio_out, pvt);
234
28.7k
    SSL_set_bio(pvt->ssl_ctx, pvt->sbio_in, pvt->sbio_out);
235
28.7k
    SSL_set_read_ahead(pvt->ssl_ctx, 1);
236
28.7k
    pvt->mode = RTPP_DTLS_ACTPASS;
237
28.7k
    pvt->state = RDC_INIT;
238
    /* Cannot grab refcount here, circular reference would ensue */
239
    /* RTPP_OBJ_INCREF(dtls_strmp); */
240
28.7k
    pvt->dtls_strm_id = dtls_strmp->stuid;
241
28.7k
    RTPP_OBJ_BORROW(&pvt->pub, cfsp->rtp_streams_wrt);
242
28.7k
    pvt->streams_wrt = cfsp->rtp_streams_wrt;
243
28.7k
    pvt->timed_cf = cfsp->rtpp_timed_cf;
244
28.7k
    PUBINST_FININIT(&pvt->pub, pvt, rtpp_dtls_conn_dtor);
245
28.7k
    pvt->mself = mself;
246
28.7k
    return (&(pvt->pub));
247
0
e5:
248
0
    BIO_free(pvt->sbio_out);
249
0
e4:
250
0
    BIO_free(pvt->sbio_in);
251
0
e3:
252
0
    SSL_free(pvt->ssl_ctx);
253
0
e2:
254
0
    BIO_meth_free(pvt->biomet);
255
0
e1:
256
0
    RTPP_OBJ_DECREF(&pvt->pub);
257
0
e0:
258
0
    return (NULL);
259
0
}
260
261
static enum rtpp_dtls_mode
262
rtpp_dtls_conn_pickmode(enum rtpp_dtls_mode peer_mode)
263
21.8k
{
264
265
21.8k
    switch (peer_mode) {
266
0
    case RTPP_DTLS_ACTPASS:
267
0
        return (RTPP_DTLS_PASSIVE);
268
13.2k
    case RTPP_DTLS_ACTIVE:
269
13.2k
        return (RTPP_DTLS_PASSIVE);
270
8.54k
    case RTPP_DTLS_PASSIVE:
271
8.54k
        return (RTPP_DTLS_ACTIVE);
272
0
    default:
273
0
        abort();
274
21.8k
    }
275
    /* Not Reached */
276
21.8k
}
277
278
static enum rtpp_dtls_mode
279
rtpp_dtls_conn_setmode(struct rtpp_dtls_conn *self,
280
  const struct rdc_peer_spec *rdfsp)
281
39.9k
{
282
39.9k
    struct rtpp_dtls_conn_priv *pvt;
283
39.9k
    enum rtpp_dtls_mode my_mode;
284
39.9k
    char *ep;
285
286
39.9k
    PUB2PVT(self, pvt);
287
288
39.9k
    pthread_mutex_lock(&pvt->state_lock);
289
290
39.9k
    if (rdfsp == NULL) {
291
18.1k
        goto out;
292
18.1k
    }
293
21.8k
    my_mode = rtpp_dtls_conn_pickmode(rdfsp->peer_mode);
294
21.8k
    if (my_mode != pvt->mode && pvt->state != RDC_INIT) {
295
82
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "%p: cannot change mode "
296
82
          "from %d to %d when in the %d state", self, pvt->mode, my_mode,
297
82
          pvt->state);
298
82
        goto failed;
299
82
    }
300
21.7k
    if (rdfsp->algorithm.len != FP_DIGEST_ALG_LEN ||
301
21.7k
      memcmp(rdfsp->algorithm.s, FP_DIGEST_ALG, FP_DIGEST_ALG_LEN) != 0) {
302
4.69k
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "unsupported fingerprint "
303
9.38k
          "algorithm: \"%.*s\"", FMTSTR(&rdfsp->algorithm));
304
4.69k
        goto failed;
305
4.69k
    }
306
17.0k
    if (rdfsp->fingerprint->len != FP_FINGERPRINT_STR_LEN) {
307
93
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid fingerprint "
308
93
          "length: \"%lu\"", (unsigned long)rdfsp->fingerprint->len);
309
93
        goto failed;
310
93
    }
311
16.9k
    sprintf(pvt->fingerprint, "%.*s %.*s", FMTSTR(&rdfsp->algorithm),
312
16.9k
      FMTSTR(rdfsp->fingerprint));
313
16.9k
    if (rdfsp->ssrc != NULL) {
314
13.9k
        uint32_t ssrc = strtoul(rdfsp->ssrc->s, &ep, 10);
315
13.9k
        if (ep == rdfsp->ssrc->s || ep[0] != '\0') {
316
100
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid ssrc: %.*s",
317
200
              FMTSTR(rdfsp->ssrc));
318
100
            goto failed;
319
100
        }
320
13.8k
        pvt->ssrc = ssrc;
321
13.8k
    }
322
16.8k
    if (my_mode == RTPP_DTLS_ACTIVE && pvt->state == RDC_INIT) {
323
7.52k
        pvt->state = RDC_CONNECTING;
324
7.52k
        if (tls_connect(pvt) != 0) {
325
188
            goto failed;
326
188
        }
327
7.52k
    }
328
16.6k
    pvt->mode = my_mode;
329
34.8k
out:
330
34.8k
    pthread_mutex_unlock(&pvt->state_lock);
331
34.8k
    return (pvt->mode);
332
5.15k
failed:
333
5.15k
    pthread_mutex_unlock(&pvt->state_lock);
334
5.15k
    return (RTPP_DTLS_MODERR);
335
16.6k
}
336
337
static srtp_t
338
setup_srtp_stream(const struct srtp_crypto_suite *suite, uint8_t *key,
339
  uint32_t ssrc, struct rtpp_log *log)
340
0
{
341
0
    srtp_policy_t policy;
342
0
    srtp_t srtp_ctx;
343
0
    int err;
344
345
0
    memset(&policy, '\0', sizeof(policy));
346
0
    suite->set_srtp_policy(&policy.rtp);
347
0
    suite->set_srtp_policy(&policy.rtcp);
348
0
    policy.key = key;
349
0
    policy.window_size = 128;
350
0
    policy.rtp.auth_tag_len = suite->tag_size;
351
0
    policy.rtp.sec_serv = policy.rtcp.sec_serv = suite->sec_serv;
352
353
0
    if (ssrc == SSRC_BAD) {
354
0
        policy.ssrc.type  = ssrc_any_inbound;
355
0
    } else {
356
0
        policy.ssrc.type  = ssrc_specific;
357
0
        policy.ssrc.value = ssrc;
358
0
    }
359
360
0
    err = srtp_create(&srtp_ctx, &policy);
361
0
    if (err != srtp_err_status_ok || srtp_ctx == NULL) {
362
0
        RTPP_LOG(log, RTPP_LOG_ERR, "srtp_create() failed");
363
0
        return (NULL);
364
0
    }
365
0
    return (srtp_ctx);
366
0
}
367
368
static void
369
rtpp_dtls_conn_dtls_recv(struct rtpp_dtls_conn *self,
370
  const struct rtp_packet *pktp)
371
31.7k
{
372
31.7k
    struct rtpp_dtls_conn_priv *pvt;
373
31.7k
    int r, err;
374
31.7k
    uint8_t cli_key[32+14], srv_key[32+14];
375
31.7k
    const struct srtp_crypto_suite *suite;
376
31.7k
    char srv_fingerprint[FP_DIGEST_STRBUF_LEN];
377
378
31.7k
    PUB2PVT(self, pvt);
379
380
31.7k
    pthread_mutex_lock(&pvt->state_lock);
381
382
31.7k
    switch (pvt->state) {
383
5.54k
    case RDC_INIT:
384
5.54k
        pvt->state = RDC_CONNECTING;
385
5.54k
        break;
386
25.6k
    case RDC_CONNECTING:
387
25.6k
    case RDC_UP:
388
25.6k
        break;
389
635
    case RDC_DEAD:
390
635
        goto out;
391
31.7k
    }
392
393
31.1k
    r = BIO_write(pvt->sbio_in, pktp->data.buf, pktp->size);
394
31.1k
    if (r <= 0) {
395
0
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "receive bio write error: %i", r);
396
0
        ERR_clear_error();
397
0
        goto out;
398
0
    }
399
31.1k
    if (SSL_get_state(pvt->ssl_ctx) != TLS_ST_OK) {
400
31.1k
        if (pvt->state == RDC_UP) {
401
0
            goto godead;
402
0
        }
403
31.1k
        if (pvt->mode == RTPP_DTLS_ACTIVE)
404
10.3k
            err = tls_connect(pvt);
405
20.7k
        else
406
20.7k
            err = tls_accept(pvt);
407
31.1k
        if (err) {
408
4.86k
            goto godead;
409
4.86k
        }
410
411
#if 0
412
        RTPP_LOG(pvt->mself->log, RTPP_LOG_DBUG, "%s: state=0x%04x",
413
          "server", SSL_get_state(pvt->ssl_ctx));
414
#endif
415
416
        /* TLS connection is established */
417
26.2k
        if (SSL_get_state(pvt->ssl_ctx) != TLS_ST_OK)
418
26.2k
            goto out;
419
420
0
        err = tls_srtp_keyinfo(pvt->ssl_ctx, &suite, cli_key, sizeof(cli_key),
421
0
          srv_key, sizeof(srv_key), pvt->mself->log);
422
0
        if (err != 0) {
423
0
            goto godead;
424
0
        }
425
426
0
        err = tls_peer_fingerprint(pvt->ssl_ctx, srv_fingerprint,
427
0
          sizeof(srv_fingerprint));
428
0
        if (err != 0) {
429
0
            goto godead;
430
0
        }
431
432
0
        if (pvt->fingerprint[0] != '\0' &&
433
0
          strcmp(pvt->fingerprint, srv_fingerprint) != 0) {
434
0
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "fingerprint verification failed");
435
0
            goto godead;
436
0
        }
437
438
0
        pvt->srtp_ctx_out = setup_srtp_stream(suite,
439
0
          pvt->mode == RTPP_DTLS_ACTIVE ? cli_key : srv_key, SSRC_BAD,
440
0
          pvt->mself->log);
441
0
        if (pvt->srtp_ctx_out == NULL) {
442
0
            goto godead;
443
0
        }
444
0
        pvt->srtp_ctx_in = setup_srtp_stream(suite,
445
0
          pvt->mode == RTPP_DTLS_ACTIVE ? srv_key : cli_key, pvt->ssrc,
446
0
          pvt->mself->log);
447
0
        if (pvt->srtp_ctx_in == NULL) {
448
0
            goto godead;
449
0
        }
450
451
#if 0
452
        RTPP_LOG(pvt->mself->log, RTPP_LOG_DBUG,
453
          "DTLS connection is established with %s key: %s", suite->can_name,
454
            pvt->fingerprint);
455
#endif
456
0
        pvt->state = RDC_UP;
457
0
    }
458
0
    goto out;
459
4.86k
godead:
460
4.86k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_DBUG, "DTLS connection is dead: %p",
461
4.86k
      pvt);
462
4.86k
    pvt->state = RDC_DEAD;
463
31.7k
out:
464
31.7k
    pthread_mutex_unlock(&pvt->state_lock);
465
31.7k
}
466
467
#if SRTP_PROTECT_NARGS == 4
468
#define SRTP_PROTECT(a, b, c) srtp_protect(a, b, c, 0)
469
#define SRTCP_PROTECT(a, b, c) srtp_protect_rtcp(a, b, c, 0)
470
#else
471
#define SRTP_PROTECT(a, b, c) srtp_protect(a, b, c)
472
#define SRTCP_PROTECT(a, b, c) srtp_protect_rtcp(a, b, c)
473
#endif
474
475
static struct res_loc
476
rtpp_dtls_conn_rtp_send(struct rtpp_dtls_conn *self, struct pkt_proc_ctx *pktxp)
477
167k
{
478
167k
    struct res_loc status;
479
167k
#if defined(SRTP_PROTECT_LASTARG)
480
167k
    SRTP_PROTECT_LASTARG len;
481
#else
482
    size_t len;
483
#endif
484
167k
    struct rtpp_dtls_conn_priv *pvt;
485
486
167k
    PUB2PVT(self, pvt);
487
488
167k
    if (pvt->state != RDC_UP) {
489
167k
        return (RES_HERE(-1));
490
167k
    }
491
492
0
    len = pktxp->pktp->size;
493
0
    if (rtpp_is_rtcp_tst(pktxp)) {
494
0
        status = RES_HERE(SRTCP_PROTECT(pvt->srtp_ctx_out, pktxp->pktp->data.buf, &len));
495
0
    } else {
496
0
        status = RES_HERE(SRTP_PROTECT(pvt->srtp_ctx_out, pktxp->pktp->data.buf, &len));
497
0
    }
498
0
    if (status.v) {
499
0
        status.v = -1;
500
0
        return (status);
501
0
    }
502
0
    pktxp->pktp->size = len;
503
0
    CALL_SMETHOD(pktxp->strmp_in->pproc_manager, handleat, pktxp,
504
0
      PPROC_ORD_ENCRYPT + 1);
505
0
    return (RES_HERE(0));
506
0
}
507
508
static struct res_loc
509
rtpp_dtls_conn_srtp_recv(struct rtpp_dtls_conn *self, struct pkt_proc_ctx *pktxp)
510
93.7k
{
511
93.7k
    struct res_loc status;
512
93.7k
#if defined(SRTP_PROTECT_LASTARG)
513
93.7k
    SRTP_PROTECT_LASTARG len;
514
#else
515
    size_t len;
516
#endif
517
93.7k
    struct rtpp_dtls_conn_priv *pvt;
518
519
93.7k
    PUB2PVT(self, pvt);
520
521
93.7k
    if (pvt->state != RDC_UP) {
522
93.7k
        return (RES_HERE(-1));
523
93.7k
    }
524
525
0
    len = pktxp->pktp->size;
526
0
    if (rtpp_is_rtcp_tst(pktxp)) {
527
0
        status = RES_HERE(srtp_unprotect_rtcp(pvt->srtp_ctx_in, pktxp->pktp->data.buf, &len));
528
0
    } else {
529
0
        status = RES_HERE(srtp_unprotect(pvt->srtp_ctx_in, pktxp->pktp->data.buf, &len));
530
0
    }
531
0
    if (status.v) {
532
0
        status.v = -1;
533
0
        return (status);
534
0
    }
535
0
    pktxp->pktp->size = len;
536
0
    CALL_SMETHOD(pktxp->strmp_in->pproc_manager, handleat, pktxp,
537
0
      PPROC_ORD_DECRYPT + 1);
538
0
    return (RES_HERE(0));
539
0
}
540
541
static int
542
bio_write(BIO *b, const char *buf, int len)
543
11.9k
{
544
11.9k
    struct rtpp_dtls_conn_priv *pvt = BIO_get_data(b);
545
11.9k
    struct rtp_packet *packet;
546
11.9k
    struct rtpp_stream *dtls_strmp;
547
548
11.9k
    dtls_strmp = CALL_SMETHOD(pvt->streams_wrt, get_by_idx, pvt->dtls_strm_id);
549
11.9k
    if (dtls_strmp == NULL)
550
0
        goto e0;
551
11.9k
    if (len > MAX_RPKT_LEN || !CALL_SMETHOD(dtls_strmp, issendable))
552
1.69k
        goto e1;
553
10.3k
    packet = rtp_packet_alloc();
554
10.3k
    if (packet == NULL)
555
0
        goto e1;
556
10.3k
    memcpy(packet->data.buf, buf, len);
557
10.3k
    packet->size = len;
558
10.3k
    CALL_SMETHOD(dtls_strmp, send_pkt, NULL, packet);
559
10.3k
    RTPP_OBJ_DECREF(dtls_strmp);
560
10.3k
    return (len);
561
1.69k
e1:
562
1.69k
    RTPP_OBJ_DECREF(dtls_strmp);
563
1.69k
e0:
564
1.69k
    return (-1);
565
1.69k
}
566
567
static long
568
bio_ctrl(BIO *b, int cmd, long num, void *ptr)
569
74.4k
{
570
74.4k
    (void)b;
571
74.4k
    (void)num;
572
74.4k
    (void)ptr;
573
574
74.4k
    switch (cmd) {
575
576
10.3k
    case BIO_CTRL_FLUSH:
577
        /* The OpenSSL library needs this */
578
10.3k
        return 1;
579
580
0
#if defined (BIO_CTRL_DGRAM_QUERY_MTU)
581
7.52k
    case BIO_CTRL_DGRAM_QUERY_MTU:
582
7.52k
        return MTU_DEFAULT;
583
0
#endif
584
585
0
#if defined (BIO_CTRL_DGRAM_GET_FALLBACK_MTU)
586
0
    case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
587
0
        return MTU_FALLBACK;
588
74.4k
#endif
589
74.4k
    }
590
591
56.6k
    return 0;
592
74.4k
}
593
594
static int
595
bio_create(BIO *b)
596
28.7k
{
597
28.7k
    BIO_set_init(b, 1);
598
28.7k
    BIO_set_data(b, NULL);
599
28.7k
    BIO_set_flags(b, 0);
600
601
28.7k
    return (1);
602
28.7k
}
603
604
605
static int
606
bio_destroy(BIO *b)
607
28.7k
{
608
609
28.7k
    BIO_set_init(b, 0);
610
28.7k
    BIO_set_data(b, NULL);
611
28.7k
    BIO_set_flags(b, 0);
612
613
28.7k
    return (1);
614
28.7k
}
615
616
static BIO_METHOD *
617
bio_method_udp(void)
618
28.7k
{
619
28.7k
    BIO_METHOD *method;
620
621
28.7k
    method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "udp_send");
622
28.7k
    if (!method) {
623
0
        return NULL;
624
0
    }
625
626
28.7k
    BIO_meth_set_write(method, bio_write);
627
28.7k
    BIO_meth_set_ctrl(method, bio_ctrl);
628
28.7k
    BIO_meth_set_create(method, bio_create);
629
28.7k
    BIO_meth_set_destroy(method, bio_destroy);
630
631
28.7k
    return (method);
632
28.7k
}
633
634
static int
635
tls_print_error(const char *str, size_t len, void *arg)
636
5.05k
{
637
5.05k
    struct rtpp_log *log = arg;
638
5.05k
    RTPP_LOG(log, RTPP_LOG_ERR, "%.*s", (int)len, str);
639
640
5.05k
    return 1;
641
5.05k
}
642
643
644
static void
645
tls_flush_error(struct rtpp_log *log)
646
38.6k
{
647
648
38.6k
    ERR_print_errors_cb(tls_print_error, log);
649
38.6k
}
650
651
static int
652
tls_accept(struct rtpp_dtls_conn_priv *pvt)
653
20.7k
{
654
20.7k
    int r;
655
656
20.7k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
657
658
20.7k
    ERR_clear_error();
659
660
20.7k
    r = SSL_accept(pvt->ssl_ctx);
661
20.7k
    if (r <= 0) {
662
20.7k
        const int ssl_err = SSL_get_error(pvt->ssl_ctx, r);
663
664
20.7k
        tls_flush_error(pvt->mself->log);
665
666
20.7k
        switch (ssl_err) {
667
17.4k
        case SSL_ERROR_WANT_READ:
668
17.4k
            break;
669
670
3.35k
        default:
671
3.35k
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "accept error: %i",
672
3.35k
              ssl_err);
673
3.35k
            return (-1);
674
20.7k
        }
675
20.7k
    }
676
677
17.4k
    if (check_timer(pvt) != 0)
678
0
        return (-1);
679
680
17.4k
    return (0);
681
17.4k
}
682
683
static enum rtpp_timed_cb_rvals
684
rtpp_dtls_conn_timeout(double dtime, void *arg)
685
0
{
686
0
    struct rtpp_dtls_conn_priv *pvt = arg;
687
688
0
    pthread_mutex_lock(&pvt->state_lock);
689
690
0
    if (pvt->ttp == NULL) {
691
        /* Lost race with check_timer() */
692
0
        goto done;
693
0
    }
694
695
0
    RTPP_OBJ_DECREF(pvt->ttp);
696
0
    pvt->ttp = NULL;
697
0
    if (pvt->state != RDC_CONNECTING)
698
0
        goto done;
699
0
    if (DTLSv1_handle_timeout(pvt->ssl_ctx) >= 0) {
700
0
        if (check_timer(pvt) != 0)
701
0
            pvt->state = RDC_DEAD;
702
0
    } else {
703
0
        ERR_clear_error();
704
0
        pvt->state = RDC_DEAD;
705
0
    }
706
0
done:
707
0
    pthread_mutex_unlock(&pvt->state_lock);
708
0
    return (CB_LAST);
709
0
}
710
711
static int
712
check_timer(struct rtpp_dtls_conn_priv *pvt)
713
33.6k
{
714
33.6k
    int err;
715
33.6k
    struct timeval tv = {0, 0};
716
717
33.6k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
718
719
33.6k
    err = DTLSv1_get_timeout(pvt->ssl_ctx, &tv);
720
33.6k
    if (err == 1 && pvt->ttp != NULL)
721
8.86k
        return (0);
722
24.7k
    if (err == 1) {
723
7.33k
        double to = timeval2dtime(&tv);
724
7.33k
        pvt->ttp = CALL_SMETHOD(pvt->timed_cf, schedule_rc, to,
725
7.33k
          pvt->pub.rcnt, rtpp_dtls_conn_timeout, NULL, pvt);
726
7.33k
        if (pvt->ttp == NULL)
727
0
            return (-1);
728
17.4k
    } else if (pvt->ttp != NULL) {
729
0
        CALL_METHOD(pvt->ttp, cancel);
730
0
        RTPP_OBJ_DECREF(pvt->ttp);
731
0
        pvt->ttp = NULL;
732
0
    }
733
734
24.7k
    return (0);
735
24.7k
}
736
737
static int
738
tls_connect(struct rtpp_dtls_conn_priv *pvt)
739
17.9k
{
740
17.9k
    int r;
741
742
17.9k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
743
744
17.9k
    ERR_clear_error();
745
746
17.9k
    r = SSL_connect(pvt->ssl_ctx);
747
17.9k
    if (r <= 0) {
748
17.9k
        const int ssl_err = SSL_get_error(pvt->ssl_ctx, r);
749
750
17.9k
        tls_flush_error(pvt->mself->log);
751
752
17.9k
        switch (ssl_err) {
753
16.2k
        case SSL_ERROR_WANT_READ:
754
16.2k
            break;
755
756
1.70k
        default:
757
1.70k
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "connect error: %i",
758
1.70k
              ssl_err);
759
1.70k
            return (-1);
760
17.9k
        }
761
17.9k
    }
762
763
16.2k
    check_timer(pvt);
764
765
16.2k
    return (0);
766
17.9k
}
767
768
static void
769
mem_secclean(void *data, size_t size)
770
0
{
771
0
    memset(data, 0, size);
772
    /* Insert an asm statement that may potentially depend
773
     * on the memory contents that were affected by memset.
774
     * This prevents optimizing away the memset. */
775
0
    __asm__ __volatile__("" : : "r" (data), "r" (size) : "memory");
776
0
}
777
778
static int
779
tls_srtp_keyinfo(SSL *ssl_ctx, const struct srtp_crypto_suite **suite,
780
  uint8_t *cli_key, size_t cli_key_size, uint8_t *srv_key,
781
  size_t srv_key_size, struct rtpp_log *log)
782
0
{
783
0
    static const char *label = "EXTRACTOR-dtls_srtp";
784
0
    size_t size;
785
0
    SRTP_PROTECTION_PROFILE *sel;
786
0
    uint8_t keymat[256], *p;
787
788
0
    sel = SSL_get_selected_srtp_profile(ssl_ctx);
789
0
    if (!sel) {
790
0
        ERR_clear_error();
791
0
        RTPP_LOG(log, RTPP_LOG_ERR,
792
0
          "SSL_get_selected_srtp_profile() failed");
793
0
        return (-1);
794
0
    }
795
796
0
    switch (sel->id) {
797
0
    case SRTP_AES128_CM_SHA1_80:
798
0
        *suite = &srtp_suites[SRTP_AES_CM_128_HMAC_SHA1_80];
799
0
        break;
800
801
0
    case SRTP_AES128_CM_SHA1_32:
802
0
        *suite = &srtp_suites[SRTP_AES_CM_128_HMAC_SHA1_32];
803
0
        break;
804
805
0
    case SRTP_AES128_F8_SHA1_80:
806
0
        *suite = &srtp_suites[SRTP_F8_128_HMAC_SHA1_80];
807
0
        break;
808
809
0
    case SRTP_AES128_F8_SHA1_32:
810
0
        *suite = &srtp_suites[SRTP_F8_128_HMAC_SHA1_32];
811
0
        break;
812
813
0
#ifdef SRTP_AEAD_AES_128_GCM
814
0
    case SRTP_AEAD_AES_128_GCM:
815
0
        *suite = &srtp_suites[SRTP_AES_128_GCM];
816
0
        break;
817
0
#endif
818
819
0
#ifdef SRTP_AEAD_AES_256_GCM
820
0
    case SRTP_AEAD_AES_256_GCM:
821
0
        *suite = &srtp_suites[SRTP_AES_256_GCM];
822
0
        break;
823
0
#endif
824
825
0
    default:
826
0
        abort();
827
0
    }
828
829
0
    size = (*suite)->key_size + (*suite)->iv_size;
830
831
0
    if (cli_key_size < size || srv_key_size < size)
832
0
        abort();
833
834
0
    if (sizeof(keymat) < (2 * size))
835
0
        abort();
836
837
0
    if (SSL_export_keying_material(ssl_ctx, keymat, 2 * size, label,
838
0
      strlen(label), NULL, 0, 0) != 1) {
839
0
        ERR_clear_error();
840
0
        RTPP_LOG(log, RTPP_LOG_ERR,
841
0
          "SSL_export_keying_material() failed");
842
0
        return (-1);
843
0
    }
844
845
0
    p = keymat;
846
847
0
    memcpy(cli_key, p, (*suite)->key_size);
848
0
    p += (*suite)->key_size;
849
0
    memcpy(srv_key, p, (*suite)->key_size);
850
0
    p += (*suite)->key_size;
851
0
    memcpy(cli_key + (*suite)->key_size, p, (*suite)->iv_size);
852
0
    p += (*suite)->iv_size;
853
0
    memcpy(srv_key + (*suite)->key_size, p, (*suite)->iv_size);
854
855
0
    mem_secclean(keymat, sizeof(keymat));
856
857
0
    return (0);
858
0
}
859
860
static int
861
tls_peer_fingerprint(SSL *ssl_ctx, char *buf, size_t size)
862
0
{
863
0
    X509 *cert;
864
0
    int err;
865
866
0
    cert = SSL_get_peer_certificate(ssl_ctx);
867
0
    if (cert == NULL)
868
0
        return (-1);
869
870
0
    err = rtpp_dtls_fp_gen(cert, buf, size);
871
872
0
    X509_free(cert);
873
874
0
    return (err);
875
0
}
876
877
static void
878
rtpp_dtls_conn_godead(struct rtpp_dtls_conn *self)
879
28.7k
{
880
28.7k
    struct rtpp_dtls_conn_priv *pvt;
881
882
28.7k
    PUB2PVT(self, pvt);
883
884
28.7k
    pthread_mutex_lock(&pvt->state_lock);
885
28.7k
    pvt->state = RDC_DEAD;
886
28.7k
    if (pvt->ttp != NULL) {
887
7.33k
        CALL_METHOD(pvt->ttp, cancel);
888
7.33k
        RTPP_OBJ_DECREF(pvt->ttp);
889
7.33k
        pvt->ttp = NULL;
890
7.33k
    }
891
28.7k
    pthread_mutex_unlock(&pvt->state_lock);
892
28.7k
}