Coverage Report

Created: 2026-03-14 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rtpproxy/modules/dtls_gw/rtpp_dtls_conn.c
Line
Count
Source
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
29.5k
{
188
189
29.5k
    if (pvt->srtp_ctx_in != NULL)
190
0
        srtp_dealloc(pvt->srtp_ctx_in);
191
29.5k
    if (pvt->srtp_ctx_out != NULL)
192
0
        srtp_dealloc(pvt->srtp_ctx_out);
193
29.5k
    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
29.5k
    SSL_free(pvt->ssl_ctx);
197
29.5k
    BIO_meth_free(pvt->biomet);
198
29.5k
}
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
29.5k
{
204
29.5k
    struct rtpp_dtls_conn_priv *pvt;
205
206
29.5k
    pvt = mod_rzmalloc(sizeof(*pvt), PVT_RCOFFS(pvt));
207
29.5k
    if (pvt == NULL) {
208
0
        goto e0;
209
0
    }
210
29.5k
    pvt->biomet = bio_method_udp();
211
29.5k
    if (pvt->biomet == NULL) {
212
0
        ERR_clear_error();
213
0
        goto e1;
214
0
    }
215
29.5k
    pvt->ssl_ctx = SSL_new(ctx);
216
29.5k
    if (pvt->ssl_ctx == NULL) {
217
0
        ERR_clear_error();
218
0
        goto e2;
219
0
    }
220
29.5k
    pvt->sbio_in = BIO_new(BIO_s_mem());
221
29.5k
    if (pvt->sbio_in == NULL) {
222
0
        ERR_clear_error();
223
0
        goto e3;
224
0
    }
225
29.5k
    pvt->sbio_out = BIO_new(pvt->biomet);
226
29.5k
    if (pvt->sbio_out == NULL) {
227
0
        ERR_clear_error();
228
0
        goto e4;
229
0
    }
230
29.5k
    if (pthread_mutex_init(&pvt->state_lock, NULL) != 0) {
231
0
        goto e5;
232
0
    }
233
29.5k
    BIO_set_data(pvt->sbio_out, pvt);
234
29.5k
    SSL_set_bio(pvt->ssl_ctx, pvt->sbio_in, pvt->sbio_out);
235
29.5k
    SSL_set_read_ahead(pvt->ssl_ctx, 1);
236
29.5k
    pvt->mode = RTPP_DTLS_ACTPASS;
237
29.5k
    pvt->state = RDC_INIT;
238
    /* Cannot grab refcount here, circular reference would ensue */
239
    /* RTPP_OBJ_INCREF(dtls_strmp); */
240
29.5k
    pvt->dtls_strm_id = dtls_strmp->stuid;
241
29.5k
    RTPP_OBJ_BORROW_s(&pvt->pub, cfsp->rtp_streams_wrt);
242
29.5k
    pvt->streams_wrt = cfsp->rtp_streams_wrt;
243
29.5k
    pvt->timed_cf = cfsp->rtpp_timed_cf;
244
29.5k
    PUBINST_FININIT(&pvt->pub, pvt, rtpp_dtls_conn_dtor);
245
29.5k
    pvt->mself = mself;
246
29.5k
    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
22.6k
{
264
265
22.6k
    switch (peer_mode) {
266
0
    case RTPP_DTLS_ACTPASS:
267
0
        return (RTPP_DTLS_PASSIVE);
268
13.6k
    case RTPP_DTLS_ACTIVE:
269
13.6k
        return (RTPP_DTLS_PASSIVE);
270
8.94k
    case RTPP_DTLS_PASSIVE:
271
8.94k
        return (RTPP_DTLS_ACTIVE);
272
0
    default:
273
0
        abort();
274
22.6k
    }
275
    /* Not Reached */
276
22.6k
}
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
41.3k
{
282
41.3k
    struct rtpp_dtls_conn_priv *pvt;
283
41.3k
    enum rtpp_dtls_mode my_mode;
284
41.3k
    char *ep;
285
286
41.3k
    PUB2PVT(self, pvt);
287
288
41.3k
    pthread_mutex_lock(&pvt->state_lock);
289
290
41.3k
    if (rdfsp == NULL) {
291
18.7k
        goto out;
292
18.7k
    }
293
22.6k
    my_mode = rtpp_dtls_conn_pickmode(rdfsp->peer_mode);
294
22.6k
    if (my_mode != pvt->mode && pvt->state != RDC_INIT) {
295
68
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "%p: cannot change mode "
296
68
          "from %d to %d when in the %d state", self, pvt->mode, my_mode,
297
68
          pvt->state);
298
68
        goto failed;
299
68
    }
300
22.5k
    if (rdfsp->algorithm.len != FP_DIGEST_ALG_LEN ||
301
18.3k
      memcmp(rdfsp->algorithm.s, FP_DIGEST_ALG, FP_DIGEST_ALG_LEN) != 0) {
302
4.86k
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "unsupported fingerprint "
303
9.73k
          "algorithm: \"%.*s\"", FMTSTR(&rdfsp->algorithm));
304
4.86k
        goto failed;
305
4.86k
    }
