diff options
Diffstat (limited to '')
| -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 | ||||
| -rw-r--r-- | src/regress/lib/libssl/tlsext/tlsexttest.c | 403 |
6 files changed, 652 insertions, 275 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 | } |
diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c index d3858e4c50..1b2820d78b 100644 --- a/src/regress/lib/libssl/tlsext/tlsexttest.c +++ b/src/regress/lib/libssl/tlsext/tlsexttest.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tlsexttest.c,v 1.14 2017/08/27 02:17:51 beck Exp $ */ | 1 | /* $OpenBSD: tlsexttest.c,v 1.15 2017/08/27 02:58:04 doug Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2017 Joel Sing <jsing@openbsd.org> |
| 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> | 4 | * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> |
| @@ -2257,6 +2257,400 @@ test_tlsext_sessionticket_serverhello(void) | |||
| 2257 | return (failure); | 2257 | return (failure); |
| 2258 | } | 2258 | } |
| 2259 | 2259 | ||
| 2260 | #ifndef OPENSSL_NO_SRTP | ||
| 2261 | /* | ||
| 2262 | * Supported Secure Real-time Transport Protocol (RFC 5764 section 4.1.1) | ||
| 2263 | */ | ||
| 2264 | |||
| 2265 | /* Colon separated string values */ | ||
| 2266 | const char *tlsext_srtp_single_profile = "SRTP_AES128_CM_SHA1_80"; | ||
| 2267 | const char *tlsext_srtp_multiple_profiles = "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32"; | ||
| 2268 | |||
| 2269 | const char *tlsext_srtp_aes128cmsha80 = "SRTP_AES128_CM_SHA1_80"; | ||
| 2270 | const char *tlsext_srtp_aes128cmsha32 = "SRTP_AES128_CM_SHA1_32"; | ||
| 2271 | |||
| 2272 | const uint8_t tlsext_srtp_single[] = { | ||
| 2273 | /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ | ||
| 2274 | 0x00, 0x02, /* len */ | ||
| 2275 | 0x00, 0x01, /* SRTP_AES128_CM_SHA1_80 */ | ||
| 2276 | 0x00 /* opaque srtp_mki<0..255> */ | ||
| 2277 | }; | ||
| 2278 | |||
| 2279 | const uint8_t tlsext_srtp_multiple[] = { | ||
| 2280 | /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ | ||
| 2281 | 0x00, 0x04, /* len */ | ||
| 2282 | 0x00, 0x01, /* SRTP_AES128_CM_SHA1_80 */ | ||
| 2283 | 0x00, 0x02, /* SRTP_AES128_CM_SHA1_32 */ | ||
| 2284 | 0x00 /* opaque srtp_mki<0..255> */ | ||
| 2285 | }; | ||
| 2286 | |||
| 2287 | const uint8_t tlsext_srtp_multiple_invalid[] = { | ||
| 2288 | /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ | ||
| 2289 | 0x00, 0x04, /* len */ | ||
| 2290 | 0x00, 0x08, /* arbitrary value not found in known profiles */ | ||
| 2291 | 0x00, 0x09, /* arbitrary value not found in known profiles */ | ||
| 2292 | 0x00 /* opaque srtp_mki<0..255> */ | ||
| 2293 | }; | ||
| 2294 | |||
| 2295 | const uint8_t tlsext_srtp_single_invalid[] = { | ||
| 2296 | /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ | ||
| 2297 | 0x00, 0x02, /* len */ | ||
| 2298 | 0x00, 0x08, /* arbitrary value not found in known profiles */ | ||
| 2299 | 0x00 /* opaque srtp_mki<0..255> */ | ||
| 2300 | }; | ||
| 2301 | |||
| 2302 | const uint8_t tlsext_srtp_multiple_one_valid[] = { | ||
| 2303 | /* SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1> */ | ||
| 2304 | 0x00, 0x04, /* len */ | ||
| 2305 | 0x00, 0x08, /* arbitrary value not found in known profiles */ | ||
| 2306 | 0x00, 0x02, /* SRTP_AES128_CM_SHA1_32 */ | ||
| 2307 | 0x00 /* opaque srtp_mki<0..255> */ | ||
| 2308 | }; | ||
| 2309 | |||
| 2310 | static int | ||
| 2311 | test_tlsext_srtp_clienthello(void) | ||
| 2312 | { | ||
| 2313 | SRTP_PROTECTION_PROFILE *prof; | ||
| 2314 | SSL_CTX *ssl_ctx = NULL; | ||
| 2315 | SSL *ssl = NULL; | ||
| 2316 | uint8_t *data = NULL; | ||
| 2317 | CBB cbb; | ||
| 2318 | CBS cbs; | ||
| 2319 | int failure, alert; | ||
| 2320 | size_t dlen; | ||
| 2321 | |||
| 2322 | CBB_init(&cbb, 0); | ||
| 2323 | |||
| 2324 | failure = 1; | ||
| 2325 | |||
| 2326 | /* SRTP is for DTLS */ | ||
| 2327 | if ((ssl_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL) | ||
| 2328 | errx(1, "failed to create SSL_CTX"); | ||
| 2329 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 2330 | errx(1, "failed to create SSL"); | ||
| 2331 | |||
| 2332 | /* By default, we don't need this */ | ||
| 2333 | if (tlsext_srtp_clienthello_needs(ssl)) { | ||
| 2334 | FAIL("clienthello should not need SRTP by default\n"); | ||
| 2335 | goto err; | ||
| 2336 | } | ||
| 2337 | |||
| 2338 | if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_single_profile) != 0) { | ||
| 2339 | FAIL("should be able to set a single SRTP\n"); | ||
| 2340 | goto err; | ||
| 2341 | } | ||
| 2342 | if (!tlsext_srtp_clienthello_needs(ssl)) { | ||
| 2343 | FAIL("clienthello should need SRTP\n"); | ||
| 2344 | goto err; | ||
| 2345 | } | ||
| 2346 | |||
| 2347 | /* Make sure we can build the clienthello with a single profile. */ | ||
| 2348 | |||
| 2349 | if (!tlsext_srtp_clienthello_build(ssl, &cbb)) { | ||
| 2350 | FAIL("clienthello failed to build SRTP\n"); | ||
| 2351 | goto err; | ||
| 2352 | } | ||
| 2353 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 2354 | errx(1, "failed to finish CBB"); | ||
| 2355 | |||
| 2356 | if (dlen != sizeof(tlsext_srtp_single)) { | ||
| 2357 | FAIL("got clienthello SRTP with length %zu, " | ||
| 2358 | "want length %zu\n", dlen, | ||
| 2359 | sizeof(tlsext_srtp_single)); | ||
| 2360 | compare_data(data, dlen, tlsext_srtp_single, | ||
| 2361 | sizeof(tlsext_srtp_single)); | ||
| 2362 | goto err; | ||
| 2363 | } | ||
| 2364 | if (memcmp(data, tlsext_srtp_single, dlen) != 0) { | ||
| 2365 | FAIL("clienthello SRTP differs:\n"); | ||
| 2366 | compare_data(data, dlen, tlsext_srtp_single, | ||
| 2367 | sizeof(tlsext_srtp_single)); | ||
| 2368 | goto err; | ||
| 2369 | } | ||
| 2370 | |||
| 2371 | CBB_cleanup(&cbb); | ||
| 2372 | CBB_init(&cbb, 0); | ||
| 2373 | free(data); | ||
| 2374 | data = NULL; | ||
| 2375 | |||
| 2376 | /* Make sure we can parse the single profile. */ | ||
| 2377 | |||
| 2378 | if (SSL_get_selected_srtp_profile(ssl) != NULL) { | ||
| 2379 | FAIL("SRTP profile should not be set yet\n"); | ||
| 2380 | goto err; | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | CBS_init(&cbs, tlsext_srtp_single, sizeof(tlsext_srtp_single)); | ||
| 2384 | if (!tlsext_srtp_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 2385 | FAIL("failed to parse SRTP\n"); | ||
| 2386 | goto err; | ||
| 2387 | } | ||
| 2388 | |||
| 2389 | if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { | ||
| 2390 | FAIL("SRTP profile should be set now\n"); | ||
| 2391 | goto err; | ||
| 2392 | } | ||
| 2393 | if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { | ||
| 2394 | FAIL("SRTP profile was not set properly\n"); | ||
| 2395 | goto err; | ||
| 2396 | } | ||
| 2397 | |||
| 2398 | if (!tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2399 | FAIL("should send server extension when profile selected\n"); | ||
| 2400 | goto err; | ||
| 2401 | } | ||
| 2402 | |||
| 2403 | /* Make sure we can build the clienthello with multiple entries. */ | ||
| 2404 | |||
| 2405 | if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_multiple_profiles) != 0) { | ||
| 2406 | FAIL("should be able to set SRTP to multiple profiles\n"); | ||
| 2407 | goto err; | ||
| 2408 | } | ||
| 2409 | if (!tlsext_srtp_clienthello_needs(ssl)) { | ||
| 2410 | FAIL("clienthello should need SRTP by now\n"); | ||
| 2411 | goto err; | ||
| 2412 | } | ||
| 2413 | |||
| 2414 | if (!tlsext_srtp_clienthello_build(ssl, &cbb)) { | ||
| 2415 | FAIL("clienthello failed to build SRTP\n"); | ||
| 2416 | goto err; | ||
| 2417 | } | ||
| 2418 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 2419 | errx(1, "failed to finish CBB"); | ||
| 2420 | |||
| 2421 | if (dlen != sizeof(tlsext_srtp_multiple)) { | ||
| 2422 | FAIL("got clienthello SRTP with length %zu, " | ||
| 2423 | "want length %zu\n", dlen, | ||
| 2424 | sizeof(tlsext_srtp_multiple)); | ||
| 2425 | compare_data(data, dlen, tlsext_srtp_multiple, | ||
| 2426 | sizeof(tlsext_srtp_multiple)); | ||
| 2427 | goto err; | ||
| 2428 | } | ||
| 2429 | if (memcmp(data, tlsext_srtp_multiple, dlen) != 0) { | ||
| 2430 | FAIL("clienthello SRTP differs:\n"); | ||
| 2431 | compare_data(data, dlen, tlsext_srtp_multiple, | ||
| 2432 | sizeof(tlsext_srtp_multiple)); | ||
| 2433 | goto err; | ||
| 2434 | } | ||
| 2435 | |||
| 2436 | CBB_cleanup(&cbb); | ||
| 2437 | CBB_init(&cbb, 0); | ||
| 2438 | free(data); | ||
| 2439 | data = NULL; | ||
| 2440 | |||
| 2441 | /* Make sure we can parse multiple profiles (selects server preferred) */ | ||
| 2442 | |||
| 2443 | ssl->internal->srtp_profile = NULL; | ||
| 2444 | |||
| 2445 | CBS_init(&cbs, tlsext_srtp_multiple, | ||
| 2446 | sizeof(tlsext_srtp_multiple)); | ||
| 2447 | if (!tlsext_srtp_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 2448 | FAIL("failed to parse SRTP\n"); | ||
| 2449 | goto err; | ||
| 2450 | } | ||
| 2451 | |||
| 2452 | if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { | ||
| 2453 | FAIL("SRTP profile should be set now\n"); | ||
| 2454 | goto err; | ||
| 2455 | } | ||
| 2456 | if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { | ||
| 2457 | FAIL("SRTP profile was not set properly\n"); | ||
| 2458 | goto err; | ||
| 2459 | } | ||
| 2460 | |||
| 2461 | if (!tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2462 | FAIL("should send server extension when profile selected\n"); | ||
| 2463 | goto err; | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | /* | ||
| 2467 | * Make sure we can parse the clienthello with multiple entries | ||
| 2468 | * where one is unknown. | ||
| 2469 | */ | ||
| 2470 | ssl->internal->srtp_profile = NULL; | ||
| 2471 | |||
| 2472 | CBS_init(&cbs, tlsext_srtp_multiple_one_valid, | ||
| 2473 | sizeof(tlsext_srtp_multiple_one_valid)); | ||
| 2474 | if (!tlsext_srtp_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 2475 | FAIL("failed to parse SRTP\n"); | ||
| 2476 | goto err; | ||
| 2477 | } | ||
| 2478 | |||
| 2479 | if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { | ||
| 2480 | FAIL("SRTP profile should be set now\n"); | ||
| 2481 | goto err; | ||
| 2482 | } | ||
| 2483 | if (strcmp(prof->name, tlsext_srtp_aes128cmsha32) != 0) { | ||
| 2484 | FAIL("SRTP profile was not set properly\n"); | ||
| 2485 | goto err; | ||
| 2486 | } | ||
| 2487 | |||
| 2488 | if (!tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2489 | FAIL("should send server extension when profile selected\n"); | ||
| 2490 | goto err; | ||
| 2491 | } | ||
| 2492 | |||
| 2493 | /* Make sure we fall back to negotiated when none work. */ | ||
| 2494 | |||
| 2495 | ssl->internal->srtp_profile = NULL; | ||
| 2496 | |||
| 2497 | CBS_init(&cbs, tlsext_srtp_multiple_invalid, | ||
| 2498 | sizeof(tlsext_srtp_multiple_invalid)); | ||
| 2499 | if (!tlsext_srtp_clienthello_parse(ssl, &cbs, &alert)) { | ||
| 2500 | FAIL("should be able to fall back to negotiated\n"); | ||
| 2501 | goto err; | ||
| 2502 | } | ||
| 2503 | |||
| 2504 | /* If we fallback, the server should NOT send the extension. */ | ||
| 2505 | if (SSL_get_selected_srtp_profile(ssl) != NULL) { | ||
| 2506 | FAIL("should not have selected a profile when none found\n"); | ||
| 2507 | goto err; | ||
| 2508 | } | ||
| 2509 | if (tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2510 | FAIL("should not send server tlsext when no profile found\n"); | ||
| 2511 | goto err; | ||
| 2512 | } | ||
| 2513 | |||
| 2514 | failure = 0; | ||
| 2515 | |||
| 2516 | err: | ||
| 2517 | CBB_cleanup(&cbb); | ||
| 2518 | SSL_CTX_free(ssl_ctx); | ||
| 2519 | SSL_free(ssl); | ||
| 2520 | free(data); | ||
| 2521 | |||
| 2522 | return (failure); | ||
| 2523 | } | ||
| 2524 | |||
| 2525 | static int | ||
| 2526 | test_tlsext_srtp_serverhello(void) | ||
| 2527 | { | ||
| 2528 | SRTP_PROTECTION_PROFILE *prof; | ||
| 2529 | SSL_CTX *ssl_ctx = NULL; | ||
| 2530 | SSL *ssl = NULL; | ||
| 2531 | uint8_t *data = NULL; | ||
| 2532 | CBB cbb; | ||
| 2533 | CBS cbs; | ||
| 2534 | int failure, alert; | ||
| 2535 | size_t dlen; | ||
| 2536 | |||
| 2537 | CBB_init(&cbb, 0); | ||
| 2538 | |||
| 2539 | failure = 1; | ||
| 2540 | |||
| 2541 | /* SRTP is for DTLS */ | ||
| 2542 | if ((ssl_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL) | ||
| 2543 | errx(1, "failed to create SSL_CTX"); | ||
| 2544 | if ((ssl = SSL_new(ssl_ctx)) == NULL) | ||
| 2545 | errx(1, "failed to create SSL"); | ||
| 2546 | |||
| 2547 | /* By default, we don't need this */ | ||
| 2548 | if (tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2549 | FAIL("serverhello should not need SRTP by default\n"); | ||
| 2550 | goto err; | ||
| 2551 | } | ||
| 2552 | |||
| 2553 | if (srtp_find_profile_by_name((char *)tlsext_srtp_aes128cmsha80, &prof, | ||
| 2554 | strlen(tlsext_srtp_aes128cmsha80))) { | ||
| 2555 | FAIL("should be able to find the given profile\n"); | ||
| 2556 | goto err; | ||
| 2557 | } | ||
| 2558 | ssl->internal->srtp_profile = prof; | ||
| 2559 | if (!tlsext_srtp_serverhello_needs(ssl)) { | ||
| 2560 | FAIL("serverhello should need SRTP by now\n"); | ||
| 2561 | goto err; | ||
| 2562 | } | ||
| 2563 | |||
| 2564 | /* Make sure we can build the serverhello with a single profile. */ | ||
| 2565 | |||
| 2566 | if (!tlsext_srtp_serverhello_build(ssl, &cbb)) { | ||
| 2567 | FAIL("serverhello failed to build SRTP\n"); | ||
| 2568 | goto err; | ||
| 2569 | } | ||
| 2570 | if (!CBB_finish(&cbb, &data, &dlen)) | ||
| 2571 | errx(1, "failed to finish CBB"); | ||
| 2572 | |||
| 2573 | if (dlen != sizeof(tlsext_srtp_single)) { | ||
| 2574 | FAIL("got serverhello SRTP with length %zu, " | ||
| 2575 | "want length %zu\n", dlen, | ||
| 2576 | sizeof(tlsext_srtp_single)); | ||
| 2577 | compare_data(data, dlen, tlsext_srtp_single, | ||
| 2578 | sizeof(tlsext_srtp_single)); | ||
| 2579 | goto err; | ||
| 2580 | } | ||
| 2581 | if (memcmp(data, tlsext_srtp_single, dlen) != 0) { | ||
| 2582 | FAIL("serverhello SRTP differs:\n"); | ||
| 2583 | compare_data(data, dlen, tlsext_srtp_single, | ||
| 2584 | sizeof(tlsext_srtp_single)); | ||
| 2585 | goto err; | ||
| 2586 | } | ||
| 2587 | |||
| 2588 | CBB_cleanup(&cbb); | ||
| 2589 | CBB_init(&cbb, 0); | ||
| 2590 | free(data); | ||
| 2591 | data = NULL; | ||
| 2592 | |||
| 2593 | /* Make sure we can parse the single profile. */ | ||
| 2594 | ssl->internal->srtp_profile = NULL; | ||
| 2595 | |||
| 2596 | if (SSL_get_selected_srtp_profile(ssl) != NULL) { | ||
| 2597 | FAIL("SRTP profile should not be set yet\n"); | ||
| 2598 | goto err; | ||
| 2599 | } | ||
| 2600 | |||
| 2601 | /* Setup the environment as if a client sent a list of profiles. */ | ||
| 2602 | if (SSL_set_tlsext_use_srtp(ssl, tlsext_srtp_multiple_profiles) != 0) { | ||
| 2603 | FAIL("should be able to set multiple profiles in SRTP\n"); | ||
| 2604 | goto err; | ||
| 2605 | } | ||
| 2606 | |||
| 2607 | CBS_init(&cbs, tlsext_srtp_single, sizeof(tlsext_srtp_single)); | ||
| 2608 | if (!tlsext_srtp_serverhello_parse(ssl, &cbs, &alert)) { | ||
| 2609 | FAIL("failed to parse SRTP\n"); | ||
| 2610 | goto err; | ||
| 2611 | } | ||
| 2612 | |||
| 2613 | if ((prof = SSL_get_selected_srtp_profile(ssl)) == NULL) { | ||
| 2614 | FAIL("SRTP profile should be set now\n"); | ||
| 2615 | goto err; | ||
| 2616 | } | ||
| 2617 | if (strcmp(prof->name, tlsext_srtp_aes128cmsha80) != 0) { | ||
| 2618 | FAIL("SRTP profile was not set properly\n"); | ||
| 2619 | goto err; | ||
| 2620 | } | ||
| 2621 | |||
| 2622 | /* Make sure we cannot parse multiple profiles */ | ||
| 2623 | ssl->internal->srtp_profile = NULL; | ||
| 2624 | |||
| 2625 | CBS_init(&cbs, tlsext_srtp_multiple, | ||
| 2626 | sizeof(tlsext_srtp_multiple)); | ||
| 2627 | if (tlsext_srtp_serverhello_parse(ssl, &cbs, &alert)) { | ||
| 2628 | FAIL("should not find multiple entries from the server\n"); | ||
| 2629 | goto err; | ||
| 2630 | } | ||
| 2631 | |||
| 2632 | /* Make sure we cannot parse a serverhello with unknown profile */ | ||
| 2633 | ssl->internal->srtp_profile = NULL; | ||
| 2634 | |||
| 2635 | CBS_init(&cbs, tlsext_srtp_single_invalid, | ||
| 2636 | sizeof(tlsext_srtp_single_invalid)); | ||
| 2637 | if (tlsext_srtp_serverhello_parse(ssl, &cbs, &alert)) { | ||
| 2638 | FAIL("should not be able to parse this\n"); | ||
| 2639 | goto err; | ||
| 2640 | } | ||
| 2641 | |||
| 2642 | failure = 0; | ||
| 2643 | |||
| 2644 | err: | ||
| 2645 | CBB_cleanup(&cbb); | ||
| 2646 | SSL_CTX_free(ssl_ctx); | ||
| 2647 | SSL_free(ssl); | ||
| 2648 | free(data); | ||
| 2649 | |||
| 2650 | return (failure); | ||
| 2651 | } | ||
| 2652 | #endif /* OPENSSL_NO_SRTP */ | ||
| 2653 | |||
| 2260 | int | 2654 | int |
| 2261 | main(int argc, char **argv) | 2655 | main(int argc, char **argv) |
| 2262 | { | 2656 | { |
| @@ -2288,5 +2682,12 @@ main(int argc, char **argv) | |||
| 2288 | failed |= test_tlsext_sessionticket_clienthello(); | 2682 | failed |= test_tlsext_sessionticket_clienthello(); |
| 2289 | failed |= test_tlsext_sessionticket_serverhello(); | 2683 | failed |= test_tlsext_sessionticket_serverhello(); |
| 2290 | 2684 | ||
| 2685 | #ifndef OPENSSL_NO_SRTP | ||
| 2686 | failed |= test_tlsext_srtp_clienthello(); | ||
| 2687 | failed |= test_tlsext_srtp_serverhello(); | ||
| 2688 | #else | ||
| 2689 | fprintf(stderr, "Skipping SRTP tests due to OPENSSL_NO_SRTP\n"); | ||
| 2690 | #endif | ||
| 2691 | |||
| 2291 | return (failed); | 2692 | return (failed); |
| 2292 | } | 2693 | } |
