1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 /* ====================================================================
58  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  *    notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in
69  *    the documentation and/or other materials provided with the
70  *    distribution.
71  *
72  * 3. All advertising materials mentioning features or use of this
73  *    software must display the following acknowledgment:
74  *    "This product includes software developed by the OpenSSL Project
75  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76  *
77  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78  *    endorse or promote products derived from this software without
79  *    prior written permission. For written permission, please contact
80  *    openssl-core@openssl.org.
81  *
82  * 5. Products derived from this software may not be called "OpenSSL"
83  *    nor may "OpenSSL" appear in their names without prior written
84  *    permission of the OpenSSL Project.
85  *
86  * 6. Redistributions of any form whatsoever must retain the following
87  *    acknowledgment:
88  *    "This product includes software developed by the OpenSSL Project
89  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90  *
91  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  * ====================================================================
104  *
105  * This product includes cryptographic software written by Eric Young
106  * (eay@cryptsoft.com).  This product includes software written by Tim
107  * Hudson (tjh@cryptsoft.com).
108  *
109  */
110 /*
111   DTLS code by Eric Rescorla <ekr@rtfm.com>
112 
113   Copyright (C) 2006, Network Resonance, Inc.
114   Copyright (C) 2011, RTFM, Inc.
115 */
116 
117 #include <stdio.h>
118 #include <string.h>
119 
120 #include <openssl/bytestring.h>
121 #include <openssl/err.h>
122 #include <openssl/obj.h>
123 
124 #include "internal.h"
125 #include <openssl/srtp.h>
126 
127 
128 static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
129     {
130      "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
131     },
132     {
133      "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
134     },
135     {0},
136 };
137 
find_profile_by_name(const char * profile_name,const SRTP_PROTECTION_PROFILE ** pptr,size_t len)138 static int find_profile_by_name(const char *profile_name,
139                                 const SRTP_PROTECTION_PROFILE **pptr,
140                                 size_t len) {
141   const SRTP_PROTECTION_PROFILE *p;
142 
143   p = srtp_known_profiles;
144   while (p->name) {
145     if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) {
146       *pptr = p;
147       return 1;
148     }
149 
150     p++;
151   }
152 
153   return 0;
154 }
155 
find_profile_by_num(unsigned profile_num,const SRTP_PROTECTION_PROFILE ** pptr)156 static int find_profile_by_num(unsigned profile_num,
157                                const SRTP_PROTECTION_PROFILE **pptr) {
158   const SRTP_PROTECTION_PROFILE *p;
159 
160   p = srtp_known_profiles;
161   while (p->name) {
162     if (p->id == profile_num) {
163       *pptr = p;
164       return 1;
165     }
166     p++;
167   }
168 
169   return 0;
170 }
171 
ssl_ctx_make_profiles(const char * profiles_string,STACK_OF (SRTP_PROTECTION_PROFILE)** out)172 static int ssl_ctx_make_profiles(const char *profiles_string,
173                                  STACK_OF(SRTP_PROTECTION_PROFILE) **out) {
174   STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
175 
176   const char *col;
177   const char *ptr = profiles_string;
178 
179   profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
180   if (profiles == NULL) {
181     OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
182                       SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
183     return 0;
184   }
185 
186   do {
187     const SRTP_PROTECTION_PROFILE *p;
188 
189     col = strchr(ptr, ':');
190     if (find_profile_by_name(ptr, &p, col ? col - ptr : strlen(ptr))) {
191       sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
192     } else {
193       OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
194                         SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
195       return 0;
196     }
197 
198     if (col) {
199       ptr = col + 1;
200     }
201   } while (col);
202 
203   *out = profiles;
204 
205   return 1;
206 }
207 
SSL_CTX_set_srtp_profiles(SSL_CTX * ctx,const char * profiles)208 int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) {
209   return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
210 }
211 
SSL_set_srtp_profiles(SSL * s,const char * profiles)212 int SSL_set_srtp_profiles(SSL *s, const char *profiles) {
213   return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
214 }
215 
STACK_OF(SRTP_PROTECTION_PROFILE)216 STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) {
217   if (s == NULL) {
218     return NULL;
219   }
220 
221   if (s->srtp_profiles != NULL) {
222     return s->srtp_profiles;
223   }
224 
225   if (s->ctx != NULL && s->ctx->srtp_profiles != NULL) {
226     return s->ctx->srtp_profiles;
227   }
228 
229   return NULL;
230 }
231 
SSL_get_selected_srtp_profile(SSL * s)232 const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) {
233   return s->srtp_profile;
234 }
235 
SSL_CTX_set_tlsext_use_srtp(SSL_CTX * ctx,const char * profiles)236 int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
237   /* This API inverts its return value. */
238   return !SSL_CTX_set_srtp_profiles(ctx, profiles);
239 }
240 
SSL_set_tlsext_use_srtp(SSL * s,const char * profiles)241 int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) {
242   /* This API inverts its return value. */
243   return !SSL_set_srtp_profiles(s, profiles);
244 }
245 
246 /* Note: this function returns 0 length if there are no profiles specified */
ssl_add_clienthello_use_srtp_ext(SSL * s,uint8_t * p,int * len,int maxlen)247 int ssl_add_clienthello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen) {
248   int ct = 0;
249   int i;
250   STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
251   const SRTP_PROTECTION_PROFILE *prof;
252 
253   clnt = SSL_get_srtp_profiles(s);
254   ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
255 
256   if (p) {
257     if (ct == 0) {
258       OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
259                         SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
260       return 0;
261     }
262 
263     if (2 + ct * 2 + 1 > maxlen) {
264       OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
265                         SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
266       return 0;
267     }
268 
269     /* Add the length */
270     s2n(ct * 2, p);
271     for (i = 0; i < ct; i++) {
272       prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
273       s2n(prof->id, p);
274     }
275 
276     /* Add an empty use_mki value */
277     *p++ = 0;
278   }
279 
280   *len = 2 + ct * 2 + 1;
281 
282   return 1;
283 }
284 
ssl_parse_clienthello_use_srtp_ext(SSL * s,CBS * cbs,int * out_alert)285 int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
286   CBS profile_ids, srtp_mki;
287   const SRTP_PROTECTION_PROFILE *cprof, *sprof;
288   STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles = 0, *server_profiles;
289   size_t i, j;
290   int ret = 0;
291 
292   if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
293       CBS_len(&profile_ids) < 2 ||
294       !CBS_get_u8_length_prefixed(cbs, &srtp_mki) ||
295       CBS_len(cbs) != 0) {
296     OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
297                       SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
298     *out_alert = SSL_AD_DECODE_ERROR;
299     goto done;
300   }
301 
302   client_profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
303   if (client_profiles == NULL) {
304     OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
305                       ERR_R_MALLOC_FAILURE);
306     *out_alert = SSL_AD_INTERNAL_ERROR;
307     goto done;
308   }
309 
310   while (CBS_len(&profile_ids) > 0) {
311     uint16_t profile_id;
312 
313     if (!CBS_get_u16(&profile_ids, &profile_id)) {
314       *out_alert = SSL_AD_DECODE_ERROR;
315       goto done;
316     }
317 
318     if (find_profile_by_num(profile_id, &cprof)) {
319       sk_SRTP_PROTECTION_PROFILE_push(client_profiles, cprof);
320     }
321   }
322 
323   /* Discard the MKI value for now. */
324 
325   server_profiles = SSL_get_srtp_profiles(s);
326 
327   /* Pick the server's most preferred profile. */
328   for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
329     sprof = sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);
330 
331     for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); j++) {
332       cprof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, j);
333 
334       if (cprof->id == sprof->id) {
335         s->srtp_profile = sprof;
336         ret = 1;
337         goto done;
338       }
339     }
340   }
341 
342   ret = 1;
343 
344 done:
345   if (client_profiles) {
346     sk_SRTP_PROTECTION_PROFILE_free(client_profiles);
347   }
348 
349   return ret;
350 }
351 
ssl_add_serverhello_use_srtp_ext(SSL * s,unsigned char * p,int * len,int maxlen)352 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
353                                      int maxlen) {
354   if (p) {
355     if (maxlen < 5) {
356       OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
357                         SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
358       return 0;
359     }
360 
361     if (s->srtp_profile == 0) {
362       OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
363                         SSL_R_USE_SRTP_NOT_NEGOTIATED);
364       return 0;
365     }
366 
367     s2n(2, p);
368     s2n(s->srtp_profile->id, p);
369     *p++ = 0;
370   }
371 
372   *len = 5;
373 
374   return 1;
375 }
376 
ssl_parse_serverhello_use_srtp_ext(SSL * s,CBS * cbs,int * out_alert)377 int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
378   CBS profile_ids, srtp_mki;
379   uint16_t profile_id;
380   size_t i;
381 
382   STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles;
383   const SRTP_PROTECTION_PROFILE *prof;
384 
385   /* The extension consists of a u16-prefixed profile ID list containing a
386    * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
387    *
388    * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
389   if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
390       !CBS_get_u16(&profile_ids, &profile_id) || CBS_len(&profile_ids) != 0 ||
391       !CBS_get_u8_length_prefixed(cbs, &srtp_mki) || CBS_len(cbs) != 0) {
392     OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
393                       SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
394     *out_alert = SSL_AD_DECODE_ERROR;
395     return 0;
396   }
397 
398   if (CBS_len(&srtp_mki) != 0) {
399     /* Must be no MKI, since we never offer one. */
400     OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
401                       SSL_R_BAD_SRTP_MKI_VALUE);
402     *out_alert = SSL_AD_ILLEGAL_PARAMETER;
403     return 0;
404   }
405 
406   client_profiles = SSL_get_srtp_profiles(s);
407 
408   /* Throw an error if the server gave us an unsolicited extension */
409   if (client_profiles == NULL) {
410     OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
411                       SSL_R_NO_SRTP_PROFILES);
412     *out_alert = SSL_AD_DECODE_ERROR;
413     return 0;
414   }
415 
416   /* Check to see if the server gave us something we support
417      (and presumably offered). */
418   for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); i++) {
419     prof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, i);
420 
421     if (prof->id == profile_id) {
422       s->srtp_profile = prof;
423       *out_alert = 0;
424       return 1;
425     }
426   }
427 
428   OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
429                     SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
430   *out_alert = SSL_AD_ILLEGAL_PARAMETER;
431   return 0;
432 }
433