306
17.6k
    if (rdfsp->fingerprint->len != FP_FINGERPRINT_STR_LEN) {
307
106
        RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid fingerprint "
308
106
          "length: \"%lu\"", (unsigned long)rdfsp->fingerprint->len);
309
106
        goto failed;
310
106
    }
311
17.5k
    sprintf(pvt->fingerprint, "%.*s %.*s", FMTSTR(&rdfsp->algorithm),
312
17.5k
      FMTSTR(rdfsp->fingerprint));
313
17.5k
    if (rdfsp->ssrc != NULL) {
314
14.5k
        uint32_t ssrc = strtoul(rdfsp->ssrc->s, &ep, 10);
315
14.5k
        if (ep == rdfsp->ssrc->s || ep[0] != '\0') {
316
108
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "invalid ssrc: %.*s",
317
216
              FMTSTR(rdfsp->ssrc));
318
108
            goto failed;
319
108
        }
320
14.4k
        pvt->ssrc = ssrc;
321
14.4k
    }
322
17.4k
    if (my_mode == RTPP_DTLS_ACTIVE && pvt->state == RDC_INIT) {
323
7.68k
        pvt->state = RDC_CONNECTING;
324
7.68k
        if (tls_connect(pvt) != 0) {
325
185
            goto failed;
326
185
        }
327
7.68k
    }
328
17.2k
    pvt->mode = my_mode;
329
36.0k
out:
330
36.0k
    pthread_mutex_unlock(&pvt->state_lock);
331
36.0k
    return (pvt->mode);
332
5.33k
failed:
333
5.33k
    pthread_mutex_unlock(&pvt->state_lock);
334
5.33k
    return (RTPP_DTLS_MODERR);
