test-crypto-tlssession.c (23764B)
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 38static 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 45static ssize_t testRead(char *buf, size_t len, void *opaque) 46{ 47 int *fd = opaque; 48 49 return read(*fd, buf, len); 50} 51 52static 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 73static 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 = 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_set_nonblock(channel[0]); 94 qemu_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 173struct 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 184static 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 */ 223static 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 = 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_set_nonblock(channel[0]); 248 qemu_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 mkdir(CLIENT_CERT_DIR, 0700); 253 mkdir(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 393int 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 mkdir(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 servercertalt2req.filename, clientcertreq.filename, 516 false, true, "qemu.org", NULL); 517 TEST_SESS_REG(altname5, cacertreq.filename, 518 servercertalt2req.filename, clientcertreq.filename, 519 false, false, "www.qemu.org", NULL); 520 TEST_SESS_REG(altname6, cacertreq.filename, 521 servercertalt2req.filename, clientcertreq.filename, 522 false, false, "wiki.qemu.org", NULL); 523 524 const char *const wildcards1[] = { 525 "C=UK,CN=dogfood", 526 NULL, 527 }; 528 const char *const wildcards2[] = { 529 "C=UK,CN=qemu", 530 NULL, 531 }; 532 const char *const wildcards3[] = { 533 "C=UK,CN=dogfood", 534 "C=UK,CN=qemu", 535 NULL, 536 }; 537 const char *const wildcards4[] = { 538 "C=UK,CN=qemustuff", 539 NULL, 540 }; 541 const char *const wildcards5[] = { 542 "C=UK,CN=qemu*", 543 NULL, 544 }; 545 const char *const wildcards6[] = { 546 "C=UK,CN=*emu*", 547 NULL, 548 }; 549 550 TEST_SESS_REG(wildcard1, cacertreq.filename, 551 servercertreq.filename, clientcertreq.filename, 552 true, false, "qemu.org", wildcards1); 553 TEST_SESS_REG(wildcard2, cacertreq.filename, 554 servercertreq.filename, clientcertreq.filename, 555 false, false, "qemu.org", wildcards2); 556 TEST_SESS_REG(wildcard3, cacertreq.filename, 557 servercertreq.filename, clientcertreq.filename, 558 false, false, "qemu.org", wildcards3); 559 TEST_SESS_REG(wildcard4, cacertreq.filename, 560 servercertreq.filename, clientcertreq.filename, 561 true, false, "qemu.org", wildcards4); 562 TEST_SESS_REG(wildcard5, cacertreq.filename, 563 servercertreq.filename, clientcertreq.filename, 564 false, false, "qemu.org", wildcards5); 565 TEST_SESS_REG(wildcard6, cacertreq.filename, 566 servercertreq.filename, clientcertreq.filename, 567 false, false, "qemu.org", wildcards6); 568 569 TLS_ROOT_REQ(cacertrootreq, 570 "UK", "qemu root", NULL, NULL, NULL, NULL, 571 true, true, true, 572 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 573 false, false, NULL, NULL, 574 0, 0); 575 TLS_CERT_REQ(cacertlevel1areq, cacertrootreq, 576 "UK", "qemu level 1a", NULL, NULL, NULL, NULL, 577 true, true, true, 578 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 579 false, false, NULL, NULL, 580 0, 0); 581 TLS_CERT_REQ(cacertlevel1breq, cacertrootreq, 582 "UK", "qemu level 1b", NULL, NULL, NULL, NULL, 583 true, true, true, 584 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 585 false, false, NULL, NULL, 586 0, 0); 587 TLS_CERT_REQ(cacertlevel2areq, cacertlevel1areq, 588 "UK", "qemu level 2a", NULL, NULL, NULL, NULL, 589 true, true, true, 590 true, true, GNUTLS_KEY_KEY_CERT_SIGN, 591 false, false, NULL, NULL, 592 0, 0); 593 TLS_CERT_REQ(servercertlevel3areq, cacertlevel2areq, 594 "UK", "qemu.org", NULL, NULL, NULL, NULL, 595 true, true, false, 596 true, true, 597 GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT, 598 true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL, 599 0, 0); 600 TLS_CERT_REQ(clientcertlevel2breq, cacertlevel1breq, 601 "UK", "qemu client level 2b", 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_CLIENT, NULL, 606 0, 0); 607 608 gnutls_x509_crt_t certchain[] = { 609 cacertrootreq.crt, 610 cacertlevel1areq.crt, 611 cacertlevel1breq.crt, 612 cacertlevel2areq.crt, 613 }; 614 615 test_tls_write_cert_chain(WORKDIR "cacertchain-sess.pem", 616 certchain, 617 G_N_ELEMENTS(certchain)); 618 619 TEST_SESS_REG(cachain, WORKDIR "cacertchain-sess.pem", 620 servercertlevel3areq.filename, clientcertlevel2breq.filename, 621 false, false, "qemu.org", NULL); 622 623 ret = g_test_run(); 624 625 test_tls_discard_cert(&clientcertreq); 626 test_tls_discard_cert(&clientcertaltreq); 627 628 test_tls_discard_cert(&servercertreq); 629 test_tls_discard_cert(&servercertalt1req); 630 test_tls_discard_cert(&servercertalt2req); 631 632 test_tls_discard_cert(&cacertreq); 633 test_tls_discard_cert(&altcacertreq); 634 635 test_tls_discard_cert(&cacertrootreq); 636 test_tls_discard_cert(&cacertlevel1areq); 637 test_tls_discard_cert(&cacertlevel1breq); 638 test_tls_discard_cert(&cacertlevel2areq); 639 test_tls_discard_cert(&servercertlevel3areq); 640 test_tls_discard_cert(&clientcertlevel2breq); 641 unlink(WORKDIR "cacertchain-sess.pem"); 642 643 test_tls_psk_cleanup(PSKFILE); 644 test_tls_cleanup(KEYFILE); 645 rmdir(WORKDIR); 646 647 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; 648}