1 /* 2 * Copyright (C) 2015 Red Hat, Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library. If not, see 16 * <http://www.gnu.org/licenses/>. 17 * 18 * Author: Daniel P. Berrange <berrange@redhat.com> 19 */ 20 21 #include "qemu/osdep.h" 22 23 #include "crypto-tls-x509-helpers.h" 24 #include "crypto-tls-psk-helpers.h" 25 #include "crypto/tlscredsx509.h" 26 #include "crypto/tlscredspsk.h" 27 #include "crypto/tlssession.h" 28 #include "qom/object_interfaces.h" 29 #include "qapi/error.h" 30 #include "qemu/module.h" 31 #include "qemu/sockets.h" 32 #include "authz/list.h" 33 34 #define WORKDIR "tests/test-crypto-tlssession-work/" 35 #define PSKFILE WORKDIR "keys.psk" 36 #define KEYFILE WORKDIR "key-ctx.pem" 37 38 static ssize_t testWrite(const char *buf, size_t len, void *opaque) 39 { 40 int *fd = opaque; 41 42 return write(*fd, buf, len); 43 } 44 45 static ssize_t testRead(char *buf, size_t len, void *opaque) 46 { 47 int *fd = opaque; 48 49 return read(*fd, buf, len); 50 } 51 52 static QCryptoTLSCreds *test_tls_creds_psk_create( 53 QCryptoTLSCredsEndpoint endpoint, 54 const char *dir) 55 { 56 Object *parent = object_get_objects_root(); 57 Object *creds = object_new_with_props( 58 TYPE_QCRYPTO_TLS_CREDS_PSK, 59 parent, 60 (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? 61 "testtlscredsserver" : "testtlscredsclient"), 62 &error_abort, 63 "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? 64 "server" : "client"), 65 "dir", dir, 66 "priority", "NORMAL", 67 NULL 68 ); 69 return QCRYPTO_TLS_CREDS(creds); 70 } 71 72 73 static void test_crypto_tls_session_psk(void) 74 { 75 QCryptoTLSCreds *clientCreds; 76 QCryptoTLSCreds *serverCreds; 77 QCryptoTLSSession *clientSess = NULL; 78 QCryptoTLSSession *serverSess = NULL; 79 int channel[2]; 80 bool clientShake = false; 81 bool serverShake = false; 82 int ret; 83 84 /* We'll use this for our fake client-server connection */ 85 ret = qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, channel); 86 g_assert(ret == 0); 87 88 /* 89 * We have an evil loop to do the handshake in a single 90 * thread, so we need these non-blocking to avoid deadlock 91 * of ourselves 92 */ 93 qemu_socket_set_nonblock(channel[0]); 94 qemu_socket_set_nonblock(channel[1]); 95 96 clientCreds = test_tls_creds_psk_create( 97 QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, 98 WORKDIR); 99 g_assert(clientCreds != NULL); 100 101 serverCreds = test_tls_creds_psk_create( 102 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, 103 WORKDIR); 104 g_assert(serverCreds != NULL); 105 106 /* Now the real part of the test, setup the sessions */ 107 clientSess = qcrypto_tls_session_new( 108 clientCreds, NULL, NULL, 109 QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, &error_abort); 110 g_assert(clientSess != NULL); 111 112 serverSess = qcrypto_tls_session_new( 113 serverCreds, NULL, NULL, 114 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, &error_abort); 115 g_assert(serverSess != NULL); 116 117 /* For handshake to work, we need to set the I/O callbacks 118 * to read/write over the socketpair 119 */ 120 qcrypto_tls_session_set_callbacks(serverSess, 121 testWrite, testRead, 122 &channel[0]); 123 qcrypto_tls_session_set_callbacks(clientSess, 124 testWrite, testRead, 125 &channel[1]); 126 127 /* 128 * Finally we loop around & around doing handshake on each 129 * session until we get an error, or the handshake completes. 130 * This relies on the socketpair being nonblocking to avoid 131 * deadlocking ourselves upon handshake 132 */ 133 do { 134 int rv; 135 if (!serverShake) { 136 rv = qcrypto_tls_session_handshake(serverSess, 137 &error_abort); 138 g_assert(rv >= 0); 139 if (qcrypto_tls_session_get_handshake_status(serverSess) == 140 QCRYPTO_TLS_HANDSHAKE_COMPLETE) { 141 serverShake = true; 142 } 143 } 144 if (!clientShake) { 145 rv = qcrypto_tls_session_handshake(clientSess, 146 &error_abort); 147 g_assert(rv >= 0); 148 if (qcrypto_tls_session_get_handshake_status(clientSess) == 149 QCRYPTO_TLS_HANDSHAKE_COMPLETE) { 150 clientShake = true; 151 } 152 } 153 } while (!clientShake || !serverShake); 154 155 156 /* Finally make sure the server & client validation is successful. */ 157 g_assert(qcrypto_tls_session_check_credentials(serverSess, 158 &error_abort) == 0); 159 g_assert(qcrypto_tls_session_check_credentials(clientSess, 160 &error_abort) == 0); 161 162 object_unparent(OBJECT(serverCreds)); 163 object_unparent(OBJECT(clientCreds)); 164 165 qcrypto_tls_session_free(serverSess); 166 qcrypto_tls_session_free(clientSess); 167 168 close(channel[0]); 169 close(channel[1]); 170 } 171 172 173 struct QCryptoTLSSessionTestData { 174 const char *servercacrt; 175 const char *clientcacrt; 176 const char *servercrt; 177 const char *clientcrt; 178 bool expectServerFail; 179 bool expectClientFail; 180 const char *hostname; 181 const char *const *wildcards; 182 }; 183 184 static QCryptoTLSCreds *test_tls_creds_x509_create( 185 QCryptoTLSCredsEndpoint endpoint, 186 const char *certdir) 187 { 188 Object *parent = object_get_objects_root(); 189 Object *creds = object_new_with_props( 190 TYPE_QCRYPTO_TLS_CREDS_X509, 191 parent, 192 (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? 193 "testtlscredsserver" : "testtlscredsclient"), 194 &error_abort, 195 "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? 196 "server" : "client"), 197 "dir", certdir, 198 "verify-peer", "yes", 199 "priority", "NORMAL", 200 /* We skip initial sanity checks here because we 201 * want to make sure that problems are being 202 * detected at the TLS session validation stage, 203 * and the test-crypto-tlscreds test already 204 * validate the sanity check code. 205 */ 206 "sanity-check", "no", 207 NULL 208 ); 209 return QCRYPTO_TLS_CREDS(creds); 210 } 211 212 213 /* 214 * This tests validation checking of peer certificates 215 * 216 * This is replicating the checks that are done for an 217 * active TLS session after handshake completes. To 218 * simulate that we create our TLS contexts, skipping 219 * sanity checks. We then get a socketpair, and 220 * initiate a TLS session across them. Finally do 221 * do actual cert validation tests 222 */ 223 static void test_crypto_tls_session_x509(const void *opaque) 224 { 225 struct QCryptoTLSSessionTestData *data = 226 (struct QCryptoTLSSessionTestData *)opaque; 227 QCryptoTLSCreds *clientCreds; 228 QCryptoTLSCreds *serverCreds; 229 QCryptoTLSSession *clientSess = NULL; 230 QCryptoTLSSession *serverSess = NULL; 231 QAuthZList *auth; 232 const char * const *wildcards; 233 int channel[2]; 234 bool clientShake = false; 235 bool serverShake = false; 236 int ret; 237 238 /* We'll use this for our fake client-server connection */ 239 ret = qemu_socketpair(AF_UNIX, SOCK_STREAM, 0, channel); 240 g_assert(ret == 0); 241 242 /* 243 * We have an evil loop to do the handshake in a single 244 * thread, so we need these non-blocking to avoid deadlock 245 * of ourselves 246 */ 247 qemu_socket_set_nonblock(channel[0]); 248 qemu_socket_set_nonblock(channel[1]); 249 250 #define CLIENT_CERT_DIR "tests/test-crypto-tlssession-client/" 251 #define SERVER_CERT_DIR "tests/test-crypto-tlssession-server/" 252 g_mkdir_with_parents(CLIENT_CERT_DIR, 0700); 253 g_mkdir_with_parents(SERVER_CERT_DIR, 0700); 254 255 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT); 256 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT); 257 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY); 258 259 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT); 260 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT); 261 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY); 262 263 g_assert(link(data->servercacrt, 264 SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT) == 0); 265 g_assert(link(data->servercrt, 266 SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT) == 0); 267 g_assert(link(KEYFILE, 268 SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY) == 0); 269 270 g_assert(link(data->clientcacrt, 271 CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT) == 0); 272 g_assert(link(data->clientcrt, 273 CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT) == 0); 274 g_assert(link(KEYFILE, 275 CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY) == 0); 276 277 clientCreds = test_tls_creds_x509_create( 278 QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, 279 CLIENT_CERT_DIR); 280 g_assert(clientCreds != NULL); 281 282 serverCreds = test_tls_creds_x509_create( 283 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, 284 SERVER_CERT_DIR); 285 g_assert(serverCreds != NULL); 286 287 auth = qauthz_list_new("tlssessionacl", 288 QAUTHZ_LIST_POLICY_DENY, 289 &error_abort); 290 wildcards = data->wildcards; 291 while (wildcards && *wildcards) { 292 qauthz_list_append_rule(auth, *wildcards, 293 QAUTHZ_LIST_POLICY_ALLOW, 294 QAUTHZ_LIST_FORMAT_GLOB, 295 &error_abort); 296 wildcards++; 297 } 298 299 /* Now the real part of the test, setup the sessions */ 300 clientSess = qcrypto_tls_session_new( 301 clientCreds, data->hostname, NULL, 302 QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, &error_abort); 303 g_assert(clientSess != NULL); 304 305 serverSess = qcrypto_tls_session_new( 306 serverCreds, NULL, 307 data->wildcards ? "tlssessionacl" : NULL, 308 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, &error_abort); 309 g_assert(serverSess != NULL); 310 311 /* For handshake to work, we need to set the I/O callbacks 312 * to read/write over the socketpair 313 */ 314 qcrypto_tls_session_set_callbacks(serverSess, 315 testWrite, testRead, 316 &channel[0]); 317 qcrypto_tls_session_set_callbacks(clientSess, 318 testWrite, testRead, 319 &channel[1]); 320 321 /* 322 * Finally we loop around & around doing handshake on each 323 * session until we get an error, or the handshake completes. 324 * This relies on the socketpair being nonblocking to avoid 325 * deadlocking ourselves upon handshake 326 */ 327 do { 328 int rv; 329 if (!serverShake) { 330 rv = qcrypto_tls_session_handshake(serverSess, 331 &error_abort); 332 g_assert(rv >= 0); 333 if (qcrypto_tls_session_get_handshake_status(serverSess) == 334 QCRYPTO_TLS_HANDSHAKE_COMPLETE) { 335 serverShake = true; 336 } 337 } 338 if (!clientShake) { 339 rv = qcrypto_tls_session_handshake(clientSess, 340 &error_abort); 341 g_assert(rv >= 0); 342 if (qcrypto_tls_session_get_handshake_status(clientSess) == 343 QCRYPTO_TLS_HANDSHAKE_COMPLETE) { 344 clientShake = true; 345 } 346 } 347 } while (!clientShake || !serverShake); 348 349 350 /* Finally make sure the server validation does what 351 * we were expecting 352 */ 353 if (qcrypto_tls_session_check_credentials( 354 serverSess, data->expectServerFail ? NULL : &error_abort) < 0) { 355 g_assert(data->expectServerFail); 356 } else { 357 g_assert(!data->expectServerFail); 358 } 359 360 /* 361 * And the same for the client validation check 362 */ 363 if (qcrypto_tls_session_check_credentials( 364 clientSess, data->expectClientFail ? NULL : &error_abort) < 0) { 365 g_assert(data->expectClientFail); 366 } else { 367 g_assert(!data->expectClientFail); 368 } 369 370 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT); 371 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_CERT); 372 unlink(SERVER_CERT_DIR QCRYPTO_TLS_CREDS_X509_SERVER_KEY); 373 374 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CA_CERT); 375 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_CERT); 376 unlink(CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY); 377 378 rmdir(CLIENT_CERT_DIR); 379 rmdir(SERVER_CERT_DIR); 380 381 object_unparent(OBJECT(serverCreds)); 382 object_unparent(OBJECT(clientCreds)); 383 object_unparent(OBJECT(auth)); 384 385 qcrypto_tls_session_free(serverSess); 386 qcrypto_tls_session_free(clientSess); 387 388 close(channel[0]); 389 close(channel[1]); 390 } 391 392 393 int main(int argc, char **argv) 394 { 395 int ret; 396 397 module_call_init(MODULE_INIT_QOM); 398 g_test_init(&argc, &argv, NULL); 399 g_setenv("GNUTLS_FORCE_FIPS_MODE", "2", 1); 400 401 g_mkdir_with_parents(WORKDIR, 0700); 402 403 test_tls_init(KEYFILE); 404 test_tls_psk_init(PSKFILE); 405 406 /* Simple initial test using Pre-Shared Keys. */ 407 g_test_add_func("/qcrypto/tlssession/psk", 408 test_crypto_tls_session_psk); 409 410 /* More complex tests using X.509 certificates. */ 411 # define TEST_SESS_REG(name, caCrt, \ 412 serverCrt, clientCrt, \ 413 expectServerFail, expectClientFail, \ 414 hostname, wildcards) \ 415 struct QCryptoTLSSessionTestData name = { \ 416 caCrt, caCrt, serverCrt, clientCrt, \ 417 expectServerFail, expectClientFail, \ 418 hostname, wildcards \ 419 }; \ 420 g_test_add_data_func("/qcrypto/tlssession/" # name, \ 421 &name, test_crypto_tls_session_x509); \ 422 423 424 # define TEST_SESS_REG_EXT(name, serverCaCrt, clientCaCrt, \ 425 serverCrt, clientCrt, \ 426 expectServerFail, expectClientFail, \ 427 hostname, wildcards) \ 428 struct QCryptoTLSSessionTestData name = { \ 429 serverCaCrt, clientCaCrt, serverCrt, clientCrt, \ 430 expectServerFail, expectClientFail, \ 431 hostname, wildcards \ 432 }; \ 433 g_test_add_data_func("/qcrypto/tlssession/" # name, \ 434 &name, test_crypto_tls_session_x509); \ 435 436 /* A perfect CA, perfect client & perfect server */ 437 438 /* Basic:CA:critical */ 439 TLS_ROOT_REQ(cacertreq, 440 "UK", "qemu CA", NULL, NULL, NULL, NULL, 441 true, true, true, 442 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 443 false, false, NULL, NULL, 444 0, 0); 445 446 TLS_ROOT_REQ(altcacertreq, 447 "UK", "qemu CA 1", NULL, NULL, NULL, NULL, 448 true, true, true, 449 false, false, 0, 450 false, false, NULL, NULL, 451 0, 0); 452 453 TLS_CERT_REQ(servercertreq, cacertreq, 454 "UK", "qemu.org", NULL, NULL, NULL, NULL, 455 true, true, false, 456 true, true, 457 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 458 true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 459 0, 0); 460 TLS_CERT_REQ(clientcertreq, cacertreq, 461 "UK", "qemu", NULL, NULL, NULL, NULL, 462 true, true, false, 463 true, true, 464 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 465 true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 466 0, 0); 467 468 TLS_CERT_REQ(clientcertaltreq, altcacertreq, 469 "UK", "qemu", NULL, NULL, NULL, NULL, 470 true, true, false, 471 true, true, 472 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 473 true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 474 0, 0); 475 476 TEST_SESS_REG(basicca, cacertreq.filename, 477 servercertreq.filename, clientcertreq.filename, 478 false, false, "qemu.org", NULL); 479 TEST_SESS_REG_EXT(differentca, cacertreq.filename, 480 altcacertreq.filename, servercertreq.filename, 481 clientcertaltreq.filename, true, true, "qemu.org", NULL); 482 483 484 /* When an altname is set, the CN is ignored, so it must be duplicated 485 * as an altname for it to match */ 486 TLS_CERT_REQ(servercertalt1req, cacertreq, 487 "UK", "qemu.org", "www.qemu.org", "qemu.org", 488 "192.168.122.1", "fec0::dead:beaf", 489 true, true, false, 490 true, true, 491 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 492 true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 493 0, 0); 494 /* This intentionally doesn't replicate */ 495 TLS_CERT_REQ(servercertalt2req, cacertreq, 496 "UK", "qemu.org", "www.qemu.org", "wiki.qemu.org", 497 "192.168.122.1", "fec0::dead:beaf", 498 true, true, false, 499 true, true, 500 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 501 true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 502 0, 0); 503 504 TEST_SESS_REG(altname1, cacertreq.filename, 505 servercertalt1req.filename, clientcertreq.filename, 506 false, false, "qemu.org", NULL); 507 TEST_SESS_REG(altname2, cacertreq.filename, 508 servercertalt1req.filename, clientcertreq.filename, 509 false, false, "www.qemu.org", NULL); 510 TEST_SESS_REG(altname3, cacertreq.filename, 511 servercertalt1req.filename, clientcertreq.filename, 512 false, true, "wiki.qemu.org", NULL); 513 514 TEST_SESS_REG(altname4, cacertreq.filename, 515 servercertalt1req.filename, clientcertreq.filename, 516 false, false, "192.168.122.1", NULL); 517 TEST_SESS_REG(altname5, cacertreq.filename, 518 servercertalt1req.filename, clientcertreq.filename, 519 false, false, "fec0::dead:beaf", NULL); 520 521 TEST_SESS_REG(altname6, cacertreq.filename, 522 servercertalt2req.filename, clientcertreq.filename, 523 false, true, "qemu.org", NULL); 524 TEST_SESS_REG(altname7, cacertreq.filename, 525 servercertalt2req.filename, clientcertreq.filename, 526 false, false, "www.qemu.org", NULL); 527 TEST_SESS_REG(altname8, cacertreq.filename, 528 servercertalt2req.filename, clientcertreq.filename, 529 false, false, "wiki.qemu.org", NULL); 530 531 const char *const wildcards1[] = { 532 "C=UK,CN=dogfood", 533 NULL, 534 }; 535 const char *const wildcards2[] = { 536 "C=UK,CN=qemu", 537 NULL, 538 }; 539 const char *const wildcards3[] = { 540 "C=UK,CN=dogfood", 541 "C=UK,CN=qemu", 542 NULL, 543 }; 544 const char *const wildcards4[] = { 545 "C=UK,CN=qemustuff", 546 NULL, 547 }; 548 const char *const wildcards5[] = { 549 "C=UK,CN=qemu*", 550 NULL, 551 }; 552 const char *const wildcards6[] = { 553 "C=UK,CN=*emu*", 554 NULL, 555 }; 556 557 TEST_SESS_REG(wildcard1, cacertreq.filename, 558 servercertreq.filename, clientcertreq.filename, 559 true, false, "qemu.org", wildcards1); 560 TEST_SESS_REG(wildcard2, cacertreq.filename, 561 servercertreq.filename, clientcertreq.filename, 562 false, false, "qemu.org", wildcards2); 563 TEST_SESS_REG(wildcard3, cacertreq.filename, 564 servercertreq.filename, clientcertreq.filename, 565 false, false, "qemu.org", wildcards3); 566 TEST_SESS_REG(wildcard4, cacertreq.filename, 567 servercertreq.filename, clientcertreq.filename, 568 true, false, "qemu.org", wildcards4); 569 TEST_SESS_REG(wildcard5, cacertreq.filename, 570 servercertreq.filename, clientcertreq.filename, 571 false, false, "qemu.org", wildcards5); 572 TEST_SESS_REG(wildcard6, cacertreq.filename, 573 servercertreq.filename, clientcertreq.filename, 574 false, false, "qemu.org", wildcards6); 575 576 TLS_ROOT_REQ(cacertrootreq, 577 "UK", "qemu root", NULL, NULL, NULL, NULL, 578 true, true, true, 579 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 580 false, false, NULL, NULL, 581 0, 0); 582 TLS_CERT_REQ(cacertlevel1areq, cacertrootreq, 583 "UK", "qemu level 1a", NULL, NULL, NULL, NULL, 584 true, true, true, 585 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 586 false, false, NULL, NULL, 587 0, 0); 588 TLS_CERT_REQ(cacertlevel1breq, cacertrootreq, 589 "UK", "qemu level 1b", NULL, NULL, NULL, NULL, 590 true, true, true, 591 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 592 false, false, NULL, NULL, 593 0, 0); 594 TLS_CERT_REQ(cacertlevel2areq, cacertlevel1areq, 595 "UK", "qemu level 2a", NULL, NULL, NULL, NULL, 596 true, true, true, 597 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 598 false, false, NULL, NULL, 599 0, 0); 600 TLS_CERT_REQ(servercertlevel3areq, cacertlevel2areq, 601 "UK", "qemu.org", NULL, NULL, NULL, NULL, 602 true, true, false, 603 true, true, 604 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 605 true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 606 0, 0); 607 TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, 608 "UK", "qemu client level 2b", NULL, NULL, NULL, NULL, 609 true, true, false, 610 true, true, 611 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 612 true, true, GNUTLS_KP_TLS_WWW_CLIENT, NULL, 613 0, 0); 614 615 gnutls_x509_crt_t certchain[] = { 616 cacertrootreq.crt, 617 cacertlevel1areq.crt, 618 cacertlevel1breq.crt, 619 cacertlevel2areq.crt, 620 }; 621 622 test_tls_write_cert_chain(WORKDIR "cacertchain-sess.pem", 623 certchain, 624 G_N_ELEMENTS(certchain)); 625 626 TEST_SESS_REG(cachain, WORKDIR "cacertchain-sess.pem", 627 servercertlevel3areq.filename, clientcertlevel2breq.filename, 628 false, false, "qemu.org", NULL); 629 630 ret = g_test_run(); 631 632 test_tls_discard_cert(&clientcertreq); 633 test_tls_discard_cert(&clientcertaltreq); 634 635 test_tls_discard_cert(&servercertreq); 636 test_tls_discard_cert(&servercertalt1req); 637 test_tls_discard_cert(&servercertalt2req); 638 639 test_tls_discard_cert(&cacertreq); 640 test_tls_discard_cert(&altcacertreq); 641 642 test_tls_discard_cert(&cacertrootreq); 643 test_tls_discard_cert(&cacertlevel1areq); 644 test_tls_discard_cert(&cacertlevel1breq); 645 test_tls_discard_cert(&cacertlevel2areq); 646 test_tls_discard_cert(&servercertlevel3areq); 647 test_tls_discard_cert(&clientcertlevel2breq); 648 unlink(WORKDIR "cacertchain-sess.pem"); 649 650 test_tls_psk_cleanup(PSKFILE); 651 test_tls_cleanup(KEYFILE); 652 rmdir(WORKDIR); 653 654 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; 655 } 656