335
17.2k
}
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
42.1k
{
372
42.1k
    struct rtpp_dtls_conn_priv *pvt;
373
42.1k
    int r, err;
374
42.1k
    uint8_t cli_key[32+14], srv_key[32+14];
375
42.1k
    const struct srtp_crypto_suite *suite;
376
42.1k
    char srv_fingerprint[FP_DIGEST_STRBUF_LEN];
377
378
42.1k
    PUB2PVT(self, pvt);
379
380
42.1k
    pthread_mutex_lock(&pvt->state_lock);
381
382
42.1k
    switch (pvt->state) {
383
6.52k
    case RDC_INIT:
384
6.52k
        pvt->state = RDC_CONNECTING;
385
6.52k
        break;
386
32.0k
    case RDC_CONNECTING:
387
32.0k
    case RDC_UP:
388
32.0k
        break;
389
3.60k
    case RDC_DEAD:
390
3.60k
        goto out;
391
42.1k
    }
392
393
38.5k
    r = BIO_write(pvt->sbio_in, pktp->data.buf, pktp->size);
394
38.5k
    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
38.5k
    if (SSL_get_state(pvt->ssl_ctx) != TLS_ST_OK) {
400
38.5k
        if (pvt->state == RDC_UP) {
401
0
            goto godead;
402
0
        }
403
38.5k
        if (pvt->mode == RTPP_DTLS_ACTIVE)
404
13.7k
            err = tls_connect(pvt);
405
24.7k
        else
406
24.7k
            err = tls_accept(pvt);
407
38.5k
        if (err) {
408
6.43k
            goto godead;
409
6.43k
        }
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
32.0k
        if (SSL_get_state(pvt->ssl_ctx) != TLS_ST_OK)
418
32.0k
            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
6.43k
godead:
460
6.43k
    RTPP_LOG(pvt->mself->log, RTPP_LOG_DBUG, "DTLS connection is dead: %p",
461
6.43k
      pvt);
462
6.43k
    pvt->state = RDC_DEAD;
463
42.1k
out:
464
42.1k
    pthread_mutex_unlock(&pvt->state_lock);
465
42.1k
}
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
191k
{
478
191k
    struct res_loc status;
479
191k
#if defined(SRTP_PROTECT_LASTARG)
480
191k
    SRTP_PROTECT_LASTARG len;
481
#else
482
    size_t len;
483
#endif
484
191k
    struct rtpp_dtls_conn_priv *pvt;
485
486
191k
    PUB2PVT(self, pvt);
487
488
191k
    if (pvt->state != RDC_UP) {
489
191k
        return (RES_HERE(-1));
490
191k
    }
491
492
0
    if (pktxp->flags & PPROC_FLAG_COW) {
493
0
        struct rtp_packet *p = rtp_packet_alloc();
494
0
        if (p == NULL)
495
0
            return (RES_HERE(-1));
496
0
        rtp_packet_dup(p, pktxp->pktp, 0);
497
0
        RTPP_OBJ_DECREF(pktxp->pktp);
498
0
        pktxp->pktp = p;
499
0
        pktxp->flags ^= PPROC_FLAG_COW;
500
0
    }
501
502
0
    len = pktxp->pktp->size;
503
0
    if (rtpp_is_rtcp_tst(pktxp)) {
504
0
        status = RES_HERE(SRTCP_PROTECT(pvt->srtp_ctx_out, pktxp->pktp->data.buf, &len));
505
0
    } else {
506
0
        status = RES_HERE(SRTP_PROTECT(pvt->srtp_ctx_out, pktxp->pktp->data.buf, &len));
507
0
    }
508
0
    if (status.v) {
509
0
        status.v = -1;
510
0
        return (status);
511
0
    }
512
0
    pktxp->pktp->size = len;
513
0
    CALL_SMETHOD(pktxp->strmp_in->pproc_manager, handleat, pktxp,
514
0
      PPROC_ORD_ENCRYPT + 1);
515
0
    return (RES_HERE(0));
516
0
}
517
518
static struct res_loc
519
rtpp_dtls_conn_srtp_recv(struct rtpp_dtls_conn *self, struct pkt_proc_ctx *pktxp)
520
101k
{
521
101k
    struct res_loc status;
522
101k
#if defined(SRTP_PROTECT_LASTARG)
523
101k
    SRTP_PROTECT_LASTARG len;
524
#else
525
    size_t len;
526
#endif
527
101k
    struct rtpp_dtls_conn_priv *pvt;
528
529
101k
    PUB2PVT(self, pvt);
530
531
101k
    if (pvt->state != RDC_UP) {
532
101k
        return (RES_HERE(-1));
533
101k
    }
534
535
0
    len = pktxp->pktp->size;
536
0
    if (rtpp_is_rtcp_tst(pktxp)) {
537
0
        status = RES_HERE(srtp_unprotect_rtcp(pvt->srtp_ctx_in, pktxp->pktp->data.buf, &len));
538
0
    } else {
539
0
        status = RES_HERE(srtp_unprotect(pvt->srtp_ctx_in, pktxp->pktp->data.buf, &len));
540
0
    }
541
0
    if (status.v) {
542
0
        status.v = -1;
543
0
        return (status);
544
0
    }
545
0
    pktxp->pktp->size = len;
546
0
    CALL_SMETHOD(pktxp->strmp_in->pproc_manager, handleat, pktxp,
547
0
      PPROC_ORD_DECRYPT + 1);
548
0
    return (RES_HERE(0));
549
0
}
550
551
static int
552
bio_write(BIO *b, const char *buf, int len)
553
14.2k
{
554
14.2k
    struct rtpp_dtls_conn_priv *pvt = BIO_get_data(b);
555
14.2k
    struct rtp_packet *packet;
556
14.2k
    struct rtpp_stream *dtls_strmp;
557
558
14.2k
    dtls_strmp = CALL_SMETHOD(pvt->streams_wrt, get_by_idx, pvt->dtls_strm_id);
559
14.2k
    if (dtls_strmp == NULL)
560
0
        goto e0;
561
14.2k
    if (len > MAX_RPKT_LEN || !CALL_SMETHOD(dtls_strmp, issendable))
562
2.29k
        goto e1;
563
11.9k
    packet = rtp_packet_alloc();
564
11.9k
    if (packet == NULL)
565
0
        goto e1;
566
11.9k
    memcpy(packet->data.buf, buf, len);
567
11.9k
    packet->size = len;
568
11.9k
    CALL_SMETHOD(dtls_strmp, send_pkt, NULL, packet);
569
11.9k
    RTPP_OBJ_DECREF(dtls_strmp);
570
11.9k
    return (len);
571
2.29k
e1:
572
2.29k
    RTPP_OBJ_DECREF(dtls_strmp);
573
2.29k
e0:
574
2.29k
    return (-1);
575
2.29k
}
576
577
static long
578
bio_ctrl(BIO *b, int cmd, long num, void *ptr)
579
89.6k
{
580
89.6k
    (void)b;
581
89.6k
    (void)num;
582
89.6k
    (void)ptr;
583
584
89.6k
    switch (cmd) {
585
586
11.9k
    case BIO_CTRL_FLUSH:
587
        /* The OpenSSL library needs this */
588
11.9k
        return 1;
589
590
0
#if defined (BIO_CTRL_DGRAM_QUERY_MTU)
591
8.48k
    case BIO_CTRL_DGRAM_QUERY_MTU:
592
8.48k
        return MTU_DEFAULT;
593
0
#endif
594
595
0
#if defined (BIO_CTRL_DGRAM_GET_FALLBACK_MTU)
596
0
    case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
597
0
        return MTU_FALLBACK;
598
89.6k
#endif
599
89.6k
    }
600
601
69.2k
    return 0;
602
89.6k
}
603
604
static int
605
bio_create(BIO *b)
606
29.5k
{
607
29.5k
    BIO_set_init(b, 1);
608
29.5k
    BIO_set_data(b, NULL);
609
29.5k
    BIO_set_flags(b, 0);
610
611
29.5k
    return (1);
612
29.5k
}
613
614
615
static int
616
bio_destroy(BIO *b)
617
29.5k
{
618
619
29.5k
    BIO_set_init(b, 0);
620
29.5k
    BIO_set_data(b, NULL);
621
29.5k
    BIO_set_flags(b, 0);
622
623
29.5k
    return (1);
624
29.5k
}
625
626
static BIO_METHOD *
627
bio_method_udp(void)
628
29.5k
{
629
29.5k
    BIO_METHOD *method;
630
631
29.5k
    method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "udp_send");
632
29.5k
    if (!method) {
633
0
        return NULL;
634
0
    }
635
636
29.5k
    BIO_meth_set_write(method, bio_write);
637
29.5k
    BIO_meth_set_ctrl(method, bio_ctrl);
638
29.5k
    BIO_meth_set_create(method, bio_create);
639
29.5k
    BIO_meth_set_destroy(method, bio_destroy);
640
641
29.5k
    return (method);
642
29.5k
}
643
644
static int
645
tls_print_error(const char *str, size_t len, void *arg)
646
7.22k
{
647
7.22k
    struct rtpp_log *log = arg;
648
7.22k
    RTPP_LOG(log, RTPP_LOG_ERR, "%.*s", (int)len, str);
649
650
7.22k
    return 1;
651
7.22k
}
652
653
654
static void
655
tls_flush_error(struct rtpp_log *log)
656
46.2k
{
657
658
46.2k
    ERR_print_errors_cb(tls_print_error, log);
659
46.2k
}
660
661
static int
662
tls_accept(struct rtpp_dtls_conn_priv *pvt)
663
24.7k
{
664
24.7k
    int r;
665
666
24.7k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
667
668
24.7k
    ERR_clear_error();
669
670
24.7k
    r = SSL_accept(pvt->ssl_ctx);
671
24.7k
    if (r <= 0) {
672
24.7k
        const int ssl_err = SSL_get_error(pvt->ssl_ctx, r);
673
674
24.7k
        tls_flush_error(pvt->mself->log);
675
676
24.7k
        switch (ssl_err) {
677
20.4k
        case SSL_ERROR_WANT_READ:
678
20.4k
            break;
679
680
4.30k
        default:
681
4.30k
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "accept error: %i",
682
4.30k
              ssl_err);
683
4.30k
            return (-1);
684
24.7k
        }
685
24.7k
    }
