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