summaryrefslogtreecommitdiff
path: root/src/lib/libssl/d1_srtp.c
diff options
context:
space:
mode:
authordoug <>2017-08-27 02:58:04 +0000
committerdoug <>2017-08-27 02:58:04 +0000
commit6c75fbeb689a4a6974cf8563cfed0607f7f765f0 (patch)
treeaf98c801c4a8cf65f19c593a6d95424d151a7e8b /src/lib/libssl/d1_srtp.c
parent69baf63b5056297bd9125ea95453d12c33f78e64 (diff)
downloadopenbsd-6c75fbeb689a4a6974cf8563cfed0607f7f765f0.tar.gz
openbsd-6c75fbeb689a4a6974cf8563cfed0607f7f765f0.tar.bz2
openbsd-6c75fbeb689a4a6974cf8563cfed0607f7f765f0.zip
Rewrite SRTP extension using CBB/CBS and the new extension framework.
input + ok beck@, jsing@
Diffstat (limited to 'src/lib/libssl/d1_srtp.c')
-rw-r--r--src/lib/libssl/d1_srtp.c220
1 files changed, 6 insertions, 214 deletions
diff --git a/src/lib/libssl/d1_srtp.c b/src/lib/libssl/d1_srtp.c
index 26c14543fc..eb1877a12c 100644
--- a/src/lib/libssl/d1_srtp.c
+++ b/src/lib/libssl/d1_srtp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: d1_srtp.c,v 1.21 2017/02/07 02:08:38 beck Exp $ */ 1/* $OpenBSD: d1_srtp.c,v 1.22 2017/08/27 02:58:04 doug Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -138,8 +138,8 @@ static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
138 {0} 138 {0}
139}; 139};
140 140
141static int 141int
142find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr, 142srtp_find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
143 unsigned len) 143 unsigned len)
144{ 144{
145 SRTP_PROTECTION_PROFILE *p; 145 SRTP_PROTECTION_PROFILE *p;
@@ -158,8 +158,8 @@ find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
158 return 1; 158 return 1;
159} 159}
160 160
161static int 161int
162find_profile_by_num(unsigned profile_num, SRTP_PROTECTION_PROFILE **pptr) 162srtp_find_profile_by_num(unsigned profile_num, SRTP_PROTECTION_PROFILE **pptr)
163{ 163{
164 SRTP_PROTECTION_PROFILE *p; 164 SRTP_PROTECTION_PROFILE *p;
165 165
@@ -194,7 +194,7 @@ ssl_ctx_make_profiles(const char *profiles_string,
194 do { 194 do {
195 col = strchr(ptr, ':'); 195 col = strchr(ptr, ':');
196 196
197 if (!find_profile_by_name(ptr, &p, 197 if (!srtp_find_profile_by_name(ptr, &p,
198 col ? col - ptr : (int)strlen(ptr))) { 198 col ? col - ptr : (int)strlen(ptr))) {
199 sk_SRTP_PROTECTION_PROFILE_push(profiles, p); 199 sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
200 } else { 200 } else {
@@ -246,212 +246,4 @@ SSL_get_selected_srtp_profile(SSL *s)
246 return s->internal->srtp_profile; 246 return s->internal->srtp_profile;
247} 247}
248 248
249/* Note: this function returns 0 length if there are no
250 profiles specified */
251int
252ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
253{
254 int ct = 0;
255 int i;
256 STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
257 SRTP_PROTECTION_PROFILE *prof;
258
259 clnt = SSL_get_srtp_profiles(s);
260
261 ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
262
263 if (p) {
264 if (ct == 0) {
265 SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
266 return 1;
267 }
268
269 if ((2 + ct * 2 + 1) > maxlen) {
270 SSLerror(s, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
271 return 1;
272 }
273
274 /* Add the length */
275 s2n(ct * 2, p);
276 for (i = 0; i < ct; i++) {
277 prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
278 s2n(prof->id, p);
279 }
280
281 /* Add an empty use_mki value */
282 *p++ = 0;
283 }
284
285 *len = 2 + ct*2 + 1;
286
287 return 0;
288}
289
290
291int
292ssl_parse_clienthello_use_srtp_ext(SSL *s, const unsigned char *d, int len,
293 int *al)
294{
295 SRTP_PROTECTION_PROFILE *cprof, *sprof;
296 STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0, *srvr;
297 int i, j;
298 int ret = 1;
299 uint16_t id;
300 CBS cbs, ciphers, mki;
301
302 if (len < 0) {
303 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
304 *al = SSL_AD_DECODE_ERROR;
305 goto done;
306 }
307
308 CBS_init(&cbs, d, len);
309 /* Pull off the cipher suite list */
310 if (!CBS_get_u16_length_prefixed(&cbs, &ciphers) ||
311 CBS_len(&ciphers) % 2) {
312 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
313 *al = SSL_AD_DECODE_ERROR;
314 goto done;
315 }
316
317 clnt = sk_SRTP_PROTECTION_PROFILE_new_null();
318
319 while (CBS_len(&ciphers) > 0) {
320 if (!CBS_get_u16(&ciphers, &id)) {
321 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
322 *al = SSL_AD_DECODE_ERROR;
323 goto done;
324 }
325
326 if (!find_profile_by_num(id, &cprof))
327 sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof);
328 else
329 ; /* Ignore */
330 }
331
332 /* Extract the MKI value as a sanity check, but discard it for now. */
333 if (!CBS_get_u8_length_prefixed(&cbs, &mki) ||
334 CBS_len(&cbs) != 0) {
335 SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE);
336 *al = SSL_AD_DECODE_ERROR;
337 goto done;
338 }
339
340 srvr = SSL_get_srtp_profiles(s);
341
342 /*
343 * Pick our most preferred profile. If no profiles have been
344 * configured then the outer loop doesn't run
345 * (sk_SRTP_PROTECTION_PROFILE_num() = -1)
346 * and so we just return without doing anything.
347 */
348 for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) {
349 sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
350
351 for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) {
352 cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j);
353
354 if (cprof->id == sprof->id) {
355 s->internal->srtp_profile = sprof;
356 *al = 0;
357 ret = 0;
358 goto done;
359 }
360 }
361 }
362
363 ret = 0;
364
365done:
366 sk_SRTP_PROTECTION_PROFILE_free(clnt);
367
368 return ret;
369}
370
371int
372ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
373{
374 if (p) {
375 if (maxlen < 5) {
376 SSLerror(s, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
377 return 1;
378 }
379
380 if (s->internal->srtp_profile == 0) {
381 SSLerror(s, SSL_R_USE_SRTP_NOT_NEGOTIATED);
382 return 1;
383 }
384 s2n(2, p);
385 s2n(s->internal->srtp_profile->id, p);
386 *p++ = 0;
387 }
388 *len = 5;
389
390 return 0;
391}
392
393
394int
395ssl_parse_serverhello_use_srtp_ext(SSL *s, const unsigned char *d, int len, int *al)
396{
397 STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
398 SRTP_PROTECTION_PROFILE *prof;
399 int i;
400 uint16_t id;
401 CBS cbs, profile_ids, mki;
402
403 if (len < 0) {
404 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
405 *al = SSL_AD_DECODE_ERROR;
406 return 1;
407 }
408
409 CBS_init(&cbs, d, len);
410
411 /*
412 * As per RFC 5764 section 4.1.1, server response MUST be a single
413 * profile id.
414 */
415 if (!CBS_get_u16_length_prefixed(&cbs, &profile_ids) ||
416 !CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) {
417 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
418 *al = SSL_AD_DECODE_ERROR;
419 return 1;
420 }
421
422 /* Must be no MKI, since we never offer one. */
423 if (!CBS_get_u8_length_prefixed(&cbs, &mki) || CBS_len(&mki) != 0) {
424 SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE);
425 *al = SSL_AD_ILLEGAL_PARAMETER;
426 return 1;
427 }
428
429 clnt = SSL_get_srtp_profiles(s);
430
431 /* Throw an error if the server gave us an unsolicited extension. */
432 if (clnt == NULL) {
433 SSLerror(s, SSL_R_NO_SRTP_PROFILES);
434 *al = SSL_AD_DECODE_ERROR;
435 return 1;
436 }
437
438 /*
439 * Check to see if the server gave us something we support
440 * (and presumably offered).
441 */
442 for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
443 prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
444
445 if (prof->id == id) {
446 s->internal->srtp_profile = prof;
447 *al = 0;
448 return 0;
449 }
450 }
451
452 SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
453 *al = SSL_AD_DECODE_ERROR;
454 return 1;
455}
456
457#endif 249#endif