Simplify ssl_cert_type() by taking advantage of X509_get0_pubkey
[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     *out = profiles;
201
202     return 0;
203 }
204
205 int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
206 {
207     return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
208 }
209
210 int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
211 {
212     return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
213 }
214
215 STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
216 {
217     if (s != NULL) {
218         if (s->srtp_profiles != NULL) {
219             return s->srtp_profiles;
220         } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) {
221             return s->ctx->srtp_profiles;
222         }
223     }
224
225     return NULL;
226 }
227
228 SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
229 {
230     return s->srtp_profile;
231 }
232
233 /*
234  * Note: this function returns 0 length if there are no profiles specified
235  */
236 int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
237                                      int maxlen)
238 {
239     int ct = 0;
240     int i;
241     STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
242     SRTP_PROTECTION_PROFILE *prof;
243
244     clnt = SSL_get_srtp_profiles(s);
245     ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
246
247     if (p) {
248         if (ct == 0) {
249             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
250                    SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
251             return 1;
252         }
253
254         if ((2 + ct * 2 + 1) > maxlen) {
255             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
256                    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
257             return 1;
258         }
259
260         /* Add the length */
261         s2n(ct * 2, p);
262         for (i = 0; i < ct; i++) {
263             prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
264             s2n(prof->id, p);
265         }
266
267         /* Add an empty use_mki value */
268         *p++ = 0;
269     }
270
271     *len = 2 + ct * 2 + 1;
272
273     return 0;
274 }
275
276 int ssl_parse_clienthello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
277 {
278     SRTP_PROTECTION_PROFILE *sprof;
279     STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
280     unsigned int ct, mki_len, id;
281     int i, srtp_pref;
282     PACKET subpkt;
283
284     /* Pull off the length of the cipher suite list  and check it is even */
285     if (!PACKET_get_net_2(pkt, &ct)
286             || (ct & 1) != 0
287             || !PACKET_get_sub_packet(pkt, &subpkt, ct)) {
288         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
289                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
290         *al = SSL_AD_DECODE_ERROR;
291         return 1;
292     }
293
294     srvr = SSL_get_srtp_profiles(s);
295     s->srtp_profile = NULL;
296     /* Search all profiles for a match initially */
297     srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
298
299     while (PACKET_remaining(&subpkt)) {
300         if (!PACKET_get_net_2(&subpkt, &id)) {
301             SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
302                    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
303             *al = SSL_AD_DECODE_ERROR;
304             return 1;
305         }
306
307         /*
308          * Only look for match in profiles of higher preference than
309          * current match.
310          * If no profiles have been have been configured then this
311          * does nothing.
312          */
313         for (i = 0; i < srtp_pref; i++) {
314             sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
315             if (sprof->id == id) {
316                 s->srtp_profile = sprof;
317                 srtp_pref = i;
318                 break;
319             }
320         }
321     }
322
323     /*
324      * Now extract the MKI value as a sanity check, but discard it for now
325      */
326     if (!PACKET_get_1(pkt, &mki_len)) {
327         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
328                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
329         *al = SSL_AD_DECODE_ERROR;
330         return 1;
331     }
332
333     if (!PACKET_forward(pkt, mki_len)
334             || PACKET_remaining(pkt)) {
335         SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
336                SSL_R_BAD_SRTP_MKI_VALUE);
337         *al = SSL_AD_DECODE_ERROR;
338         return 1;
339     }
340
341     return 0;
342 }
343
344 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
345                                      int maxlen)
346 {
347     if (p) {
348         if (maxlen < 5) {
349             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
350                    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
351             return 1;
352         }
353
354         if (s->srtp_profile == 0) {
355             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
356                    SSL_R_USE_SRTP_NOT_NEGOTIATED);
357             return 1;
358         }
359         s2n(2, p);
360         s2n(s->srtp_profile->id, p);
361         *p++ = 0;
362     }
363     *len = 5;
364
365     return 0;
366 }
367
368 int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
369 {
370     unsigned int id, ct, mki;
371     int i;
372
373     STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
374     SRTP_PROTECTION_PROFILE *prof;
375
376     if (!PACKET_get_net_2(pkt, &ct)
377             || ct != 2
378             || !PACKET_get_net_2(pkt, &id)
379             || !PACKET_get_1(pkt, &mki)
380             || PACKET_remaining(pkt) != 0) {
381         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
382                SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
383         *al = SSL_AD_DECODE_ERROR;
384         return 1;
385     }
386
387     if (mki != 0) {
388         /* Must be no MKI, since we never offer one */
389         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
390                SSL_R_BAD_SRTP_MKI_VALUE);
391         *al = SSL_AD_ILLEGAL_PARAMETER;
392         return 1;
393     }
394
395     clnt = SSL_get_srtp_profiles(s);
396
397     /* Throw an error if the server gave us an unsolicited extension */
398     if (clnt == NULL) {
399         SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
400                SSL_R_NO_SRTP_PROFILES);
401         *al = SSL_AD_DECODE_ERROR;
402         return 1;
403     }
404
405     /*
406      * Check to see if the server gave us something we support (and
407      * presumably offered)
408      */
409     for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
410         prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
411
412         if (prof->id == id) {
413             s->srtp_profile = prof;
414             *al = 0;
415             return 0;
416         }
417     }
418
419     SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
420            SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
421     *al = SSL_AD_DECODE_ERROR;
422     return 1;
423 }
424
425 #endif