diff options
| author | doug <> | 2017-08-27 02:58:04 +0000 |
|---|---|---|
| committer | doug <> | 2017-08-27 02:58:04 +0000 |
| commit | 306dd0800e7f4fdbc7f1f0d0610cbcf42263e6d8 (patch) | |
| tree | af98c801c4a8cf65f19c593a6d95424d151a7e8b /src/lib/libssl/d1_srtp.c | |
| parent | a2f3c5ccdf113b1ab98dfd659053c47f63db82ec (diff) | |
| download | openbsd-306dd0800e7f4fdbc7f1f0d0610cbcf42263e6d8.tar.gz openbsd-306dd0800e7f4fdbc7f1f0d0610cbcf42263e6d8.tar.bz2 openbsd-306dd0800e7f4fdbc7f1f0d0610cbcf42263e6d8.zip | |
Rewrite SRTP extension using CBB/CBS and the new extension framework.
input + ok beck@, jsing@
Diffstat (limited to '')
| -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 |
