1 /* 2 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <string.h> 12 13 #include <openssl/conf.h> 14 #include <openssl/err.h> 15 #include <openssl/ssl.h> 16 17 #include "handshake_helper.h" 18 #include "ssl_test_ctx.h" 19 #include "testutil.h" 20 21 static CONF *conf = NULL; 22 23 /* Currently the section names are of the form test-<number>, e.g. test-15. */ 24 #define MAX_TESTCASE_NAME_LENGTH 100 25 26 static const char *print_alert(int alert) 27 { 28 return alert ? SSL_alert_desc_string_long(alert) : "no alert"; 29 } 30 31 static int check_result(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 32 { 33 if (!TEST_int_eq(result->result, test_ctx->expected_result)) { 34 TEST_info("ExpectedResult mismatch: expected %s, got %s.", 35 ssl_test_result_name(test_ctx->expected_result), 36 ssl_test_result_name(result->result)); 37 return 0; 38 } 39 return 1; 40 } 41 42 static int check_alerts(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 43 { 44 if (!TEST_int_eq(result->client_alert_sent, 45 result->client_alert_received)) { 46 TEST_info("Client sent alert %s but server received %s.", 47 print_alert(result->client_alert_sent), 48 print_alert(result->client_alert_received)); 49 /* 50 * We can't bail here because the peer doesn't always get far enough 51 * to process a received alert. Specifically, in protocol version 52 * negotiation tests, we have the following scenario. 53 * Client supports TLS v1.2 only; Server supports TLS v1.1. 54 * Client proposes TLS v1.2; server responds with 1.1; 55 * Client now sends a protocol alert, using TLS v1.2 in the header. 56 * The server, however, rejects the alert because of version mismatch 57 * in the record layer; therefore, the server appears to never 58 * receive the alert. 59 */ 60 /* return 0; */ 61 } 62 63 if (!TEST_int_eq(result->server_alert_sent, 64 result->server_alert_received)) { 65 TEST_info("Server sent alert %s but client received %s.", 66 print_alert(result->server_alert_sent), 67 print_alert(result->server_alert_received)); 68 /* return 0; */ 69 } 70 71 /* Tolerate an alert if one wasn't explicitly specified in the test. */ 72 if (test_ctx->expected_client_alert 73 /* 74 * The info callback alert value is computed as 75 * (s->s3->send_alert[0] << 8) | s->s3->send_alert[1] 76 * where the low byte is the alert code and the high byte is other stuff. 77 */ 78 && (result->client_alert_sent & 0xff) != test_ctx->expected_client_alert) { 79 TEST_error("ClientAlert mismatch: expected %s, got %s.", 80 print_alert(test_ctx->expected_client_alert), 81 print_alert(result->client_alert_sent)); 82 return 0; 83 } 84 85 if (test_ctx->expected_server_alert 86 && (result->server_alert_sent & 0xff) != test_ctx->expected_server_alert) { 87 TEST_error("ServerAlert mismatch: expected %s, got %s.", 88 print_alert(test_ctx->expected_server_alert), 89 print_alert(result->server_alert_sent)); 90 return 0; 91 } 92 93 if (!TEST_int_le(result->client_num_fatal_alerts_sent, 1)) 94 return 0; 95 if (!TEST_int_le(result->server_num_fatal_alerts_sent, 1)) 96 return 0; 97 return 1; 98 } 99 100 static int check_protocol(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 101 { 102 if (!TEST_int_eq(result->client_protocol, result->server_protocol)) { 103 TEST_info("Client has protocol %s but server has %s.", 104 ssl_protocol_name(result->client_protocol), 105 ssl_protocol_name(result->server_protocol)); 106 return 0; 107 } 108 109 if (test_ctx->expected_protocol) { 110 if (!TEST_int_eq(result->client_protocol, 111 test_ctx->expected_protocol)) { 112 TEST_info("Protocol mismatch: expected %s, got %s.\n", 113 ssl_protocol_name(test_ctx->expected_protocol), 114 ssl_protocol_name(result->client_protocol)); 115 return 0; 116 } 117 } 118 return 1; 119 } 120 121 static int check_servername(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 122 { 123 if (!TEST_int_eq(result->servername, test_ctx->expected_servername)) { 124 TEST_info("Client ServerName mismatch, expected %s, got %s.", 125 ssl_servername_name(test_ctx->expected_servername), 126 ssl_servername_name(result->servername)); 127 return 0; 128 } 129 return 1; 130 } 131 132 static int check_session_ticket(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 133 { 134 if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_IGNORE) 135 return 1; 136 if (!TEST_int_eq(result->session_ticket, 137 test_ctx->session_ticket_expected)) { 138 TEST_info("Client SessionTicketExpected mismatch, expected %s, got %s.", 139 ssl_session_ticket_name(test_ctx->session_ticket_expected), 140 ssl_session_ticket_name(result->session_ticket)); 141 return 0; 142 } 143 return 1; 144 } 145 146 static int check_session_id(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 147 { 148 if (test_ctx->session_id_expected == SSL_TEST_SESSION_ID_IGNORE) 149 return 1; 150 if (!TEST_int_eq(result->session_id, test_ctx->session_id_expected)) { 151 TEST_info("Client SessionIdExpected mismatch, expected %s, got %s\n.", 152 ssl_session_id_name(test_ctx->session_id_expected), 153 ssl_session_id_name(result->session_id)); 154 return 0; 155 } 156 return 1; 157 } 158 159 static int check_compression(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 160 { 161 if (!TEST_int_eq(result->compression, test_ctx->compression_expected)) 162 return 0; 163 return 1; 164 } 165 #ifndef OPENSSL_NO_NEXTPROTONEG 166 static int check_npn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 167 { 168 int ret = 1; 169 if (!TEST_str_eq(result->client_npn_negotiated, 170 result->server_npn_negotiated)) 171 ret = 0; 172 if (!TEST_str_eq(test_ctx->expected_npn_protocol, 173 result->client_npn_negotiated)) 174 ret = 0; 175 return ret; 176 } 177 #endif 178 179 static int check_alpn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 180 { 181 int ret = 1; 182 if (!TEST_str_eq(result->client_alpn_negotiated, 183 result->server_alpn_negotiated)) 184 ret = 0; 185 if (!TEST_str_eq(test_ctx->expected_alpn_protocol, 186 result->client_alpn_negotiated)) 187 ret = 0; 188 return ret; 189 } 190 191 static int check_session_ticket_app_data(HANDSHAKE_RESULT *result, 192 SSL_TEST_CTX *test_ctx) 193 { 194 size_t result_len = 0; 195 size_t expected_len = 0; 196 197 /* consider empty and NULL strings to be the same */ 198 if (result->result_session_ticket_app_data != NULL) 199 result_len = strlen(result->result_session_ticket_app_data); 200 if (test_ctx->expected_session_ticket_app_data != NULL) 201 expected_len = strlen(test_ctx->expected_session_ticket_app_data); 202 if (result_len == 0 && expected_len == 0) 203 return 1; 204 205 if (!TEST_str_eq(result->result_session_ticket_app_data, 206 test_ctx->expected_session_ticket_app_data)) 207 return 0; 208 209 return 1; 210 } 211 212 static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 213 { 214 if (!TEST_int_eq(result->client_resumed, result->server_resumed)) 215 return 0; 216 if (!TEST_int_eq(result->client_resumed, test_ctx->resumption_expected)) 217 return 0; 218 return 1; 219 } 220 221 static int check_nid(const char *name, int expected_nid, int nid) 222 { 223 if (expected_nid == 0 || expected_nid == nid) 224 return 1; 225 TEST_error("%s type mismatch, %s vs %s\n", 226 name, OBJ_nid2ln(expected_nid), 227 nid == NID_undef ? "absent" : OBJ_nid2ln(nid)); 228 return 0; 229 } 230 231 static void print_ca_names(STACK_OF(X509_NAME) *names) 232 { 233 int i; 234 235 if (names == NULL || sk_X509_NAME_num(names) == 0) { 236 TEST_note(" <empty>"); 237 return; 238 } 239 for (i = 0; i < sk_X509_NAME_num(names); i++) { 240 X509_NAME_print_ex(bio_err, sk_X509_NAME_value(names, i), 4, 241 XN_FLAG_ONELINE); 242 BIO_puts(bio_err, "\n"); 243 } 244 } 245 246 static int check_ca_names(const char *name, 247 STACK_OF(X509_NAME) *expected_names, 248 STACK_OF(X509_NAME) *names) 249 { 250 int i; 251 252 if (expected_names == NULL) 253 return 1; 254 if (names == NULL || sk_X509_NAME_num(names) == 0) { 255 if (TEST_int_eq(sk_X509_NAME_num(expected_names), 0)) 256 return 1; 257 goto err; 258 } 259 if (sk_X509_NAME_num(names) != sk_X509_NAME_num(expected_names)) 260 goto err; 261 for (i = 0; i < sk_X509_NAME_num(names); i++) { 262 if (!TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(names, i), 263 sk_X509_NAME_value(expected_names, i)), 264 0)) { 265 goto err; 266 } 267 } 268 return 1; 269 err: 270 TEST_info("%s: list mismatch", name); 271 TEST_note("Expected Names:"); 272 print_ca_names(expected_names); 273 TEST_note("Received Names:"); 274 print_ca_names(names); 275 return 0; 276 } 277 278 static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 279 { 280 return check_nid("Tmp key", test_ctx->expected_tmp_key_type, 281 result->tmp_key_type); 282 } 283 284 static int check_server_cert_type(HANDSHAKE_RESULT *result, 285 SSL_TEST_CTX *test_ctx) 286 { 287 return check_nid("Server certificate", test_ctx->expected_server_cert_type, 288 result->server_cert_type); 289 } 290 291 static int check_server_sign_hash(HANDSHAKE_RESULT *result, 292 SSL_TEST_CTX *test_ctx) 293 { 294 return check_nid("Server signing hash", test_ctx->expected_server_sign_hash, 295 result->server_sign_hash); 296 } 297 298 static int check_server_sign_type(HANDSHAKE_RESULT *result, 299 SSL_TEST_CTX *test_ctx) 300 { 301 return check_nid("Server signing", test_ctx->expected_server_sign_type, 302 result->server_sign_type); 303 } 304 305 static int check_server_ca_names(HANDSHAKE_RESULT *result, 306 SSL_TEST_CTX *test_ctx) 307 { 308 return check_ca_names("Server CA names", 309 test_ctx->expected_server_ca_names, 310 result->server_ca_names); 311 } 312 313 static int check_client_cert_type(HANDSHAKE_RESULT *result, 314 SSL_TEST_CTX *test_ctx) 315 { 316 return check_nid("Client certificate", test_ctx->expected_client_cert_type, 317 result->client_cert_type); 318 } 319 320 static int check_client_sign_hash(HANDSHAKE_RESULT *result, 321 SSL_TEST_CTX *test_ctx) 322 { 323 return check_nid("Client signing hash", test_ctx->expected_client_sign_hash, 324 result->client_sign_hash); 325 } 326 327 static int check_client_sign_type(HANDSHAKE_RESULT *result, 328 SSL_TEST_CTX *test_ctx) 329 { 330 return check_nid("Client signing", test_ctx->expected_client_sign_type, 331 result->client_sign_type); 332 } 333 334 static int check_client_ca_names(HANDSHAKE_RESULT *result, 335 SSL_TEST_CTX *test_ctx) 336 { 337 return check_ca_names("Client CA names", 338 test_ctx->expected_client_ca_names, 339 result->client_ca_names); 340 } 341 342 static int check_cipher(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 343 { 344 if (test_ctx->expected_cipher == NULL) 345 return 1; 346 if (!TEST_ptr(result->cipher)) 347 return 0; 348 if (!TEST_str_eq(test_ctx->expected_cipher, 349 result->cipher)) 350 return 0; 351 return 1; 352 } 353 354 /* 355 * This could be further simplified by constructing an expected 356 * HANDSHAKE_RESULT, and implementing comparison methods for 357 * its fields. 358 */ 359 static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx) 360 { 361 int ret = 1; 362 ret &= check_result(result, test_ctx); 363 ret &= check_alerts(result, test_ctx); 364 if (result->result == SSL_TEST_SUCCESS) { 365 ret &= check_protocol(result, test_ctx); 366 ret &= check_servername(result, test_ctx); 367 ret &= check_session_ticket(result, test_ctx); 368 ret &= check_compression(result, test_ctx); 369 ret &= check_session_id(result, test_ctx); 370 ret &= (result->session_ticket_do_not_call == 0); 371 #ifndef OPENSSL_NO_NEXTPROTONEG 372 ret &= check_npn(result, test_ctx); 373 #endif 374 ret &= check_cipher(result, test_ctx); 375 ret &= check_alpn(result, test_ctx); 376 ret &= check_session_ticket_app_data(result, test_ctx); 377 ret &= check_resumption(result, test_ctx); 378 ret &= check_tmp_key(result, test_ctx); 379 ret &= check_server_cert_type(result, test_ctx); 380 ret &= check_server_sign_hash(result, test_ctx); 381 ret &= check_server_sign_type(result, test_ctx); 382 ret &= check_server_ca_names(result, test_ctx); 383 ret &= check_client_cert_type(result, test_ctx); 384 ret &= check_client_sign_hash(result, test_ctx); 385 ret &= check_client_sign_type(result, test_ctx); 386 ret &= check_client_ca_names(result, test_ctx); 387 } 388 return ret; 389 } 390 391 static int test_handshake(int idx) 392 { 393 int ret = 0; 394 SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL, 395 *resume_server_ctx = NULL, *resume_client_ctx = NULL; 396 SSL_TEST_CTX *test_ctx = NULL; 397 HANDSHAKE_RESULT *result = NULL; 398 char test_app[MAX_TESTCASE_NAME_LENGTH]; 399 400 BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx); 401 402 test_ctx = SSL_TEST_CTX_create(conf, test_app); 403 if (!TEST_ptr(test_ctx)) 404 goto err; 405 406 #ifndef OPENSSL_NO_DTLS 407 if (test_ctx->method == SSL_TEST_METHOD_DTLS) { 408 server_ctx = SSL_CTX_new(DTLS_server_method()); 409 if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 410 DTLS_MAX_VERSION))) 411 goto err; 412 if (test_ctx->extra.server.servername_callback != 413 SSL_TEST_SERVERNAME_CB_NONE) { 414 if (!TEST_ptr(server2_ctx = SSL_CTX_new(DTLS_server_method()))) 415 goto err; 416 } 417 client_ctx = SSL_CTX_new(DTLS_client_method()); 418 if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, 419 DTLS_MAX_VERSION))) 420 goto err; 421 if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { 422 resume_server_ctx = SSL_CTX_new(DTLS_server_method()); 423 if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 424 DTLS_MAX_VERSION))) 425 goto err; 426 resume_client_ctx = SSL_CTX_new(DTLS_client_method()); 427 if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx, 428 DTLS_MAX_VERSION))) 429 goto err; 430 if (!TEST_ptr(resume_server_ctx) 431 || !TEST_ptr(resume_client_ctx)) 432 goto err; 433 } 434 } 435 #endif 436 if (test_ctx->method == SSL_TEST_METHOD_TLS) { 437 server_ctx = SSL_CTX_new(TLS_server_method()); 438 if (!TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 439 TLS_MAX_VERSION))) 440 goto err; 441 /* SNI on resumption isn't supported/tested yet. */ 442 if (test_ctx->extra.server.servername_callback != 443 SSL_TEST_SERVERNAME_CB_NONE) { 444 if (!TEST_ptr(server2_ctx = SSL_CTX_new(TLS_server_method()))) 445 goto err; 446 if (!TEST_true(SSL_CTX_set_max_proto_version(server2_ctx, 447 TLS_MAX_VERSION))) 448 goto err; 449 } 450 client_ctx = SSL_CTX_new(TLS_client_method()); 451 if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, 452 TLS_MAX_VERSION))) 453 goto err; 454 455 if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { 456 resume_server_ctx = SSL_CTX_new(TLS_server_method()); 457 if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 458 TLS_MAX_VERSION))) 459 goto err; 460 resume_client_ctx = SSL_CTX_new(TLS_client_method()); 461 if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx, 462 TLS_MAX_VERSION))) 463 goto err; 464 if (!TEST_ptr(resume_server_ctx) 465 || !TEST_ptr(resume_client_ctx)) 466 goto err; 467 } 468 } 469 470 #ifdef OPENSSL_NO_AUTOLOAD_CONFIG 471 if (!TEST_true(OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL))) 472 goto err; 473 #endif 474 475 if (!TEST_ptr(server_ctx) 476 || !TEST_ptr(client_ctx) 477 || !TEST_int_gt(CONF_modules_load(conf, test_app, 0), 0)) 478 goto err; 479 480 if (!SSL_CTX_config(server_ctx, "server") 481 || !SSL_CTX_config(client_ctx, "client")) { 482 goto err; 483 } 484 485 if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2")) 486 goto err; 487 if (resume_server_ctx != NULL 488 && !SSL_CTX_config(resume_server_ctx, "resume-server")) 489 goto err; 490 if (resume_client_ctx != NULL 491 && !SSL_CTX_config(resume_client_ctx, "resume-client")) 492 goto err; 493 494 result = do_handshake(server_ctx, server2_ctx, client_ctx, 495 resume_server_ctx, resume_client_ctx, test_ctx); 496 497 if (result != NULL) 498 ret = check_test(result, test_ctx); 499 500 err: 501 CONF_modules_unload(0); 502 SSL_CTX_free(server_ctx); 503 SSL_CTX_free(server2_ctx); 504 SSL_CTX_free(client_ctx); 505 SSL_CTX_free(resume_server_ctx); 506 SSL_CTX_free(resume_client_ctx); 507 SSL_TEST_CTX_free(test_ctx); 508 HANDSHAKE_RESULT_free(result); 509 return ret; 510 } 511 512 int setup_tests(void) 513 { 514 long num_tests; 515 516 if (!TEST_ptr(conf = NCONF_new(NULL)) 517 /* argv[1] should point to the test conf file */ 518 || !TEST_int_gt(NCONF_load(conf, test_get_argument(0), NULL), 0) 519 || !TEST_int_ne(NCONF_get_number_e(conf, NULL, "num_tests", 520 &num_tests), 0)) 521 return 0; 522 523 ADD_ALL_TESTS(test_handshake, (int)num_tests); 524 return 1; 525 } 526 527 void cleanup_tests(void) 528 { 529 NCONF_free(conf); 530 } 531