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