From 8595f95cef09a145ad02cbbcbe95bfa08d483740 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Fri, 30 Dec 2022 11:25:01 +0100 Subject: [PATCH] MT#56126 Introduce a preference list for crypto suites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a new option flag, which provides the ordered list, in which to add crypto suites into the SDP body. Right now they're always added in the order given in the source code. Flag usage example: `SDES-order:AES_256_CM_HMAC_SHA;AES_256_CM_HMAC_SHA1_32;AES_192_CM_HMAC_SHA1_80;` This means — those listed SDES crypto suites will be added into the generated SDP body at the top of crypto suites list, in the given order. But, each of them is added, only if it is about to be added/generated. In other words, the `SDES-order:` flag itself doesn't add crypto suites, it just affects the order of those suites to be added. And the rest of non-mentioned suites, which are also to be added, will be appended after those given, in the free manner of ordering. Important thing to remember - it doesn't change the crypto suite tag for the recipient, even though changing the order of them. Additionally. This flag does not contradict with `SDES-nonew`, `SDES-only-` and `SDES-no-` flags. It just orders the list of crypto suites already prepared to be sent out. Change-Id: I0fec54f9e2f3cd4913e905e8afe825712f82d1ae --- README.md | 18 ++++ daemon/call.c | 42 ++++++++ daemon/call_interfaces.c | 7 ++ include/call_interfaces.h | 1 + t/auto-daemon-tests.pl | 220 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 288 insertions(+) diff --git a/README.md b/README.md index 14456d226..cbceedc05 100644 --- a/README.md +++ b/README.md @@ -1264,6 +1264,24 @@ Optionally included keys are: will accepted, meanwhile no new is going to be generated by RTPEngine. It takes precedence over the `SDES-no` and `SDES-only` flags, if used in combination. + - `order:`*SUITES LIST* + + The order, in which crypto suites are being added to the SDP. + Example: `SDES-order:AES_256_CM_HMAC_SHA;AES_256_CM_HMAC_SHA1_32;AES_192_CM_HMAC_SHA1_80;`, + this means — those listed SDES crypto suites will be added into the generated SDP body at the top + of crypto suites list, in the given order. But, each of them is added, only if it is + about to be added/generated. In other words, the `SDES-order:` flag itself doesn't add crypto suites, + it just affects the order of those suites to be added. + + And the rest of non-mentioned suites (not mentioned in the `SDES-order:` list), + which are also to be added, will be appended after those given, in the free manner of ordering. + + Important thing to remember - it doesn't change the crypto suite tag + for the recipient, even though changing the order of them. + + This flag does not contradict with `SDES-nonew`, `SDES-only-` and `SDES-no-` flags. + It just orders the list of crypto suites already prepared to be sent out. + - `pad` RFC 4568 (section 6.1) is somewhat ambiguous regarding the base64 encoding format of diff --git a/daemon/call.c b/daemon/call.c index 1f4e0f5ea..ac7b49917 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1686,8 +1686,12 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi GQueue *cpq = &this->sdes_out; /* SDES options coming to us for processing */ GQueue *cpq_in = &this->sdes_in; + const GQueue *offered_cpq = other ? &other->sdes_in : NULL; + /* requested order of crypto suites */ + const GQueue *cpq_order = &flags->sdes_order; + if (!flags) return; @@ -1857,6 +1861,44 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi __sdes_flags(cps, flags); } } + + /* order the crypto suites list before to send out, if needed */ + if (cpq_order && cpq_order->head) { + ilog(LOG_DEBUG, "The crypto suites in the outbound SDP will be re-ordered."); + + GQueue cpq_orig_list = *cpq; + g_queue_init(cpq); /* re-initialize sdes_out */ + + /* first add those mentioned in the order list, + * but only, if they were previously generated/added to the sdes_out */ + for (GList *l = cpq_order ? cpq_order->head : NULL; l; l = l->next) + { + str * cs_name = l->data; + struct crypto_params_sdes * cps_order; + + GList * elem = g_queue_find_custom(&cpq_orig_list, cs_name, crypto_params_sdes_cmp); + + if (!elem) + continue; + + cps_order = elem->data; + + ilog(LOG_DEBUG, "New suites order, adding: %s (cps tag: %d)", + cps_order->params.crypto_suite->name, cps_order->tag); + + g_queue_push_tail(cpq, cps_order); + g_queue_delete_link(&cpq_orig_list, elem); + } + + /* now add the rest */ + while ((cps_orig = g_queue_pop_head(&cpq_orig_list))) + { + ilog(LOG_DEBUG, "New suites order, adding: %s (cps tag: %d)", + cps_orig->params.crypto_suite->name, cps_orig->tag); + + g_queue_push_tail(cpq, cps_orig); + } + } } /* OP_ANSWER */ diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 90a509254..a9f8c801b 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -516,6 +516,10 @@ INLINE void ng_sdes_option(struct sdp_ng_flags *out, str *s, void *dummy) { if (call_ng_flags_prefix(out, s, "no-", call_ng_flags_str_ht, &out->sdes_no)) return; + /* Order individual crypto suites */ + if (call_ng_flags_prefix(out, s, "order:", call_ng_flags_str_q_multi, &out->sdes_order)) + return; + switch (__csh_lookup(s)) { case CSH_LOOKUP("no"): case CSH_LOOKUP("off"): @@ -958,6 +962,8 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { return; if (call_ng_flags_prefix(out, s, "SDES-no-", call_ng_flags_str_ht, &out->sdes_no)) return; + if (call_ng_flags_prefix(out, s, "SDES-order:", call_ng_flags_str_q_multi, &out->sdes_order)) + return; if (call_ng_flags_prefix(out, s, "SDES-", ng_sdes_option, NULL)) return; if (call_ng_flags_prefix(out, s, "OSRTP-", ng_osrtp_option, NULL)) @@ -1592,6 +1598,7 @@ void call_ng_free_flags(struct sdp_ng_flags *flags) { g_queue_clear_full(&flags->codec_accept, free); g_queue_clear_full(&flags->codec_consume, free); g_queue_clear_full(&flags->codec_mask, free); + g_queue_clear_full(&flags->sdes_order, free); } static enum load_limit_reasons call_offer_session_limit(void) { diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 4968bbf16..9fa577d69 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -55,6 +55,7 @@ struct sdp_ng_flags { rev_ptime; GHashTable *sdes_no; /* individual crypto suites which are excluded */ GHashTable *sdes_only; /* individual crypto suites which are only accepted */ + GQueue sdes_order; /* the order, in which crypto suites are being added to the SDP */ str dtls_fingerprint; enum { ICE_DEFAULT = 0, diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index e077a6213..9f61ffca5 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -14261,6 +14261,226 @@ a=rtcp:PORT a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128 SDP +new_call; + +offer('SDES re-ordered crypto suites', { ICE => 'remove', DTLS => 'off', SDES => [ 'order:AES_256_CM_HMAC_SHA1_32;AES_256_CM_HMAC_SHA1_80;AES_CM_128_HMAC_SHA1_32;AES_CM_128_HMAC_SHA1_80' ] }, < 'remove' }, < 'remove', DTLS => 'off', SDES => [ 'nonew', 'order:AES_256_CM_HMAC_SHA1_32;AES_256_CM_HMAC_SHA1_80;AES_CM_128_HMAC_SHA1_32;AES_CM_128_HMAC_SHA1_80' ] }, < 'remove' }, < 'remove', DTLS => 'off', SDES => [ 'no-AES_CM_128_HMAC_SHA1_32', 'order:AES_256_CM_HMAC_SHA1_32;AES_256_CM_HMAC_SHA1_80;AES_CM_128_HMAC_SHA1_80' ] }, < 'remove' }, < 'remove', DTLS => 'off', SDES => [ 'only-AES_256_CM_HMAC_SHA1_32', 'order:AES_256_CM_HMAC_SHA1_32;AES_256_CM_HMAC_SHA1_80;AES_CM_128_HMAC_SHA1_32;AES_CM_128_HMAC_SHA1_80' ] }, < 'remove' }, <