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 | |
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')
-rw-r--r-- | src/lib/libssl/d1_srtp.c | 220 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 11 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 224 | ||||
-rw-r--r-- | src/lib/libssl/ssl_tlsext.h | 11 | ||||
-rw-r--r-- | src/lib/libssl/t1_lib.c | 58 |
5 files changed, 250 insertions, 274 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 |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 624df9c929..e789a4ae27 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.191 2017/08/26 20:23:46 doug Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.192 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 | * |
@@ -1348,6 +1348,15 @@ void tls1_get_formatlist(SSL *s, int client_formats, const uint8_t **pformats, | |||
1348 | void tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, | 1348 | void tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves, |
1349 | size_t *pcurveslen); | 1349 | size_t *pcurveslen); |
1350 | 1350 | ||
1351 | #ifndef OPENSSL_NO_SRTP | ||
1352 | |||
1353 | int srtp_find_profile_by_name(char *profile_name, | ||
1354 | SRTP_PROTECTION_PROFILE **pptr, unsigned len); | ||
1355 | int srtp_find_profile_by_num(unsigned profile_num, | ||
1356 | SRTP_PROTECTION_PROFILE **pptr); | ||
1357 | |||
1358 | #endif /* OPENSSL_NO_SRTP */ | ||
1359 | |||
1351 | __END_HIDDEN_DECLS | 1360 | __END_HIDDEN_DECLS |
1352 | 1361 | ||
1353 | #endif | 1362 | #endif |
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 405882c0e9..2438b90d04 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.c,v 1.11 2017/08/26 20:23:46 doug Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.12 2017/08/27 02:58:04 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -704,6 +704,7 @@ tlsext_sni_serverhello_parse(SSL *s, CBS *cbs, int *alert) | |||
704 | return 1; | 704 | return 1; |
705 | } | 705 | } |
706 | 706 | ||
707 | |||
707 | /* | 708 | /* |
708 | *Certificate Status Request - RFC 6066 section 8. | 709 | *Certificate Status Request - RFC 6066 section 8. |
709 | */ | 710 | */ |
@@ -983,6 +984,216 @@ tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert) | |||
983 | return 1; | 984 | return 1; |
984 | } | 985 | } |
985 | 986 | ||
987 | /* | ||
988 | * DTLS extension for SRTP key establishment - RFC 5764 | ||
989 | */ | ||
990 | |||
991 | #ifndef OPENSSL_NO_SRTP | ||
992 | |||
993 | int | ||
994 | tlsext_srtp_clienthello_needs(SSL *s) | ||
995 | { | ||
996 | return SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) != NULL; | ||
997 | } | ||
998 | |||
999 | int | ||
1000 | tlsext_srtp_clienthello_build(SSL *s, CBB *cbb) | ||
1001 | { | ||
1002 | CBB profiles, mki; | ||
1003 | int ct, i; | ||
1004 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL; | ||
1005 | SRTP_PROTECTION_PROFILE *prof; | ||
1006 | |||
1007 | if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { | ||
1008 | SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); | ||
1009 | return 0; | ||
1010 | } | ||
1011 | |||
1012 | if ((ct = sk_SRTP_PROTECTION_PROFILE_num(clnt)) < 1) { | ||
1013 | SSLerror(s, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | if (!CBB_add_u16_length_prefixed(cbb, &profiles)) | ||
1018 | return 0; | ||
1019 | |||
1020 | for (i = 0; i < ct; i++) { | ||
1021 | if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) == NULL) | ||
1022 | return 0; | ||
1023 | if (!CBB_add_u16(&profiles, prof->id)) | ||
1024 | return 0; | ||
1025 | } | ||
1026 | |||
1027 | if (!CBB_add_u8_length_prefixed(cbb, &mki)) | ||
1028 | return 0; | ||
1029 | |||
1030 | if (!CBB_flush(cbb)) | ||
1031 | return 0; | ||
1032 | |||
1033 | return 1; | ||
1034 | } | ||
1035 | |||
1036 | int | ||
1037 | tlsext_srtp_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
1038 | { | ||
1039 | SRTP_PROTECTION_PROFILE *cprof, *sprof; | ||
1040 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = NULL, *srvr; | ||
1041 | int i, j; | ||
1042 | int ret; | ||
1043 | uint16_t id; | ||
1044 | CBS profiles, mki; | ||
1045 | |||
1046 | ret = 0; | ||
1047 | |||
1048 | if (!CBS_get_u16_length_prefixed(cbs, &profiles)) | ||
1049 | goto err; | ||
1050 | if (CBS_len(&profiles) == 0 || CBS_len(&profiles) % 2 != 0) | ||
1051 | goto err; | ||
1052 | |||
1053 | if ((clnt = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) | ||
1054 | goto err; | ||
1055 | |||
1056 | while (CBS_len(&profiles) > 0) { | ||
1057 | if (!CBS_get_u16(&profiles, &id)) | ||
1058 | goto err; | ||
1059 | |||
1060 | if (!srtp_find_profile_by_num(id, &cprof)) { | ||
1061 | if (!sk_SRTP_PROTECTION_PROFILE_push(clnt, cprof)) | ||
1062 | goto err; | ||
1063 | } | ||
1064 | } | ||
1065 | |||
1066 | if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { | ||
1067 | SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); | ||
1068 | *alert = SSL_AD_DECODE_ERROR; | ||
1069 | goto done; | ||
1070 | } | ||
1071 | if (CBS_len(cbs) != 0) | ||
1072 | goto err; | ||
1073 | |||
1074 | /* | ||
1075 | * Per RFC 5764 section 4.1.1 | ||
1076 | * | ||
1077 | * Find the server preferred profile using the client's list. | ||
1078 | * | ||
1079 | * The server MUST send a profile if it sends the use_srtp | ||
1080 | * extension. If one is not found, it should fall back to the | ||
1081 | * negotiated DTLS cipher suite or return a DTLS alert. | ||
1082 | */ | ||
1083 | if ((srvr = SSL_get_srtp_profiles(s)) == NULL) | ||
1084 | goto err; | ||
1085 | for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(srvr); i++) { | ||
1086 | if ((sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i)) | ||
1087 | == NULL) | ||
1088 | goto err; | ||
1089 | |||
1090 | for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(clnt); j++) { | ||
1091 | if ((cprof = sk_SRTP_PROTECTION_PROFILE_value(clnt, j)) | ||
1092 | == NULL) | ||
1093 | goto err; | ||
1094 | |||
1095 | if (cprof->id == sprof->id) { | ||
1096 | s->internal->srtp_profile = sprof; | ||
1097 | ret = 1; | ||
1098 | goto done; | ||
1099 | } | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | /* If we didn't find anything, fall back to the negotiated */ | ||
1104 | ret = 1; | ||
1105 | goto done; | ||
1106 | |||
1107 | err: | ||
1108 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
1109 | *alert = SSL_AD_DECODE_ERROR; | ||
1110 | |||
1111 | done: | ||
1112 | sk_SRTP_PROTECTION_PROFILE_free(clnt); | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | int | ||
1117 | tlsext_srtp_serverhello_needs(SSL *s) | ||
1118 | { | ||
1119 | return SSL_IS_DTLS(s) && SSL_get_selected_srtp_profile(s) != NULL; | ||
1120 | } | ||
1121 | |||
1122 | int | ||
1123 | tlsext_srtp_serverhello_build(SSL *s, CBB *cbb) | ||
1124 | { | ||
1125 | SRTP_PROTECTION_PROFILE *profile; | ||
1126 | CBB srtp, mki; | ||
1127 | |||
1128 | if (!CBB_add_u16_length_prefixed(cbb, &srtp)) | ||
1129 | return 0; | ||
1130 | |||
1131 | if ((profile = SSL_get_selected_srtp_profile(s)) == NULL) | ||
1132 | return 0; | ||
1133 | |||
1134 | if (!CBB_add_u16(&srtp, profile->id)) | ||
1135 | return 0; | ||
1136 | |||
1137 | if (!CBB_add_u8_length_prefixed(cbb, &mki)) | ||
1138 | return 0; | ||
1139 | |||
1140 | if (!CBB_flush(cbb)) | ||
1141 | return 0; | ||
1142 | |||
1143 | return 1; | ||
1144 | } | ||
1145 | |||
1146 | int | ||
1147 | tlsext_srtp_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
1148 | { | ||
1149 | STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; | ||
1150 | SRTP_PROTECTION_PROFILE *prof; | ||
1151 | int i; | ||
1152 | uint16_t id; | ||
1153 | CBS profile_ids, mki; | ||
1154 | |||
1155 | if (!CBS_get_u16_length_prefixed(cbs, &profile_ids)) { | ||
1156 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
1157 | goto err; | ||
1158 | } | ||
1159 | |||
1160 | if (!CBS_get_u16(&profile_ids, &id) || CBS_len(&profile_ids) != 0) { | ||
1161 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
1162 | goto err; | ||
1163 | } | ||
1164 | |||
1165 | if (!CBS_get_u8_length_prefixed(cbs, &mki) || CBS_len(&mki) != 0) { | ||
1166 | SSLerror(s, SSL_R_BAD_SRTP_MKI_VALUE); | ||
1167 | *alert = SSL_AD_ILLEGAL_PARAMETER; | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | if ((clnt = SSL_get_srtp_profiles(s)) == NULL) { | ||
1172 | SSLerror(s, SSL_R_NO_SRTP_PROFILES); | ||
1173 | goto err; | ||
1174 | } | ||
1175 | |||
1176 | for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { | ||
1177 | if ((prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i)) | ||
1178 | == NULL) { | ||
1179 | SSLerror(s, SSL_R_NO_SRTP_PROFILES); | ||
1180 | goto err; | ||
1181 | } | ||
1182 | |||
1183 | if (prof->id == id) { | ||
1184 | s->internal->srtp_profile = prof; | ||
1185 | return 1; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | SSLerror(s, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); | ||
1190 | err: | ||
1191 | *alert = SSL_AD_DECODE_ERROR; | ||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | #endif /* OPENSSL_NO_SRTP */ | ||
1196 | |||
986 | struct tls_extension { | 1197 | struct tls_extension { |
987 | uint16_t type; | 1198 | uint16_t type; |
988 | int (*clienthello_needs)(SSL *s); | 1199 | int (*clienthello_needs)(SSL *s); |
@@ -1066,6 +1277,17 @@ static struct tls_extension tls_extensions[] = { | |||
1066 | .serverhello_build = tlsext_alpn_serverhello_build, | 1277 | .serverhello_build = tlsext_alpn_serverhello_build, |
1067 | .serverhello_parse = tlsext_alpn_serverhello_parse, | 1278 | .serverhello_parse = tlsext_alpn_serverhello_parse, |
1068 | }, | 1279 | }, |
1280 | #ifndef OPENSSL_NO_SRTP | ||
1281 | { | ||
1282 | .type = TLSEXT_TYPE_use_srtp, | ||
1283 | .clienthello_needs = tlsext_srtp_clienthello_needs, | ||
1284 | .clienthello_build = tlsext_srtp_clienthello_build, | ||
1285 | .clienthello_parse = tlsext_srtp_clienthello_parse, | ||
1286 | .serverhello_needs = tlsext_srtp_serverhello_needs, | ||
1287 | .serverhello_build = tlsext_srtp_serverhello_build, | ||
1288 | .serverhello_parse = tlsext_srtp_serverhello_parse, | ||
1289 | } | ||
1290 | #endif /* OPENSSL_NO_SRTP */ | ||
1069 | }; | 1291 | }; |
1070 | 1292 | ||
1071 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 1293 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |
diff --git a/src/lib/libssl/ssl_tlsext.h b/src/lib/libssl/ssl_tlsext.h index 21f9bb1bf9..7c6250a7f7 100644 --- a/src/lib/libssl/ssl_tlsext.h +++ b/src/lib/libssl/ssl_tlsext.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.h,v 1.9 2017/08/26 20:23:46 doug Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.h,v 1.10 2017/08/27 02:58:04 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
@@ -72,6 +72,15 @@ int tlsext_sessionticket_serverhello_needs(SSL *s); | |||
72 | int tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb); | 72 | int tlsext_sessionticket_serverhello_build(SSL *s, CBB *cbb); |
73 | int tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert); | 73 | int tlsext_sessionticket_serverhello_parse(SSL *s, CBS *cbs, int *alert); |
74 | 74 | ||
75 | #ifndef OPENSSL_NO_SRTP | ||
76 | int tlsext_srtp_clienthello_needs(SSL *s); | ||
77 | int tlsext_srtp_clienthello_build(SSL *s, CBB *cbb); | ||
78 | int tlsext_srtp_clienthello_parse(SSL *s, CBS *cbs, int *alert); | ||
79 | int tlsext_srtp_serverhello_needs(SSL *s); | ||
80 | int tlsext_srtp_serverhello_build(SSL *s, CBB *cbb); | ||
81 | int tlsext_srtp_serverhello_parse(SSL *s, CBS *cbs, int *alert); | ||
82 | #endif | ||
83 | |||
75 | int tlsext_clienthello_build(SSL *s, CBB *cbb); | 84 | int tlsext_clienthello_build(SSL *s, CBB *cbb); |
76 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, | 85 | int tlsext_clienthello_parse_one(SSL *s, CBS *cbs, uint16_t tlsext_type, |
77 | int *alert); | 86 | int *alert); |
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index eb1d96cc11..a9f10166fe 100644 --- a/src/lib/libssl/t1_lib.c +++ b/src/lib/libssl/t1_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: t1_lib.c,v 1.135 2017/08/26 20:23:46 doug Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.136 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 | * |
@@ -687,26 +687,6 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
687 | return NULL; | 687 | return NULL; |
688 | ret += len; | 688 | ret += len; |
689 | 689 | ||
690 | #ifndef OPENSSL_NO_SRTP | ||
691 | if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { | ||
692 | int el; | ||
693 | |||
694 | ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); | ||
695 | |||
696 | if ((size_t)(limit - ret) < 4 + el) | ||
697 | return NULL; | ||
698 | |||
699 | s2n(TLSEXT_TYPE_use_srtp, ret); | ||
700 | s2n(el, ret); | ||
701 | |||
702 | if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { | ||
703 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
704 | return NULL; | ||
705 | } | ||
706 | ret += el; | ||
707 | } | ||
708 | #endif | ||
709 | |||
710 | if ((extdatalen = ret - p - 2) == 0) | 690 | if ((extdatalen = ret - p - 2) == 0) |
711 | return p; | 691 | return p; |
712 | 692 | ||
@@ -745,26 +725,6 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) | |||
745 | * extension. | 725 | * extension. |
746 | */ | 726 | */ |
747 | 727 | ||
748 | #ifndef OPENSSL_NO_SRTP | ||
749 | if (SSL_IS_DTLS(s) && s->internal->srtp_profile) { | ||
750 | int el; | ||
751 | |||
752 | ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); | ||
753 | |||
754 | if ((size_t)(limit - ret) < 4 + el) | ||
755 | return NULL; | ||
756 | |||
757 | s2n(TLSEXT_TYPE_use_srtp, ret); | ||
758 | s2n(el, ret); | ||
759 | |||
760 | if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { | ||
761 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
762 | return NULL; | ||
763 | } | ||
764 | ret += el; | ||
765 | } | ||
766 | #endif | ||
767 | |||
768 | if ((extdatalen = ret - p - 2) == 0) | 728 | if ((extdatalen = ret - p - 2) == 0) |
769 | return p; | 729 | return p; |
770 | 730 | ||
@@ -815,14 +775,6 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, | |||
815 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) | 775 | if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) |
816 | return 0; | 776 | return 0; |
817 | 777 | ||
818 | /* session ticket processed earlier */ | ||
819 | #ifndef OPENSSL_NO_SRTP | ||
820 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { | ||
821 | if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) | ||
822 | return 0; | ||
823 | } | ||
824 | #endif | ||
825 | |||
826 | data += size; | 778 | data += size; |
827 | } | 779 | } |
828 | 780 | ||
@@ -888,14 +840,6 @@ ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, size_t n, int *al) | |||
888 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) | 840 | if (!tlsext_serverhello_parse_one(s, &cbs, type, al)) |
889 | return 0; | 841 | return 0; |
890 | 842 | ||
891 | #ifndef OPENSSL_NO_SRTP | ||
892 | else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { | ||
893 | if (ssl_parse_serverhello_use_srtp_ext(s, data, | ||
894 | size, al)) | ||
895 | return 0; | ||
896 | } | ||
897 | #endif | ||
898 | |||
899 | data += size; | 843 | data += size; |
900 | 844 | ||
901 | } | 845 | } |