686
687
20.4k
    if (check_timer(pvt) != 0)
688
0
        return (-1);
689
690
20.4k
    return (0);
691
20.4k
}
692
693
static enum rtpp_timed_cb_rvals
694
rtpp_dtls_conn_timeout(double dtime, void *arg)
695
0
{
696
0
    struct rtpp_dtls_conn_priv *pvt = arg;
697
698
0
    pthread_mutex_lock(&pvt->state_lock);
699
700
0
    if (pvt->ttp == NULL) {
701
        /* Lost race with check_timer() */
702
0
        goto done;
703
0
    }
704
705
0
    RTPP_OBJ_DECREF(pvt->ttp);
706
0
    pvt->ttp = NULL;
707
0
    if (pvt->state != RDC_CONNECTING)
708
0
        goto done;
709
0
    if (DTLSv1_handle_timeout(pvt->ssl_ctx) >= 0) {
710
0
        if (check_timer(pvt) != 0)
711
0
            pvt->state = RDC_DEAD;
712
0
    } else {
713
0
        ERR_clear_error();
714
0
        pvt->state = RDC_DEAD;
715
0
    }
716
0
done:
717
0
    pthread_mutex_unlock(&pvt->state_lock);
718
0
    return (CB_LAST);
719
0
}
720
721
static int
722
check_timer(struct rtpp_dtls_conn_priv *pvt)
723
39.6k
{
724
39.6k
    int err;
725
39.6k
    struct timeval tv = {0, 0};
726
727
39.6k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
728
729
39.6k
    err = DTLSv1_get_timeout(pvt->ssl_ctx, &tv);
730
39.6k
    if (err == 1 && pvt->ttp != NULL)
731
11.6k
        return (0);
732
27.9k
    if (err == 1) {
733
7.73k
        double to = timeval2dtime(&tv);
734
7.73k
        pvt->ttp = CALL_SMETHOD(pvt->timed_cf, schedule_rc, to,
735
7.73k
          pvt->pub.rcnt, rtpp_dtls_conn_timeout, NULL, pvt);
736
7.73k
        if (pvt->ttp == NULL)
737
0
            return (-1);
738
20.2k
    } else if (pvt->ttp != NULL) {
739
0
        CALL_METHOD(pvt->ttp, cancel);
740
0
        RTPP_OBJ_DECREF(pvt->ttp);
741
0
        pvt->ttp = NULL;
742
0
    }
743
744
27.9k
    return (0);
745
27.9k
}
746
747
static int
748
tls_connect(struct rtpp_dtls_conn_priv *pvt)
749
21.4k
{
750
21.4k
    int r;
751
752
21.4k
    RTPP_DBG_ASSERT(rtpp_mutex_islocked(&pvt->state_lock));
753
754
21.4k
    ERR_clear_error();
755
756
21.4k
    r = SSL_connect(pvt->ssl_ctx);
757
21.4k
    if (r <= 0) {
758
21.4k
        const int ssl_err = SSL_get_error(pvt->ssl_ctx, r);
759
760
21.4k
        tls_flush_error(pvt->mself->log);
761
762
21.4k
        switch (ssl_err) {
763
19.1k
        case SSL_ERROR_WANT_READ:
764
19.1k
            break;
765
766
2.31k
        default:
767
2.31k
            RTPP_LOG(pvt->mself->log, RTPP_LOG_ERR, "connect error: %i",
768
2.31k
              ssl_err);
769
2.31k
            return (-1);
770
21.4k
        }
771
21.4k
    }
772
773
19.1k
    check_timer(pvt);
774
775
19.1k
    return (0);
776
21.4k
}
777
778
static void
779
mem_secclean(void *data, size_t size)
780
0
{
781
0
    memset(data, 0, size);
782
    /* Insert an asm statement that may potentially depend
783
     * on the memory contents that were affected by memset.
784
     * This prevents optimizing away the memset. */
785
0
    __asm__ __volatile__("" : : "r" (data), "r" (size) : "memory");
786
0
}
787
788
static int
789
tls_srtp_keyinfo(SSL *ssl_ctx, const struct srtp_crypto_suite **suite,
790
  uint8_t *cli_key, size_t cli_key_size, uint8_t *srv_key,
791
  size_t srv_key_size, struct rtpp_log *log)
