xref: /dragonfly/crypto/libressl/ssl/d1_srtp.c (revision f5b1c8a1)
1 /* $OpenBSD: d1_srtp.c,v 1.14 2015/07/17 17:36:24 doug Exp $ */
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.
115  * Copyright (C) 2011, RTFM, Inc.
116  */
117 
118 #include <stdio.h>
119 
120 #include <openssl/objects.h>
121 
122 #include "ssl_locl.h"
123 
124 #ifndef OPENSSL_NO_SRTP
125 
126 #include "bytestring.h"
127 #include "srtp.h"
128 
129 static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
130 	{
131 		"SRTP_AES128_CM_SHA1_80",
132 		SRTP_AES128_CM_SHA1_80,
133 	},
134 	{
135 		"SRTP_AES128_CM_SHA1_32",
136 		SRTP_AES128_CM_SHA1_32,
137 	},
138 	{0}
139 };
140 
141 static int
142 find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
143     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)) {
151 			*pptr = p;
152 			return 0;
153 		}
154 
155 		p++;
156 	}
157 
158 	return 1;
159 }
160 
161 static int
162 find_profile_by_num(unsigned profile_num, SRTP_PROTECTION_PROFILE **pptr)
163 {
164 	SRTP_PROTECTION_PROFILE *p;
165 
166 	p = srtp_known_profiles;
167 	while (p->name) {
168 		if (p->id == profile_num) {
169 			*pptr = p;
170 			return 0;
171 		}
172 		p++;
173 	}
174 
175 	return 1;
176 }
177 
178 static int
179 ssl_ctx_make_profiles(const char *profiles_string,
180     STACK_OF(SRTP_PROTECTION_PROFILE) **out)
181 {
182 	STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
183 
184 	char *col;
185 	char *ptr = (char *)profiles_string;
186 
187 	SRTP_PROTECTION_PROFILE *p;
188 
189 	if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) {
190 		SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
191 		    SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
192 		return 1;
193 	}
194 
195 	do {
196 		col = strchr(ptr, ':');
197 
198 		if (!find_profile_by_name(ptr, &p,
199 		    col ? col - ptr : (int)strlen(ptr))) {
200 			sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
201 		} else {
202 			SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
203 			    SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
204 			sk_SRTP_PROTECTION_PROFILE_free(profiles);
205 			return 1;
206 		}
207 
208 		if (col)
209 			ptr = col + 1;
210 	} while (col);
211 
212 	*out = profiles;
213 
214 	return 0;
215 }
216 
217 int
218 SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
219 {
220 	return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
221 }
222 
223 int
224 SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
225 {
226 	return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
227 }
228 
229 
230 STACK_OF(SRTP_PROTECTION_PROFILE) *
231 SSL_get_srtp_profiles(SSL *s)
232 {
233 	if (s != NULL) {
234 		if (s->srtp_profiles != NULL) {
235 			return s->srtp_profiles;
236 		} else if ((s->ctx != NULL) &&
237 		    (s->ctx->srtp_profiles != NULL)) {
238 			return s->ctx->srtp_profiles;
239 		}
240 	}
241 
242 	return NULL;
243 }
244 
245 SRTP_PROTECTION_PROFILE *
246 SSL_get_selected_srtp_profile(SSL *s)
247 {
248 	return s->srtp_profile;
249 }
250 
251 /* Note: this function returns 0 length if there are no
252    profiles specified */
253 int
254 ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
255 {
256 	int ct = 0;
257 	int i;
258 	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
259 	SRTP_PROTECTION_PROFILE *prof;
260 
261 	clnt = SSL_get_srtp_profiles(s);
262 
263 	ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
264 
265 	if (p) {
266 		if (ct == 0) {
267 			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
268 			    SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
269 			return 1;
270 		}
271 
272 		if ((2 + ct * 2 + 1) > maxlen) {
273 			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
274 			    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
275 			return 1;
276 		}
277 
278 		/* Add the length */
279 		s2n(ct * 2, p);
280 		for (i = 0; i < ct; i++) {
281 			prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
282 			s2n(prof->id, p);
283 		}
284 
285 		/* Add an empty use_mki value */
286 		*p++ = 0;
287 	}
288 
289 	*len = 2 + ct*2 + 1;
290 
291 	return 0;
292 }
293 
294 
295 int
296 ssl_parse_clienthello_use_srtp_ext(SSL *s, const unsigned char *d, int len,
297     int *al)
298 {
299 	SRTP_PROTECTION_PROFILE *cprof, *sprof;
300 	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0, *srvr;
301 	int i, j;
302 	int ret = 1;
303 	uint16_t id;
304 	CBS cbs, ciphers, mki;
305 
306 	if (len < 0) {
307 		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
308 		    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
309 		*al = SSL_AD_DECODE_ERROR;
310 		goto done;
311 	}
312 
313 	CBS_init(&cbs, d, len);
314 	/* Pull off the cipher suite list */
315 	if (!CBS_get_u16_length_prefixed(&cbs, &ciphers) ||
316 	    CBS_len(&ciphers) % 2) {
317 		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
318 		    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
319 		*al = SSL_AD_DECODE_ERROR;
320 		goto done;
321 	}
322 
323 	clnt = sk_SRTP_PROTECTION_PROFILE_new_null();
324 
325 	while (CBS_len(&ciphers) > 0) {
326 		if (!CBS_get_u16(&ciphers, &id)) {
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 			goto done;
331 		}
332 
333 		if (!find_profile_by_num(id, &cprof))
334 			sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof);
335 		else
336 			; /* Ignore */
337 	}
338 
339 	/* Extract the MKI value as a sanity check, but discard it for now. */
340 	if (!CBS_get_u8_length_prefixed(&cbs, &mki) ||
341 	    CBS_len(&cbs) != 0) {
342 		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
343 		    SSL_R_BAD_SRTP_MKI_VALUE);
344 		*al = SSL_AD_DECODE_ERROR;
345 		goto done;
346 	}
347 
348 	srvr = SSL_get_srtp_profiles(s);
349 
350 	/*
351 	 * Pick our most preferred profile. If no profiles have been
352 	 * configured then the outer loop doesn't run
353 	 * (sk_SRTP_PROTECTION_PROFILE_num() = -1)
354 	 * and so we just return without doing anything.
355 	 */
356 	for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) {
357 		sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
358 
359 		for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) {
360 			cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j);
361 
362 			if (cprof->id == sprof->id) {
363 				s->srtp_profile = sprof;
364 				*al = 0;
365 				ret = 0;
366 				goto done;
367 			}
368 		}
369 	}
370 
371 	ret = 0;
372 
373 done:
374 	if (clnt)
375 		sk_SRTP_PROTECTION_PROFILE_free(clnt);
376 
377 	return ret;
378 }
379 
380 int
381 ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
382 {
383 	if (p) {
384 		if (maxlen < 5) {
385 			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
386 			    SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
387 			return 1;
388 		}
389 
390 		if (s->srtp_profile == 0) {
391 			SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
392 			    SSL_R_USE_SRTP_NOT_NEGOTIATED);
393 			return 1;
394 		}
395 		s2n(2, p);
396 		s2n(s->srtp_profile->id, p);
397 		*p++ = 0;
398 	}
399 	*len = 5;
400 
401 	return 0;
402 }
403 
404 
405 int
406 ssl_parse_serverhello_use_srtp_ext(SSL *s, const unsigned char *d, int len, int *al)
407 {
408 	STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
409 	SRTP_PROTECTION_PROFILE *prof;
410 	int i;
411 	uint16_t id;
412 	CBS cbs, profile_ids, mki;
413 
414 	if (len < 0) {
415 		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
416 		    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
417 		*al = SSL_AD_DECODE_ERROR;
418 		return 1;
419 	}
420 
421 	CBS_init(&cbs, d, len);
422 
423 	/*
424 	 * As per RFC 5764 section 4.1.1, server response MUST be a single
425 	 * profile id.
426 	 */
427 	if (!CBS_get_u16_length_prefixed(&cbs, &profile_ids) ||
428 	    !CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) {
429 		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
430 		    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
431 		*al = SSL_AD_DECODE_ERROR;
432 		return 1;
433 	}
434 
435 	/* Must be no MKI, since we never offer one. */
436 	if (!CBS_get_u8_length_prefixed(&cbs, &mki) || CBS_len(&mki) != 0) {
437 		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
438 		    SSL_R_BAD_SRTP_MKI_VALUE);
439 		*al = SSL_AD_ILLEGAL_PARAMETER;
440 		return 1;
441 	}
442 
443 	clnt = SSL_get_srtp_profiles(s);
444 
445 	/* Throw an error if the server gave us an unsolicited extension. */
446 	if (clnt == NULL) {
447 		SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
448 		    SSL_R_NO_SRTP_PROFILES);
449 		*al = SSL_AD_DECODE_ERROR;
450 		return 1;
451 	}
452 
453 	/*
454 	 * Check to see if the server gave us something we support
455 	 * (and presumably offered).
456 	 */
457 	for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
458 		prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
459 
460 		if (prof->id == id) {
461 			s->srtp_profile = prof;
462 			*al = 0;
463 			return 0;
464 		}
465 	}
466 
467 	SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
468 	    SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
469 	*al = SSL_AD_DECODE_ERROR;
470 	return 1;
471 }
472 
473 #endif
474