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