792
0
{
793
0
    static const char *label = "EXTRACTOR-dtls_srtp";
794
0
    size_t size;
795
0
    SRTP_PROTECTION_PROFILE *sel;
796
0
    uint8_t keymat[256], *p;
797
798
0
    sel = SSL_get_selected_srtp_profile(ssl_ctx);
799
0
    if (!sel) {
800
0
        ERR_clear_error();
801
0
        RTPP_LOG(log, RTPP_LOG_ERR,
802
0
          "SSL_get_selected_srtp_profile() failed");
803
0
        return (-1);
804
0
    }
805
806
0
    switch (sel->id) {
807
0
    case SRTP_AES128_CM_SHA1_80:
808
0
        *suite = &srtp_suites[SRTP_AES_CM_128_HMAC_SHA1_80];
809
0
        break;
810
811
0
    case SRTP_AES128_CM_SHA1_32:
812
0
        *suite = &srtp_suites[SRTP_AES_CM_128_HMAC_SHA1_32];
813
0
        break;
814
815
0
    case SRTP_AES128_F8_SHA1_80:
816
0
        *suite = &srtp_suites[SRTP_F8_128_HMAC_SHA1_80];
817
0
        break;
818
819
0
    case SRTP_AES128_F8_SHA1_32:
820
0
        *suite = &srtp_suites[SRTP_F8_128_HMAC_SHA1_32];
821
0
        break;
822
823
0
#ifdef SRTP_AEAD_AES_128_GCM
824
0
    case SRTP_AEAD_AES_128_GCM:
825
0
        *suite = &srtp_suites[SRTP_AES_128_GCM];
826
0
        break;
827
0
#endif
828
829
0
#ifdef SRTP_AEAD_AES_256_GCM
830
0
    case SRTP_AEAD_AES_256_GCM:
831
0
        *suite = &srtp_suites[SRTP_AES_256_GCM];
832
0
        break;
833
0
#endif
834
835
0
    default:
836
0
        abort();
837
0
    }
838
839
0
    size = (*suite)->key_size + (*suite)->iv_size;
840
841
0
    if (cli_key_size < size || srv_key_size < size)
842
0
        abort();
843
844
0
    if (sizeof(keymat) < (2 * size))
845
0
        abort();
846
847
0
    if (SSL_export_keying_material(ssl_ctx, keymat, 2 * size, label,
848
0
      strlen(label), NULL, 0, 0) != 1) {
849
0
        ERR_clear_error();
850
0
        RTPP_LOG(log, RTPP_LOG_ERR,
851
0
          "SSL_export_keying_material() failed");
852
0
        return (-1);
853
0
    }
854
855
0
    p = keymat;
856
857
0
    memcpy(cli_key, p, (*suite)->key_size);
858
0
    p += (*suite)->key_size;
859
0
    memcpy(srv_key, p, (*suite)->key_size);
860
0
    p += (*suite)->key_size;
861
0
    memcpy(cli_key + (*suite)->key_size, p, (*suite)->iv_size);
862
0
    p += (*suite)->iv_size;
863
0
    memcpy(srv_key + (*suite)->key_size, p, (*suite)->iv_size);
864
865
0
    mem_secclean(keymat, sizeof(keymat));
866
867
0
    return (0);
868
0
}
869
870
static int
871
tls_peer_fingerprint(SSL *ssl_ctx, char *buf, size_t size)
872
0
{
873
0
    X509 *cert;
874
0
    int err;
875
876
0
    cert = SSL_get_peer_certificate(ssl_ctx);
877
0
    if (cert == NULL)
878
0
        return (-1);
879
880
0
    err = rtpp_dtls_fp_gen(cert, buf, size);
881
882
0
    X509_free(cert);
883
884
0
    return (err);
885
0
}
886
887
static void
888
rtpp_dtls_conn_godead(struct rtpp_dtls_conn *self)
889
29.5k
{
890
29.5k
    struct rtpp_dtls_conn_priv *pvt;
891
892
29.5k
    PUB2PVT(self, pvt);
893
894
29.5k
    pthread_mutex_lock(&pvt->state_lock);
895
29.5k
    pvt->state = RDC_DEAD;
896
29.5k
    if (pvt->ttp != NULL) {
897
7.73k
        CALL_METHOD(pvt->ttp, cancel);
898
7.73k
        RTPP_OBJ_DECREF(pvt->ttp);
899
        pvt->ttp = NULL;
900
7.73k
    }
901
29.5k
    pthread_mutex_unlock(&pvt->state_lock);
902
29.5k
}