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