ARI: Add ability to raise arbitrary User Events
[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 "asterisk/options.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/sdp_srtp.h"
40
41 #define SRTP_MASTER_LEN 30
42 #define SRTP_MASTERKEY_LEN 16
43 #define SRTP_MASTERSALT_LEN ((SRTP_MASTER_LEN) - (SRTP_MASTERKEY_LEN))
44 #define SRTP_MASTER_LEN64 (((SRTP_MASTER_LEN) * 8 + 5) / 6 + 1)
45
46 extern struct ast_srtp_res *res_srtp;
47 extern struct ast_srtp_policy_res *res_srtp_policy;
48
49 struct ast_sdp_srtp *ast_sdp_srtp_alloc(void)
50 {
51         if (!ast_rtp_engine_srtp_is_registered()) {
52                ast_debug(1, "No SRTP module loaded, can't setup SRTP session.\n");
53                return NULL;
54         }
55
56         return ast_calloc(1, sizeof(struct ast_sdp_srtp));
57 }
58
59 void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
60 {
61         if (srtp->crypto) {
62                 ast_sdp_crypto_destroy(srtp->crypto);
63         }
64         srtp->crypto = NULL;
65         ast_free(srtp);
66 }
67
68 struct ast_sdp_crypto {
69         char *a_crypto;
70         unsigned char local_key[SRTP_MASTER_LEN];
71         char *tag;
72         char local_key64[SRTP_MASTER_LEN64];
73         unsigned char remote_key[SRTP_MASTER_LEN];
74 };
75
76 static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, unsigned long ssrc, int inbound);
77
78 void ast_sdp_crypto_destroy(struct ast_sdp_crypto *crypto)
79 {
80         ast_free(crypto->a_crypto);
81         crypto->a_crypto = NULL;
82         ast_free(crypto->tag);
83         crypto->tag = NULL;
84         ast_free(crypto);
85 }
86
87 struct ast_sdp_crypto *ast_sdp_crypto_alloc(void)
88 {
89         struct ast_sdp_crypto *p;
90         int key_len;
91         unsigned char remote_key[SRTP_MASTER_LEN];
92
93         if (!ast_rtp_engine_srtp_is_registered()) {
94                 return NULL;
95         }
96
97         if (!(p = ast_calloc(1, sizeof(*p)))) {
98                 return NULL;
99         }
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_free(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_free(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;
215         char *lifetime = NULL;
216         int found = 0;
217         int key_len = 0;
218         int suite_val = 0;
219         unsigned char remote_key[SRTP_MASTER_LEN];
220         int taglen = 0;
221         struct ast_sdp_crypto *crypto = srtp->crypto;
222
223         if (!ast_rtp_engine_srtp_is_registered()) {
224                 return -1;
225         }
226
227         str = ast_strdupa(attr);
228
229         tag = strsep(&str, " ");
230         suite = strsep(&str, " ");
231         key_params = strsep(&str, " ");
232         session_params = strsep(&str, " ");
233
234         if (!tag || !suite) {
235                 ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
236                 return -1;
237         }
238
239         if (!ast_strlen_zero(session_params)) {
240                 ast_log(LOG_WARNING, "Unsupported crypto parameters: %s", session_params);
241                 return -1;
242         }
243
244         if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
245                 suite_val = AST_AES_CM_128_HMAC_SHA1_80;
246                 ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_80);
247                 taglen = 80;
248         } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
249                 suite_val = AST_AES_CM_128_HMAC_SHA1_32;
250                 ast_set_flag(srtp, AST_SRTP_CRYPTO_TAG_32);
251                 taglen = 32;
252         } else {
253                 ast_log(LOG_WARNING, "Unsupported crypto suite: %s\n", suite);
254                 return -1;
255         }
256
257         while ((key_param = strsep(&key_params, ";"))) {
258                 char *method = NULL;
259                 char *info = NULL;
260
261                 method = strsep(&key_param, ":");
262                 info = strsep(&key_param, ";");
263
264                 if (!strcmp(method, "inline")) {
265                         key_salt = strsep(&info, "|");
266                         lifetime = strsep(&info, "|");
267
268                         if (lifetime) {
269                                 ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n", attr);
270                                 continue;
271                         }
272
273                         found = 1;
274                         break;
275                 }
276         }
277
278         if (!found) {
279                 ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
280                 return -1;
281         }
282
283         if ((key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key))) != SRTP_MASTER_LEN) {
284                 ast_log(LOG_WARNING, "SRTP descriptions key %d != %d\n", key_len, SRTP_MASTER_LEN);
285                 return -1;
286         }
287
288         if (!memcmp(crypto->remote_key, remote_key, sizeof(crypto->remote_key))) {
289                 ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
290                 ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
291                 return 0;
292         }
293         memcpy(crypto->remote_key, remote_key, sizeof(crypto->remote_key));
294
295         if (crypto_activate(crypto, suite_val, remote_key, rtp) < 0) {
296                 return -1;
297         }
298
299         if (!crypto->tag) {
300                 ast_debug(1, "Accepting crypto tag %s\n", tag);
301                 crypto->tag = ast_strdup(tag);
302                 if (!crypto->tag) {
303                         ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
304                         return -1;
305                 }
306         }
307
308         /* Finally, rebuild the crypto line */
309         if (ast_sdp_crypto_build_offer(crypto, taglen)) {
310                 return -1;
311         }
312
313         ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
314         return 0;
315 }
316
317 int ast_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
318 {
319         /* Rebuild the crypto line */
320         if (p->a_crypto) {
321                 ast_free(p->a_crypto);
322         }
323
324         if (ast_asprintf(&p->a_crypto, "%s AES_CM_128_HMAC_SHA1_%i inline:%s",
325                          p->tag ? p->tag : "1", taglen, p->local_key64) == -1) {
326                         ast_log(LOG_ERROR, "Could not allocate memory for crypto line\n");
327                 return -1;
328         }
329
330         ast_debug(1, "Crypto line: a=crypto:%s\n", p->a_crypto);
331
332         return 0;
333 }
334
335 const char *ast_sdp_srtp_get_attrib(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
336 {
337         int taglen = default_taglen_32 ? 32 : 80;
338
339         if (!srtp) {
340                 return NULL;
341         }
342
343         /* Set encryption properties */
344         if (!srtp->crypto) {
345                 srtp->crypto = ast_sdp_crypto_alloc();
346         }
347
348         if (dtls_enabled) {
349                 /* If DTLS-SRTP is enabled the key details will be pulled from TLS */
350                 return NULL;
351         }
352
353         /* set the key length based on INVITE or settings */
354         if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_80)) {
355                 taglen = 80;
356         } else if (ast_test_flag(srtp, AST_SRTP_CRYPTO_TAG_32)) {
357                 taglen = 32;
358         }
359
360         if (srtp->crypto && (ast_sdp_crypto_build_offer(srtp->crypto, taglen) >= 0)) {
361                 return srtp->crypto->a_crypto;
362         }
363
364         ast_log(LOG_WARNING, "No SRTP key management enabled\n");
365         return NULL;
366 }
367
368 char *ast_sdp_get_rtp_profile(unsigned int sdes_active, struct ast_rtp_instance *instance, unsigned int using_avpf)
369 {
370         struct ast_rtp_engine_dtls *dtls;
371
372         if ((dtls = ast_rtp_instance_get_dtls(instance)) && dtls->active(instance)) {
373                 return using_avpf ? "UDP/TLS/RTP/SAVPF" : "UDP/TLS/RTP/SAVP";
374         } else {
375                 if (using_avpf) {
376                         return sdes_active ? "RTP/SAVPF" : "RTP/AVPF";
377                 } else {
378                         return sdes_active ? "RTP/SAVP" : "RTP/AVP";
379                 }
380         }
381 }
382