Remove /* foo.c */ comments
[openssl.git] / ssl / d1_srtp.c
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. Copyright (C) 2011, RTFM, Inc.
114  */
115
116 #include <stdio.h>
117 #include <openssl/objects.h>
118 #include "ssl_locl.h"
119
120 #ifndef OPENSSL_NO_SRTP
121
122 static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
123     {
124      "SRTP_AES128_CM_SHA1_80",
125      SRTP_AES128_CM_SHA1_80,
126      },
127     {
128      "SRTP_AES128_CM_SHA1_32",
129      SRTP_AES128_CM_SHA1_32,
130      },
131     {0}
132 };
133
134 static int find_profile_by_name(char *profile_name,
135                                 SRTP_PROTECTION_PROFILE **pptr, unsigned len)
136 {
137     SRTP_PROTECTION_PROFILE *p;
138
139     p = srtp_known_profiles;
140     while (p->name) {
141         if ((len == strlen(p->name))
142             && strncmp(p->name, profile_name, len) == 0) {
143             *pptr = p;
144             return 0;
145         }
146
147         p++;
148     }
149
150     return 1;
151 }
152
153 static int ssl_ctx_make_profiles(const char *profiles_string,
154                                  STACK_OF(SRTP_PROTECTION_PROFILE) **out)
155 {
156     STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
157
158     char *col;
159     char *ptr = (char *)profiles_string;
160     SRTP_PROTECTION_PROFILE *p;
161
162     if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) {
163         SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
164                SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
165         return 1;
166     }
167
168     do {
169         col = strchr(ptr, ':');
170
171         if (!find_profile_by_name(ptr, &p,
172                                   col ? col - ptr : (int)strlen(ptr))) {
173             if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) {
174                 SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
175                        SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
176                 sk_SRTP_PROTECTION_PROFILE_free(profiles);
177                 return 1;
178             }
179
180             sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
181         } else {
182             SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
183                    SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
184             sk_SRTP_PROTECTION_PROFILE_free(profiles);
185             return 1;
186         }
187
188         if (col)
189             ptr = col + 1;
190     } while (col);
191
192     *out = profiles;
193
194     return 0;
195 }
196
197 int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
198 {
199     return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
200 }
201
202 int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
203 {
204     return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
205 }
206
207 STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
208 {
209     if (s != NULL) {
210         if (s->srtp_profiles != NULL) {
211             return s->srtp_profiles;
212         } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) {
213             return s->ctx->srtp_profiles;
214         }
215     }
216
217     return NULL;
218 }
219
220 SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
221 {
222     return s->srtp_profile;
223 }
224
225 /*
226  * Note: this function returns 0 length if there are no profiles specified
227  */
228 int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
229                                      int maxlen)
230 {
231     int ct = 0;
232     int i;
233     STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
234     SRTP_PROTECTION_PROFILE *prof;
235
236     clnt = SSL_get_srtp_profiles(s);
237     ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
238
239     if (p) {
240         if (ct == 0) {
241             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
242                    SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
243             return 1;
244         }
245
246         if ((2 + ct * 2 + 1) > maxlen) {
247             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
248                    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
249             return 1;
250         }
251
252         /* Add the length */
253         s2n(ct * 2, p);
254         for (i = 0; i < ct; i++) {
255             prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
256             s2n(prof->id, p);
257         }
258
259         /* Add an empty use_mki value */
260         *p++ = 0;
261     }
262
263     *len = 2 + ct * 2 + 1;
264
265     return 0;
266 }
267
268 int ssl_parse_clienthello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
269 {
270     SRTP_PROTECTION_PROFILE *sprof;
271     STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
272     unsigned int ct, mki_len, id;
273     int i, srtp_pref;
274     PACKET subpkt;
275
276     /* Pull off the length of the cipher suite list  and check it is even */
277     if (!PACKET_get_net_2(pkt, &ct)
278             || (ct & 1) != 0
279             || !PACKET_get_sub_packet(pkt, &subpkt, ct)) {
280         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
281                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
282         *al = SSL_AD_DECODE_ERROR;
283         return 1;
284     }
285
286     srvr = SSL_get_srtp_profiles(s);
287     s->srtp_profile = NULL;
288     /* Search all profiles for a match initially */
289     srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
290
291     while (PACKET_remaining(&subpkt)) {
292         if (!PACKET_get_net_2(&subpkt, &id)) {
293             SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
294                    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
295             *al = SSL_AD_DECODE_ERROR;
296             return 1;
297         }
298
299         /*
300          * Only look for match in profiles of higher preference than
301          * current match.
302          * If no profiles have been have been configured then this
303          * does nothing.
304          */
305         for (i = 0; i < srtp_pref; i++) {
306             sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
307             if (sprof->id == id) {
308                 s->srtp_profile = sprof;
309                 srtp_pref = i;
310                 break;
311             }
312         }
313     }
314
315     /*
316      * Now extract the MKI value as a sanity check, but discard it for now
317      */
318     if (!PACKET_get_1(pkt, &mki_len)) {
319         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
320                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
321         *al = SSL_AD_DECODE_ERROR;
322         return 1;
323     }
324
325     if (!PACKET_forward(pkt, mki_len)
326             || PACKET_remaining(pkt)) {
327         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
328                SSL_R_BAD_SRTP_MKI_VALUE);
329         *al = SSL_AD_DECODE_ERROR;
330         return 1;
331     }
332
333     return 0;
334 }
335
336 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
337                                      int maxlen)
338 {
339     if (p) {
340         if (maxlen < 5) {
341             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
342                    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
343             return 1;
344         }
345
346         if (s->srtp_profile == 0) {
347             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
348                    SSL_R_USE_SRTP_NOT_NEGOTIATED);
349             return 1;
350         }
351         s2n(2, p);
352         s2n(s->srtp_profile->id, p);
353         *p++ = 0;
354     }
355     *len = 5;
356
357     return 0;
358 }
359
360 int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
361 {
362     unsigned int id, ct, mki;
363     int i;
364
365     STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
366     SRTP_PROTECTION_PROFILE *prof;
367
368     if (!PACKET_get_net_2(pkt, &ct)
369             || ct != 2
370             || !PACKET_get_net_2(pkt, &id)
371             || !PACKET_get_1(pkt, &mki)
372             || PACKET_remaining(pkt) != 0) {
373         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
374                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
375         *al = SSL_AD_DECODE_ERROR;
376         return 1;
377     }
378
379     if (mki != 0) {
380         /* Must be no MKI, since we never offer one */
381         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
382                SSL_R_BAD_SRTP_MKI_VALUE);
383         *al = SSL_AD_ILLEGAL_PARAMETER;
384         return 1;
385     }
386
387     clnt = SSL_get_srtp_profiles(s);
388
389     /* Throw an error if the server gave us an unsolicited extension */
390     if (clnt == NULL) {
391         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
392                SSL_R_NO_SRTP_PROFILES);
393         *al = SSL_AD_DECODE_ERROR;
394         return 1;
395     }
396
397     /*
398      * Check to see if the server gave us something we support (and
399      * presumably offered)
400      */
401     for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
402         prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
403
404         if (prof->id == id) {
405             s->srtp_profile = prof;
406             *al = 0;
407             return 0;
408         }
409     }
410
411     SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
412            SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
413     *al = SSL_AD_DECODE_ERROR;
414     return 1;
415 }
416
417 #endif