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