diff options
author | jsing <> | 2025-02-01 14:13:17 +0000 |
---|---|---|
committer | jsing <> | 2025-02-01 14:13:17 +0000 |
commit | fbb32c61a451cdf69f0bd9ab01ea2c484fc4723c (patch) | |
tree | cddbc33c399af8a611fdf6d8b4e3a2f4ccad4e6f | |
parent | 68f6e90022f7f35d4c05cd703e67be40e085329e (diff) | |
download | openbsd-fbb32c61a451cdf69f0bd9ab01ea2c484fc4723c.tar.gz openbsd-fbb32c61a451cdf69f0bd9ab01ea2c484fc4723c.tar.bz2 openbsd-fbb32c61a451cdf69f0bd9ab01ea2c484fc4723c.zip |
Improve detection and handling of alerts in renegotiation regress.
-rw-r--r-- | src/regress/lib/libssl/renegotiation/renegotiation_test.c | 99 |
1 files changed, 76 insertions, 23 deletions
diff --git a/src/regress/lib/libssl/renegotiation/renegotiation_test.c b/src/regress/lib/libssl/renegotiation/renegotiation_test.c index 4a80ef61ea..45e8bc297e 100644 --- a/src/regress/lib/libssl/renegotiation/renegotiation_test.c +++ b/src/regress/lib/libssl/renegotiation/renegotiation_test.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: renegotiation_test.c,v 1.1 2025/02/01 12:21:52 jsing Exp $ */ | 1 | /* $OpenBSD: renegotiation_test.c,v 1.2 2025/02/01 14:13:17 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020,2025 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020,2025 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -28,6 +28,7 @@ const char *server_key_file; | |||
28 | int debug = 0; | 28 | int debug = 0; |
29 | 29 | ||
30 | int tls_client_alert; | 30 | int tls_client_alert; |
31 | int tls_server_alert; | ||
31 | 32 | ||
32 | static void | 33 | static void |
33 | hexdump(const unsigned char *buf, size_t len) | 34 | hexdump(const unsigned char *buf, size_t len) |
@@ -113,9 +114,16 @@ ssl_error(SSL *ssl, const char *name, const char *desc, int ssl_ret) | |||
113 | } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) { | 114 | } else if (ssl_err == SSL_ERROR_SYSCALL && errno == 0) { |
114 | /* Yup, this is apparently a thing... */ | 115 | /* Yup, this is apparently a thing... */ |
115 | } else { | 116 | } else { |
116 | if (tls_client_alert != 0 && | 117 | if (tls_client_alert >> 8 == SSL3_AL_FATAL || |
117 | ERR_GET_REASON(ERR_peek_error()) >= SSL_AD_REASON_OFFSET) | 118 | tls_server_alert >> 8 == SSL3_AL_FATAL) { |
119 | ERR_clear_error(); | ||
118 | return 0; | 120 | return 0; |
121 | } | ||
122 | if (tls_client_alert >> 8 == SSL3_AL_WARNING || | ||
123 | tls_server_alert >> 8 == SSL3_AL_WARNING) { | ||
124 | ERR_clear_error(); | ||
125 | return 1; | ||
126 | } | ||
119 | fprintf(stderr, "FAIL: %s %s failed - ssl err = %d, errno = %d\n", | 127 | fprintf(stderr, "FAIL: %s %s failed - ssl err = %d, errno = %d\n", |
120 | name, desc, ssl_err, errno); | 128 | name, desc, ssl_err, errno); |
121 | ERR_print_errors_fp(stderr); | 129 | ERR_print_errors_fp(stderr); |
@@ -236,7 +244,9 @@ struct tls_reneg_test { | |||
236 | long ssl_server_options; | 244 | long ssl_server_options; |
237 | int renegotiate_client; | 245 | int renegotiate_client; |
238 | int renegotiate_server; | 246 | int renegotiate_server; |
239 | int want_alert; | 247 | int client_ignored; |
248 | int want_client_alert; | ||
249 | int want_server_alert; | ||
240 | int want_failure; | 250 | int want_failure; |
241 | }; | 251 | }; |
242 | 252 | ||
@@ -270,7 +280,7 @@ static const struct tls_reneg_test tls_reneg_tests[] = { | |||
270 | .ssl_max_proto_version = TLS1_2_VERSION, | 280 | .ssl_max_proto_version = TLS1_2_VERSION, |
271 | .ssl_server_options = SSL_OP_NO_CLIENT_RENEGOTIATION, | 281 | .ssl_server_options = SSL_OP_NO_CLIENT_RENEGOTIATION, |
272 | .renegotiate_server = 1, | 282 | .renegotiate_server = 1, |
273 | .want_alert = 1, | 283 | .want_client_alert = SSL3_AL_FATAL << 8 | SSL_AD_NO_RENEGOTIATION, |
274 | }, | 284 | }, |
275 | { | 285 | { |
276 | .desc = "TLSv1.2 - Client renegotiation not permitted, client " | 286 | .desc = "TLSv1.2 - Client renegotiation not permitted, client " |
@@ -278,7 +288,7 @@ static const struct tls_reneg_test tls_reneg_tests[] = { | |||
278 | .ssl_max_proto_version = TLS1_2_VERSION, | 288 | .ssl_max_proto_version = TLS1_2_VERSION, |
279 | .ssl_server_options = SSL_OP_NO_CLIENT_RENEGOTIATION, | 289 | .ssl_server_options = SSL_OP_NO_CLIENT_RENEGOTIATION, |
280 | .renegotiate_client = 1, | 290 | .renegotiate_client = 1, |
281 | .want_alert = 1, | 291 | .want_client_alert = SSL3_AL_FATAL << 8 | SSL_AD_NO_RENEGOTIATION, |
282 | }, | 292 | }, |
283 | { | 293 | { |
284 | .desc = "TLSv1.3 - No renegotiation supported, no renegotiation", | 294 | .desc = "TLSv1.3 - No renegotiation supported, no renegotiation", |
@@ -313,6 +323,17 @@ tls_client_info_callback(const SSL *ssl, int where, int value) | |||
313 | } | 323 | } |
314 | } | 324 | } |
315 | 325 | ||
326 | static void | ||
327 | tls_server_info_callback(const SSL *ssl, int where, int value) | ||
328 | { | ||
329 | if (where == SSL_CB_READ_ALERT) { | ||
330 | fprintf(stderr, "INFO: server read %s alert - %s\n", | ||
331 | SSL_alert_type_string_long(value), | ||
332 | SSL_alert_desc_string_long(value)); | ||
333 | tls_server_alert = value; | ||
334 | } | ||
335 | } | ||
336 | |||
316 | static int | 337 | static int |
317 | tls_check_reneg(SSL *client, SSL *server, int client_pending, | 338 | tls_check_reneg(SSL *client, SSL *server, int client_pending, |
318 | int server_pending, long client_num_reneg, long server_num_reneg) | 339 | int server_pending, long client_num_reneg, long server_num_reneg) |
@@ -370,15 +391,19 @@ tls_reneg_test(const struct tls_reneg_test *trt) | |||
370 | goto failure; | 391 | goto failure; |
371 | 392 | ||
372 | SSL_set_options(client, trt->ssl_client_options); | 393 | SSL_set_options(client, trt->ssl_client_options); |
394 | SSL_set_info_callback(client, tls_client_info_callback); | ||
373 | 395 | ||
374 | if ((server = tls_server(client_wbio, server_wbio)) == NULL) | 396 | if ((server = tls_server(client_wbio, server_wbio)) == NULL) |
375 | goto failure; | 397 | goto failure; |
376 | 398 | ||
377 | SSL_set_options(server, trt->ssl_server_options); | 399 | SSL_set_options(server, trt->ssl_server_options); |
400 | SSL_set_info_callback(server, tls_server_info_callback); | ||
401 | |||
378 | if (!SSL_set_max_proto_version(server, trt->ssl_max_proto_version)) | 402 | if (!SSL_set_max_proto_version(server, trt->ssl_max_proto_version)) |
379 | goto failure; | 403 | goto failure; |
380 | 404 | ||
381 | SSL_set_info_callback(client, tls_client_info_callback); | 405 | tls_client_alert = 0; |
406 | tls_server_alert = 0; | ||
382 | 407 | ||
383 | if (!do_client_server_loop(client, do_connect, server, do_accept)) { | 408 | if (!do_client_server_loop(client, do_connect, server, do_accept)) { |
384 | fprintf(stderr, "FAIL: client and server handshake failed\n"); | 409 | fprintf(stderr, "FAIL: client and server handshake failed\n"); |
@@ -424,34 +449,49 @@ tls_reneg_test(const struct tls_reneg_test *trt) | |||
424 | goto failure; | 449 | goto failure; |
425 | } | 450 | } |
426 | 451 | ||
427 | if (!tls_check_reneg(client, server, 1, 1, 1, 1)) | 452 | if (!tls_check_reneg(client, server, (trt->client_ignored == 0), 1, |
453 | (trt->client_ignored == 0), 1)) | ||
428 | goto failure; | 454 | goto failure; |
429 | 455 | ||
430 | if (!do_client_server_loop(client, do_write, server, do_read)) { | 456 | if (!do_client_server_loop(client, do_write, server, do_read)) { |
431 | if (!trt->want_alert) { | 457 | if (!trt->want_client_alert && !trt->want_server_alert) { |
432 | fprintf(stderr, "FAIL: client write and server read failed\n"); | 458 | fprintf(stderr, "FAIL: client write and server read failed\n"); |
433 | goto failure; | 459 | goto failure; |
434 | } | 460 | } |
435 | if (tls_client_alert != (SSL3_AL_FATAL << 8 | | 461 | if (tls_client_alert != trt->want_client_alert) { |
436 | SSL_AD_NO_RENEGOTIATION)) { | ||
437 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", | 462 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", |
438 | tls_client_alert, SSL3_AL_FATAL << 8 | | 463 | tls_client_alert, trt->want_client_alert); |
439 | SSL_AD_NO_RENEGOTIATION); | 464 | goto failure; |
465 | } | ||
466 | if (tls_server_alert != trt->want_server_alert) { | ||
467 | fprintf(stderr, "FAIL: server alert = %x, want %x\n", | ||
468 | tls_server_alert, trt->want_server_alert); | ||
469 | goto failure; | ||
440 | } | 470 | } |
441 | goto done; | 471 | goto done; |
442 | } | 472 | } |
443 | if (trt->want_alert) { | 473 | if (tls_client_alert != trt->want_client_alert) { |
444 | fprintf(stderr, "FAIL: server renegotiation should have alerted\n"); | 474 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", |
475 | tls_client_alert, trt->want_client_alert); | ||
476 | goto failure; | ||
477 | } | ||
478 | if (tls_server_alert != trt->want_server_alert) { | ||
479 | fprintf(stderr, "FAIL: server alert = %x, want %x\n", | ||
480 | tls_server_alert, trt->want_server_alert); | ||
445 | goto failure; | 481 | goto failure; |
446 | } | 482 | } |
447 | 483 | ||
448 | if (!tls_check_reneg(client, server, 0, 0, 1, 1)) | 484 | if (!tls_check_reneg(client, server, 0, (trt->client_ignored != 0), |
485 | (trt->client_ignored == 0), 1)) | ||
449 | goto failure; | 486 | goto failure; |
450 | } | 487 | } |
451 | 488 | ||
452 | SSL_clear_num_renegotiations(client); | 489 | SSL_clear_num_renegotiations(client); |
453 | SSL_clear_num_renegotiations(server); | 490 | SSL_clear_num_renegotiations(server); |
454 | 491 | ||
492 | tls_client_alert = 0; | ||
493 | tls_server_alert = 0; | ||
494 | |||
455 | if (trt->renegotiate_client) { | 495 | if (trt->renegotiate_client) { |
456 | /* | 496 | /* |
457 | * Trigger renegotiation from the client - this results in the | 497 | * Trigger renegotiation from the client - this results in the |
@@ -469,6 +509,9 @@ tls_reneg_test(const struct tls_reneg_test *trt) | |||
469 | goto failure; | 509 | goto failure; |
470 | } | 510 | } |
471 | 511 | ||
512 | if (!tls_check_reneg(client, server, 1, 0, 0, 0)) | ||
513 | goto failure; | ||
514 | |||
472 | if (!do_client_server_loop(client, do_read, server, do_write)) { | 515 | if (!do_client_server_loop(client, do_read, server, do_write)) { |
473 | fprintf(stderr, "FAIL: client read and server write failed\n"); | 516 | fprintf(stderr, "FAIL: client read and server write failed\n"); |
474 | goto failure; | 517 | goto failure; |
@@ -478,20 +521,30 @@ tls_reneg_test(const struct tls_reneg_test *trt) | |||
478 | goto failure; | 521 | goto failure; |
479 | 522 | ||
480 | if (!do_client_server_loop(client, do_write, server, do_read)) { | 523 | if (!do_client_server_loop(client, do_write, server, do_read)) { |
481 | if (!trt->want_alert) { | 524 | if (!trt->want_client_alert && !trt->want_server_alert) { |
482 | fprintf(stderr, "FAIL: client write and server read failed\n"); | 525 | fprintf(stderr, "FAIL: client write and server read failed\n"); |
483 | goto failure; | 526 | goto failure; |
484 | } | 527 | } |
485 | if (tls_client_alert != (SSL3_AL_FATAL << 8 | | 528 | if (tls_client_alert != trt->want_client_alert) { |
486 | SSL_AD_NO_RENEGOTIATION)) { | ||
487 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", | 529 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", |
488 | tls_client_alert, SSL3_AL_FATAL << 8 | | 530 | tls_client_alert, trt->want_client_alert); |
489 | SSL_AD_NO_RENEGOTIATION); | 531 | goto failure; |
532 | } | ||
533 | if (tls_server_alert != trt->want_server_alert) { | ||
534 | fprintf(stderr, "FAIL: server alert = %x, want %x\n", | ||
535 | tls_server_alert, trt->want_server_alert); | ||
536 | goto failure; | ||
490 | } | 537 | } |
491 | goto done; | 538 | goto done; |
492 | } | 539 | } |
493 | if (trt->want_alert) { | 540 | if (tls_client_alert != trt->want_client_alert) { |
494 | fprintf(stderr, "FAIL: server renegotiation should have alerted\n"); | 541 | fprintf(stderr, "FAIL: client alert = %x, want %x\n", |
542 | tls_client_alert, trt->want_client_alert); | ||
543 | goto failure; | ||
544 | } | ||
545 | if (tls_server_alert != trt->want_server_alert) { | ||
546 | fprintf(stderr, "FAIL: server alert = %x, want %x\n", | ||
547 | tls_server_alert, trt->want_server_alert); | ||
495 | goto failure; | 548 | goto failure; |
496 | } | 549 | } |
497 | 550 | ||