1 /* 2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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 <openssl/ssl.h> 11 #include <string.h> 12 #include "helpers/ssltestlib.h" 13 #include "testutil.h" 14 #include "internal/packet.h" 15 16 static char *cert = NULL; 17 static char *privkey = NULL; 18 19 static BIO *s_to_c_fbio = NULL, *c_to_s_fbio = NULL; 20 static int chseen = 0, shseen = 0, sccsseen = 0, ccsaftersh = 0; 21 static int ccsbeforesh = 0, sappdataseen = 0, cappdataseen = 0, badccs = 0; 22 static int badvers = 0, badsessid = 0; 23 24 static unsigned char chsessid[SSL_MAX_SSL_SESSION_ID_LENGTH]; 25 static size_t chsessidlen = 0; 26 27 static int watchccs_new(BIO *bi); 28 static int watchccs_free(BIO *a); 29 static int watchccs_read(BIO *b, char *out, int outl); 30 static int watchccs_write(BIO *b, const char *in, int inl); 31 static long watchccs_ctrl(BIO *b, int cmd, long num, void *ptr); 32 static int watchccs_gets(BIO *bp, char *buf, int size); 33 static int watchccs_puts(BIO *bp, const char *str); 34 35 /* Choose a sufficiently large type likely to be unused for this custom BIO */ 36 # define BIO_TYPE_WATCHCCS_FILTER (0x80 | BIO_TYPE_FILTER) 37 38 static BIO_METHOD *method_watchccs = NULL; 39 40 static const BIO_METHOD *bio_f_watchccs_filter(void) 41 { 42 if (method_watchccs == NULL) { 43 method_watchccs = BIO_meth_new(BIO_TYPE_WATCHCCS_FILTER, 44 "Watch CCS filter"); 45 if ( method_watchccs == NULL 46 || !BIO_meth_set_write(method_watchccs, watchccs_write) 47 || !BIO_meth_set_read(method_watchccs, watchccs_read) 48 || !BIO_meth_set_puts(method_watchccs, watchccs_puts) 49 || !BIO_meth_set_gets(method_watchccs, watchccs_gets) 50 || !BIO_meth_set_ctrl(method_watchccs, watchccs_ctrl) 51 || !BIO_meth_set_create(method_watchccs, watchccs_new) 52 || !BIO_meth_set_destroy(method_watchccs, watchccs_free)) 53 return NULL; 54 } 55 return method_watchccs; 56 } 57 58 static int watchccs_new(BIO *bio) 59 { 60 BIO_set_init(bio, 1); 61 return 1; 62 } 63 64 static int watchccs_free(BIO *bio) 65 { 66 BIO_set_init(bio, 0); 67 return 1; 68 } 69 70 static int watchccs_read(BIO *bio, char *out, int outl) 71 { 72 int ret = 0; 73 BIO *next = BIO_next(bio); 74 75 if (outl <= 0) 76 return 0; 77 if (next == NULL) 78 return 0; 79 80 BIO_clear_retry_flags(bio); 81 82 ret = BIO_read(next, out, outl); 83 if (ret <= 0 && BIO_should_read(next)) 84 BIO_set_retry_read(bio); 85 86 return ret; 87 } 88 89 static int watchccs_write(BIO *bio, const char *in, int inl) 90 { 91 int ret = 0; 92 BIO *next = BIO_next(bio); 93 PACKET pkt, msg, msgbody, sessionid; 94 unsigned int rectype, recvers, msgtype, expectedrecvers; 95 96 if (inl <= 0) 97 return 0; 98 if (next == NULL) 99 return 0; 100 101 BIO_clear_retry_flags(bio); 102 103 if (!PACKET_buf_init(&pkt, (const unsigned char *)in, inl)) 104 return 0; 105 106 /* We assume that we always write complete records each time */ 107 while (PACKET_remaining(&pkt)) { 108 if (!PACKET_get_1(&pkt, &rectype) 109 || !PACKET_get_net_2(&pkt, &recvers) 110 || !PACKET_get_length_prefixed_2(&pkt, &msg)) 111 return 0; 112 113 expectedrecvers = TLS1_2_VERSION; 114 115 if (rectype == SSL3_RT_HANDSHAKE) { 116 if (!PACKET_get_1(&msg, &msgtype) 117 || !PACKET_get_length_prefixed_3(&msg, &msgbody)) 118 return 0; 119 if (msgtype == SSL3_MT_CLIENT_HELLO) { 120 chseen++; 121 122 /* 123 * Skip legacy_version (2 bytes) and Random (32 bytes) to read 124 * session_id. 125 */ 126 if (!PACKET_forward(&msgbody, 34) 127 || !PACKET_get_length_prefixed_1(&msgbody, &sessionid)) 128 return 0; 129 130 if (chseen == 1) { 131 expectedrecvers = TLS1_VERSION; 132 133 /* Save the session id for later */ 134 chsessidlen = PACKET_remaining(&sessionid); 135 if (!PACKET_copy_bytes(&sessionid, chsessid, chsessidlen)) 136 return 0; 137 } else { 138 /* 139 * Check the session id for the second ClientHello is the 140 * same as the first one. 141 */ 142 if (PACKET_remaining(&sessionid) != chsessidlen 143 || (chsessidlen > 0 144 && memcmp(chsessid, PACKET_data(&sessionid), 145 chsessidlen) != 0)) 146 badsessid = 1; 147 } 148 } else if (msgtype == SSL3_MT_SERVER_HELLO) { 149 shseen++; 150 /* 151 * Skip legacy_version (2 bytes) and Random (32 bytes) to read 152 * session_id. 153 */ 154 if (!PACKET_forward(&msgbody, 34) 155 || !PACKET_get_length_prefixed_1(&msgbody, &sessionid)) 156 return 0; 157 158 /* 159 * Check the session id is the same as the one in the 160 * ClientHello 161 */ 162 if (PACKET_remaining(&sessionid) != chsessidlen 163 || (chsessidlen > 0 164 && memcmp(chsessid, PACKET_data(&sessionid), 165 chsessidlen) != 0)) 166 badsessid = 1; 167 } 168 } else if (rectype == SSL3_RT_CHANGE_CIPHER_SPEC) { 169 if (bio == s_to_c_fbio) { 170 /* 171 * Server writing. We shouldn't have written any app data 172 * yet, and we should have seen both the ClientHello and the 173 * ServerHello 174 */ 175 if (!sappdataseen 176 && chseen == 1 177 && shseen == 1 178 && !sccsseen) 179 sccsseen = 1; 180 else 181 badccs = 1; 182 } else if (!cappdataseen) { 183 /* 184 * Client writing. We shouldn't have written any app data 185 * yet, and we should have seen the ClientHello 186 */ 187 if (shseen == 1 && !ccsaftersh) 188 ccsaftersh = 1; 189 else if (shseen == 0 && !ccsbeforesh) 190 ccsbeforesh = 1; 191 else 192 badccs = 1; 193 } else { 194 badccs = 1; 195 } 196 } else if(rectype == SSL3_RT_APPLICATION_DATA) { 197 if (bio == s_to_c_fbio) 198 sappdataseen = 1; 199 else 200 cappdataseen = 1; 201 } 202 if (recvers != expectedrecvers) 203 badvers = 1; 204 } 205 206 ret = BIO_write(next, in, inl); 207 if (ret <= 0 && BIO_should_write(next)) 208 BIO_set_retry_write(bio); 209 210 return ret; 211 } 212 213 static long watchccs_ctrl(BIO *bio, int cmd, long num, void *ptr) 214 { 215 long ret; 216 BIO *next = BIO_next(bio); 217 218 if (next == NULL) 219 return 0; 220 221 switch (cmd) { 222 case BIO_CTRL_DUP: 223 ret = 0; 224 break; 225 default: 226 ret = BIO_ctrl(next, cmd, num, ptr); 227 break; 228 } 229 return ret; 230 } 231 232 static int watchccs_gets(BIO *bio, char *buf, int size) 233 { 234 /* We don't support this - not needed anyway */ 235 return -1; 236 } 237 238 static int watchccs_puts(BIO *bio, const char *str) 239 { 240 return watchccs_write(bio, str, strlen(str)); 241 } 242 243 static int test_tls13ccs(int tst) 244 { 245 SSL_CTX *sctx = NULL, *cctx = NULL; 246 SSL *sssl = NULL, *cssl = NULL; 247 int ret = 0; 248 const char msg[] = "Dummy data"; 249 char buf[80]; 250 size_t written, readbytes; 251 SSL_SESSION *sess = NULL; 252 253 chseen = shseen = sccsseen = ccsaftersh = ccsbeforesh = 0; 254 sappdataseen = cappdataseen = badccs = badvers = badsessid = 0; 255 chsessidlen = 0; 256 257 if (!TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), 258 TLS_client_method(), TLS1_VERSION, 0, 259 &sctx, &cctx, cert, privkey)) 260 || !TEST_true(SSL_CTX_set_max_early_data(sctx, 261 SSL3_RT_MAX_PLAIN_LENGTH))) 262 goto err; 263 264 /* 265 * Test 0: Simple Handshake 266 * Test 1: Simple Handshake, client middlebox compat mode disabled 267 * Test 2: Simple Handshake, server middlebox compat mode disabled 268 * Test 3: HRR Handshake 269 * Test 4: HRR Handshake, client middlebox compat mode disabled 270 * Test 5: HRR Handshake, server middlebox compat mode disabled 271 * Test 6: Early data handshake 272 * Test 7: Early data handshake, client middlebox compat mode disabled 273 * Test 8: Early data handshake, server middlebox compat mode disabled 274 * Test 9: Early data then HRR 275 * Test 10: Early data then HRR, client middlebox compat mode disabled 276 * Test 11: Early data then HRR, server middlebox compat mode disabled 277 */ 278 switch (tst) { 279 case 0: 280 case 3: 281 case 6: 282 case 9: 283 break; 284 case 1: 285 case 4: 286 case 7: 287 case 10: 288 SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); 289 break; 290 case 2: 291 case 5: 292 case 8: 293 case 11: 294 SSL_CTX_clear_options(sctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); 295 break; 296 default: 297 TEST_error("Invalid test value"); 298 goto err; 299 } 300 301 if (tst >= 6) { 302 /* Get a session suitable for early_data */ 303 if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL)) 304 || !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))) 305 goto err; 306 sess = SSL_get1_session(cssl); 307 if (!TEST_ptr(sess)) 308 goto err; 309 SSL_shutdown(cssl); 310 SSL_shutdown(sssl); 311 SSL_free(sssl); 312 SSL_free(cssl); 313 sssl = cssl = NULL; 314 } 315 316 if ((tst >= 3 && tst <= 5) || tst >= 9) { 317 /* HRR handshake */ 318 #if defined(OPENSSL_NO_EC) 319 # if !defined(OPENSSL_NO_DH) 320 if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "ffdhe3072"))) 321 goto err; 322 # endif 323 #else 324 if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "P-256"))) 325 goto err; 326 #endif 327 } 328 329 s_to_c_fbio = BIO_new(bio_f_watchccs_filter()); 330 c_to_s_fbio = BIO_new(bio_f_watchccs_filter()); 331 if (!TEST_ptr(s_to_c_fbio) 332 || !TEST_ptr(c_to_s_fbio)) { 333 BIO_free(s_to_c_fbio); 334 BIO_free(c_to_s_fbio); 335 goto err; 336 } 337 338 /* BIOs get freed on error */ 339 if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, s_to_c_fbio, 340 c_to_s_fbio))) 341 goto err; 342 343 if (tst >= 6) { 344 /* Early data */ 345 if (!TEST_true(SSL_set_session(cssl, sess)) 346 || !TEST_true(SSL_write_early_data(cssl, msg, strlen(msg), 347 &written)) 348 || (tst <= 8 349 && !TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf), 350 &readbytes), 351 SSL_READ_EARLY_DATA_SUCCESS))) 352 goto err; 353 if (tst <= 8) { 354 if (!TEST_int_gt(SSL_connect(cssl), 0)) 355 goto err; 356 } else { 357 if (!TEST_int_le(SSL_connect(cssl), 0)) 358 goto err; 359 } 360 if (!TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf), 361 &readbytes), 362 SSL_READ_EARLY_DATA_FINISH)) 363 goto err; 364 } 365 366 /* Perform handshake (or complete it if doing early data ) */ 367 if (!TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))) 368 goto err; 369 370 /* 371 * Check there were no unexpected CCS messages, all record versions 372 * were as expected, and that the session ids were reflected by the server 373 * correctly. 374 */ 375 if (!TEST_false(badccs) || !TEST_false(badvers) || !TEST_false(badsessid)) 376 goto err; 377 378 switch (tst) { 379 case 0: 380 if (!TEST_true(sccsseen) 381 || !TEST_true(ccsaftersh) 382 || !TEST_false(ccsbeforesh) 383 || !TEST_size_t_gt(chsessidlen, 0)) 384 goto err; 385 break; 386 387 case 1: 388 if (!TEST_true(sccsseen) 389 || !TEST_false(ccsaftersh) 390 || !TEST_false(ccsbeforesh) 391 || !TEST_size_t_eq(chsessidlen, 0)) 392 goto err; 393 break; 394 395 case 2: 396 if (!TEST_false(sccsseen) 397 || !TEST_true(ccsaftersh) 398 || !TEST_false(ccsbeforesh) 399 || !TEST_size_t_gt(chsessidlen, 0)) 400 goto err; 401 break; 402 403 case 3: 404 if (!TEST_true(sccsseen) 405 || !TEST_true(ccsaftersh) 406 || !TEST_false(ccsbeforesh) 407 || !TEST_size_t_gt(chsessidlen, 0)) 408 goto err; 409 break; 410 411 case 4: 412 if (!TEST_true(sccsseen) 413 || !TEST_false(ccsaftersh) 414 || !TEST_false(ccsbeforesh) 415 || !TEST_size_t_eq(chsessidlen, 0)) 416 goto err; 417 break; 418 419 case 5: 420 if (!TEST_false(sccsseen) 421 || !TEST_true(ccsaftersh) 422 || !TEST_false(ccsbeforesh) 423 || !TEST_size_t_gt(chsessidlen, 0)) 424 goto err; 425 break; 426 427 case 6: 428 if (!TEST_true(sccsseen) 429 || !TEST_false(ccsaftersh) 430 || !TEST_true(ccsbeforesh) 431 || !TEST_size_t_gt(chsessidlen, 0)) 432 goto err; 433 break; 434 435 case 7: 436 if (!TEST_true(sccsseen) 437 || !TEST_false(ccsaftersh) 438 || !TEST_false(ccsbeforesh) 439 || !TEST_size_t_eq(chsessidlen, 0)) 440 goto err; 441 break; 442 443 case 8: 444 if (!TEST_false(sccsseen) 445 || !TEST_false(ccsaftersh) 446 || !TEST_true(ccsbeforesh) 447 || !TEST_size_t_gt(chsessidlen, 0)) 448 goto err; 449 break; 450 451 case 9: 452 if (!TEST_true(sccsseen) 453 || !TEST_false(ccsaftersh) 454 || !TEST_true(ccsbeforesh) 455 || !TEST_size_t_gt(chsessidlen, 0)) 456 goto err; 457 break; 458 459 case 10: 460 if (!TEST_true(sccsseen) 461 || !TEST_false(ccsaftersh) 462 || !TEST_false(ccsbeforesh) 463 || !TEST_size_t_eq(chsessidlen, 0)) 464 goto err; 465 break; 466 467 case 11: 468 if (!TEST_false(sccsseen) 469 || !TEST_false(ccsaftersh) 470 || !TEST_true(ccsbeforesh) 471 || !TEST_size_t_gt(chsessidlen, 0)) 472 goto err; 473 break; 474 475 default: 476 TEST_error("Invalid test value"); 477 goto err; 478 } 479 480 ret = 1; 481 err: 482 SSL_SESSION_free(sess); 483 SSL_free(sssl); 484 SSL_free(cssl); 485 SSL_CTX_free(sctx); 486 SSL_CTX_free(cctx); 487 488 return ret; 489 } 490 491 OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") 492 493 int setup_tests(void) 494 { 495 if (!test_skip_common_options()) { 496 TEST_error("Error parsing test options\n"); 497 return 0; 498 } 499 500 if (!TEST_ptr(cert = test_get_argument(0)) 501 || !TEST_ptr(privkey = test_get_argument(1))) 502 return 0; 503 504 ADD_ALL_TESTS(test_tls13ccs, 12); 505 506 return 1; 507 } 508 509 void cleanup_tests(void) 510 { 511 BIO_meth_free(method_watchccs); 512 } 513