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