diff options
author | doug <> | 2017-08-27 02:58:04 +0000 |
---|---|---|
committer | doug <> | 2017-08-27 02:58:04 +0000 |
commit | 6c75fbeb689a4a6974cf8563cfed0607f7f765f0 (patch) | |
tree | af98c801c4a8cf65f19c593a6d95424d151a7e8b /src/lib/libssl/d1_srtp.c | |
parent | 69baf63b5056297bd9125ea95453d12c33f78e64 (diff) | |
download | openbsd-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.c | 220 |
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 | ||
141 | static int | 141 | int |
142 | find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr, | 142 | srtp_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 | ||
161 | static int | 161 | int |
162 | find_profile_by_num(unsigned profile_num, SRTP_PROTECTION_PROFILE **pptr) | 162 | srtp_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 */ | ||
251 | int | ||
252 | ssl_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 | |||
291 | int | ||
292 | ssl_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 | |||
365 | done: | ||
366 | sk_SRTP_PROTECTION_PROFILE_free(clnt); | ||
367 | |||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | int | ||
372 | ssl_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 | |||
394 | int | ||
395 | ssl_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 |