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