Replace most uses of ast_register_atexit with ast_register_cleanup.
[asterisk/asterisk.git] / main / sdp_srtp.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2006 - 2007, Mikael Magnusson
5  *
6  * Mikael Magnusson <mikma@users.sourceforge.net>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file ast_sdp_crypto.c
20  *
21  * \brief SRTP and SDP Security descriptions
22  *
23  * Specified in RFC 3711
24  * Specified in RFC 4568
25  *
26  * \author Mikael Magnusson <mikma@users.sourceforge.net>
27  */
28
29 /*** MODULEINFO
30         <support_level>core</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36
37 #include <math.h>
38 #include "asterisk/options.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/sdp_srtp.h"
41
42 #define SRTP_MASTER_LEN 30
43 #define SRTP_MASTERKEY_LEN 16
44 #define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN))
45 #define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1)
46
47 extern struct ast_srtp_res *res_srtp;
48 extern struct ast_srtp_policy_res *res_srtp_policy;
49
50 struct ast_sdp_srtp *ast_sdp_srtp_alloc(void)
51 {
52         if (!ast_rtp_engine_srtp_is_registered()) {
53                ast_debug(1, "No SRTP module loaded, can't setup SRTP session.\n");
54                return NULL;
55         }
56
57         return ast_calloc(1, sizeof(struct ast_sdp_srtp));
58 }
59
60 void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
61 {
62         if (srtp->crypto) {
63                 ast_sdp_crypto_destroy(srtp->crypto);
64         }
65         srtp->crypto = NULL;
66         ast_free(srtp);
67 }
68
69 struct ast_sdp_crypto {
70         char *a_crypto;
71         unsigned char local_key[SRTP_MASTER_LEN];
72         int tag;
73         char local_key64[SRTP_MASTER_LEN64];
74         unsigned char remote_key[SRTP_MASTER_LEN];
75 };
76
77 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound);
78
79 void ast_sdp_crypto_destroy(struct ast_sdp_crypto *crypto)
80 {
81         ast_free(crypto->a_crypto);
82         crypto->a_crypto = NULL;
83         ast_free(crypto);
84 }
85
86 struct ast_sdp_crypto *ast_sdp_crypto_alloc(void)
87 {
88         struct ast_sdp_crypto *p;
89         int key_len;
90         unsigned char remote_key[SRTP_MASTER_LEN];
91
92         if (!ast_rtp_engine_srtp_is_registered()) {
93                 return NULL;
94         }
95
96         if (!(p = ast_calloc(1, sizeof(*p)))) {
97                 return NULL;
98         }
99         p->tag = 1;
100
101         if (res_srtp->get_random(p->local_key, sizeof(p->local_key)) < 0) {
102                 ast_sdp_crypto_destroy(p);
103                 return NULL;
104         }
105
106         ast_base64encode(p->local_key64, p->local_key, SRTP_MASTER_LEN, sizeof(p->local_key64));
107
108         key_len = ast_base64decode(remote_key, p->local_key64, sizeof(remote_key));
109
110         if (key_len != SRTP_MASTER_LEN) {
111                 ast_log(LOG_ERROR, "base64 encode/decode bad len %d != %d\n", key_len, SRTP_MASTER_LEN);
112                 ast_sdp_crypto_destroy(p);
113                 return NULL;
114         }
115
116         if (memcmp(remote_key, p->local_key, SRTP_MASTER_LEN)) {
117                 ast_log(LOG_ERROR, "base64 encode/decode bad key\n");
118                 ast_sdp_crypto_destroy(p);
119                 return NULL;
120         }
121
122         ast_debug(1 , "local_key64 %s len %zu\n", p->local_key64, strlen(p->local_key64));
123
124         return p;
125 }
126
127 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound)
128 {
129         const unsigned char *master_salt = NULL;
130
131         if (!ast_rtp_engine_srtp_is_registered()) {
132                 return -1;
133         }
134
135         master_salt = master_key + SRTP_MASTERKEY_LEN;
136         if (res_srtp_policy->set_master_key(policy, master_key, SRTP_MASTERKEY_LEN, master_salt, SRTP_MASTERSALT_LEN) < 0) {
137                 return -1;
138         }
139
140         if (res_srtp_policy->set_suite(policy, suite_val)) {
141                 ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
142                 return -1;
143         }
144
145         res_srtp_policy->set_ssrc(policy, ssrc, inbound);
146
147         return 0;
148 }
149
150 static int crypto_activate(struct ast_sdp_crypto *p, int suite_val, unsigned char *remote_key, struct ast_rtp_instance *rtp)
151 {
152         struct ast_srtp_policy *local_policy = NULL;
153         struct ast_srtp_policy *remote_policy = NULL;
154         struct ast_rtp_instance_stats stats = {0,};
155         int res = -1;
156
157         if (!ast_rtp_engine_srtp_is_registered()) {
158                 return -1;
159         }
160
161         if (!p) {
162                 return -1;
163         }
164
165         if (!(local_policy = res_srtp_policy->alloc())) {
166                 return -1;
167         }
168
169         if (!(remote_policy = res_srtp_policy->alloc())) {
170                 goto err;
171         }
172
173         if (ast_rtp_instance_get_stats(rtp, &stats, AST_RTP_INSTANCE_STAT_LOCAL_SSRC)) {
174                 goto err;
175         }
176
177         if (set_crypto_policy(local_policy, suite_val, p->local_key, stats.local_ssrc, 0) < 0) {
178                 goto err;
179         }
180
181         if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0) {
182                 goto err;
183         }
184
185         /* Add the SRTP policies */
186         if (ast_rtp_instance_add_srtp_policy(rtp, remote_policy, local_policy)) {
187                 ast_log(LOG_WARNING, "Could not set SRTP policies\n");
188                 goto err;
189         }
190
191         ast_debug(1 , "SRTP policy activated\n");
192         res = 0;
193
194 err:
195         if (local_policy) {
196                 res_srtp_policy->destroy(local_policy);
197         }
198
199         if (remote_policy) {
200                 res_srtp_policy->destroy(remote_policy);
201         }
202
203         return res;
204 }
205
206 int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
207 {
208         char *str = NULL;
209         char *tag = NULL;
210         char *suite = NULL;
211         char *key_params = NULL;
212         char *key_param = NULL;
213         char *session_params = NULL;
214         char *key_salt = NULL;       /* The actual master key and key salt */
215         char *lifetime = NULL;       /* Key lifetime (# of RTP packets) */
216         char *mki = NULL;            /* Master Key Index */
217         int found = 0;
218         int key_len = 0;
219         int suite_val = 0;
220         unsigned char remote_key[SRTP_MASTER_LEN];
221         int taglen = 0;
222         double sdes_lifetime;
223         struct ast_sdp_crypto *crypto = srtp->crypto;
224
225         if (!ast_rtp_engine_srtp_is_registered()) {
226                 return -1;
227         }
228
229         str = ast_strdupa(attr);
230
231         tag = strsep(&str, " ");
232         suite = strsep(&str, " ");
233         key_params = strsep(&str, " ");
234         session_params = strsep(&str, " ");
235
236         if (!tag || !suite) {
237                 ast_log(LOG_WARNING, "Unrecognized crypto attribute a=%s\n", attr);
238                 return -1;
239         }
240
241         if (sscanf(tag, "%30d", &crypto->tag) != 1 || crypto->tag <= 0 || crypto->tag > 9) {
242                 ast_log(LOG_WARNING, "Unacceptable a=crypto tag: %s\n", tag);
243                 return -1;
244         }
245
246         if (!ast_strlen_zero(session_params)) {
247                 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s\n", session_params);
248                 return -1;
249         }
250
251         if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
252                 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
253                 ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_80);
254                 taglen = 80;
255         } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
256                 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
257                 ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_32);
258                 taglen = 32;
259         } else {
260                 ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite);
261                 return -1;
262         }
263
264         while ((key_param = strsep(&key_params, ";"))) {
265                 unsigned int n_lifetime;
266                 char *method = NULL;
267                 char *info = NULL;
268
269                 method = strsep(&key_param, ":");
270                 info = strsep(&key_param, ";");
271                 sdes_lifetime = 0;
272
273                 if (strcmp(method, "inline")) {
274                         continue;
275                 }
276
277                 key_salt = strsep(&info, "|");
278
279                 /* The next parameter can be either lifetime or MKI */
280                 lifetime = strsep(&info, "|");
281                 if (!lifetime) {
282                         found = 1;
283                         break;
284                 }
285
286                 mki = strchr(lifetime, ':');
287                 if (mki) {
288                         mki = lifetime;
289                         lifetime = NULL;
290                 } else {
291                         mki = strsep(&info, "|");
292                 }
293
294                 if (mki && *mki != '1') {
295                         ast_log(LOG_NOTICE, "Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
296                         continue;
297                 }
298
299                 if (lifetime) {
300                         if (!strncmp(lifetime, "2^", 2)) {
301                                 char *lifetime_val = lifetime + 2;
302
303                                 /* Exponential lifetime */
304                                 if (sscanf(lifetime_val, "%30u", &n_lifetime) != 1) {
305                                         ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
306                                         continue;
307                                 }
308
309                                 if (n_lifetime > 48) {
310                                         /* Yeah... that's a bit big. */
311                                         ast_log(LOG_NOTICE, "Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
312                                         n_lifetime = 48;
313                                 }
314                                 sdes_lifetime = pow(2, n_lifetime);
315                         } else {
316                                 /* Decimal lifetime */
317                                 if (sscanf(lifetime, "%30u", &n_lifetime) != 1) {
318                                         ast_log(LOG_NOTICE, "Failed to parse lifetime value in crypto attribute: %s\n", attr);
319                                         continue;
320                                 }
321                                 sdes_lifetime = n_lifetime;
322                         }
323
324                         /* Accept anything above 10 hours. Less than 10; reject. */
325                         if (sdes_lifetime < 1800000) {
326                                 ast_log(LOG_NOTICE, "Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
327                                 continue;
328                         }
329                 }
330
331                 ast_debug(2, "Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
332                         attr, sdes_lifetime, mki ? mki : "-");
333
334                 found = 1;
335                 break;
336         }
337
338         if (!found) {
339                 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable: '%s'\n", attr);
340                 return -1;
341         }
342
343         key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key));
344         if (key_len != SRTP_MASTER_LEN) {
345                 ast_log(LOG_WARNING, "SRTP descriptions key length '%d' != master length '%d'\n",
346                         key_len, SRTP_MASTER_LEN);
347                 return -1;
348         }
349
350         if (!memcmp(crypto->remote_key, remote_key, sizeof(crypto->remote_key))) {
351                 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
352                 ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
353                 return 0;
354         }
355         memcpy(crypto->remote_key, remote_key, sizeof(crypto->remote_key));
356
357         if (crypto_activate(crypto, suite_val, remote_key, rtp) < 0) {
358                 return -1;
359         }
360
361         /* Finally, rebuild the crypto line */
362         if (ast_sdp_crypto_build_offer(crypto, taglen)) {
363                 return -1;
364         }
365
366         ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
367         return 0;
368 }
369
370 int ast_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
371 {
372         /* Rebuild the crypto line */
373         if (p->a_crypto) {
374                 ast_free(p->a_crypto);
375         }
376
377         if (ast_asprintf(&p->a_crypto, "%d AES_CM_128_HMAC_SHA1_%i inline:%s",
378                          p->tag, taglen, p->local_key64) == -1) {
379                         ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
380                 return -1;
381         }
382
383         ast_debug(1, "Crypto line: a=crypto:%s\n", p->a_crypto);
384
385         return 0;
386 }
387
388 const char *ast_sdp_srtp_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
389 {
390         int taglen = default_taglen_32 ? 32 : 80;
391
392         if (!srtp) {
393                 return NULL;
394         }
395
396         /* Set encryption properties */
397         if (!srtp->crypto) {
398                 srtp->crypto = ast_sdp_crypto_alloc();
399         }
400
401         if (dtls_enabled) {
402                 /* If DTLS-SRTP is enabled the key details will be pulled from TLS */
403                 return NULL;
404         }
405
406         /* set the key length based on INVITE or settings */
407         if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_80)) {
408                 taglen = 80;
409         } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_32)) {
410                 taglen = 32;
411         }
412
413         if (srtp->crypto && (ast_sdp_crypto_build_offer(srtp->crypto, taglen) >= 0)) {
414                 return srtp->crypto->a_crypto;
415         }
416
417         ast_log(LOG_WARNING, "No SRTP key management enabled\n");
418         return NULL;
419 }
420
421 char *ast_sdp_get_rtp_profile(unsigned int sdes_active, struct ast_rtp_instance *instance, unsigned int using_avpf,
422         unsigned int force_avp)
423 {
424         struct ast_rtp_engine_dtls *dtls;
425
426         if ((dtls = ast_rtp_instance_get_dtls(instance)) && dtls->active(instance)) {
427                 if (force_avp) {
428                         return using_avpf ? "RTP/SAVPF" : "RTP/SAVP";
429                 } else {
430                         return using_avpf ? "UDP/TLS/RTP/SAVPF" : "UDP/TLS/RTP/SAVP";
431                 }
432         } else {
433                 if (using_avpf) {
434                         return sdes_active ? "RTP/SAVPF" : "RTP/AVPF";
435                 } else {
436                         return sdes_active ? "RTP/SAVP" : "RTP/AVP";
437                 }
438         }
439 }
440