diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/Makefile.include | 4 | ||||
| -rw-r--r-- | tests/benchmark-crypto-cipher.c | 6 | ||||
| -rw-r--r-- | tests/benchmark-crypto-hash.c | 5 | ||||
| -rw-r--r-- | tests/benchmark-crypto-hmac.c | 6 | ||||
| -rw-r--r-- | tests/crypto-tls-psk-helpers.c | 50 | ||||
| -rw-r--r-- | tests/crypto-tls-psk-helpers.h | 29 | ||||
| -rw-r--r-- | tests/qemu-iotests/222 | 155 | ||||
| -rw-r--r-- | tests/qemu-iotests/222.out | 67 | ||||
| -rwxr-xr-x | tests/qemu-iotests/223 | 138 | ||||
| -rw-r--r-- | tests/qemu-iotests/223.out | 49 | ||||
| -rw-r--r-- | tests/qemu-iotests/group | 2 | ||||
| -rw-r--r-- | tests/test-crypto-tlssession.c | 179 | ||||
| -rw-r--r-- | tests/test-cutils.c | 21 | ||||
| -rw-r--r-- | tests/test-keyval.c | 7 | ||||
| -rw-r--r-- | tests/test-qemu-opts.c | 9 |
15 files changed, 680 insertions, 47 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include index e8bb2d8f66..8859e88ffb 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -723,7 +723,9 @@ tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \ tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS) tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \ - tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) + tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o \ + tests/crypto-tls-psk-helpers.o \ + $(test-crypto-obj-y) tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o \ tests/socket-helpers.o $(test-util-obj-y) tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y) diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c index cf98443468..f5a0d0bc32 100644 --- a/tests/benchmark-crypto-cipher.c +++ b/tests/benchmark-crypto-cipher.c @@ -11,6 +11,7 @@ * top-level directory. */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "crypto/init.h" #include "crypto/cipher.h" @@ -56,8 +57,7 @@ static void test_cipher_speed(const void *opaque) total += chunk_size; } while (g_test_timer_elapsed() < 5.0); - total /= 1024 * 1024; /* to MB */ - + total /= MiB; g_print("cbc(aes128): "); g_print("Testing chunk_size %zu bytes ", chunk_size); g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last()); @@ -78,7 +78,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_assert(qcrypto_init(NULL) == 0); - for (i = 512; i <= (64 * 1204); i *= 2) { + for (i = 512; i <= 64 * KiB; i *= 2) { memset(name, 0 , sizeof(name)); snprintf(name, sizeof(name), "/crypto/cipher/speed-%zu", i); g_test_add_data_func(name, (void *)i, test_cipher_speed); diff --git a/tests/benchmark-crypto-hash.c b/tests/benchmark-crypto-hash.c index 122bfb6b85..9b6f7a9155 100644 --- a/tests/benchmark-crypto-hash.c +++ b/tests/benchmark-crypto-hash.c @@ -11,6 +11,7 @@ * top-level directory. */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "crypto/init.h" #include "crypto/hash.h" @@ -39,7 +40,7 @@ static void test_hash_speed(const void *opaque) total += chunk_size; } while (g_test_timer_elapsed() < 5.0); - total /= 1024 * 1024; /* to MB */ + total /= MiB; g_print("sha256: "); g_print("Testing chunk_size %zu bytes ", chunk_size); g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last()); @@ -57,7 +58,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_assert(qcrypto_init(NULL) == 0); - for (i = 512; i <= (64 * 1204); i *= 2) { + for (i = 512; i <= 64 * KiB; i *= 2) { memset(name, 0 , sizeof(name)); snprintf(name, sizeof(name), "/crypto/hash/speed-%zu", i); g_test_add_data_func(name, (void *)i, test_hash_speed); diff --git a/tests/benchmark-crypto-hmac.c b/tests/benchmark-crypto-hmac.c index c30250df3e..f1dfa240cb 100644 --- a/tests/benchmark-crypto-hmac.c +++ b/tests/benchmark-crypto-hmac.c @@ -11,6 +11,7 @@ * top-level directory. */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "crypto/init.h" #include "crypto/hmac.h" @@ -53,8 +54,7 @@ static void test_hmac_speed(const void *opaque) total += chunk_size; } while (g_test_timer_elapsed() < 5.0); - total /= 1024 * 1024; /* to MB */ - + total /= MiB; g_print("hmac(sha256): "); g_print("Testing chunk_size %zu bytes ", chunk_size); g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last()); @@ -72,7 +72,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_assert(qcrypto_init(NULL) == 0); - for (i = 512; i <= (64 * 1204); i *= 2) { + for (i = 512; i <= 64 * KiB; i *= 2) { memset(name, 0 , sizeof(name)); snprintf(name, sizeof(name), "/crypto/hmac/speed-%zu", i); g_test_add_data_func(name, (void *)i, test_hmac_speed); diff --git a/tests/crypto-tls-psk-helpers.c b/tests/crypto-tls-psk-helpers.c new file mode 100644 index 0000000000..a8395477c3 --- /dev/null +++ b/tests/crypto-tls-psk-helpers.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Richard W.M. Jones <rjones@redhat.com> + */ + +#include "qemu/osdep.h" + +/* Include this first because it defines QCRYPTO_HAVE_TLS_TEST_SUPPORT */ +#include "crypto-tls-x509-helpers.h" + +#include "crypto-tls-psk-helpers.h" +#include "qemu/sockets.h" + +#ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT + +void test_tls_psk_init(const char *pskfile) +{ + FILE *fp; + + fp = fopen(pskfile, "w"); + if (fp == NULL) { + g_critical("Failed to create pskfile %s", pskfile); + abort(); + } + /* Don't do this in real applications! Use psktool. */ + fprintf(fp, "qemu:009d5638c40fde0c\n"); + fclose(fp); +} + +void test_tls_psk_cleanup(const char *pskfile) +{ + unlink(pskfile); +} + +#endif /* QCRYPTO_HAVE_TLS_TEST_SUPPORT */ diff --git a/tests/crypto-tls-psk-helpers.h b/tests/crypto-tls-psk-helpers.h new file mode 100644 index 0000000000..9aec29f1a0 --- /dev/null +++ b/tests/crypto-tls-psk-helpers.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Richard W.M. Jones <rjones@redhat.com> + */ + +#include <gnutls/gnutls.h> + +#ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT +# include "qemu-common.h" + +void test_tls_psk_init(const char *keyfile); +void test_tls_psk_cleanup(const char *keyfile); + +#endif /* QCRYPTO_HAVE_TLS_TEST_SUPPORT */ diff --git a/tests/qemu-iotests/222 b/tests/qemu-iotests/222 new file mode 100644 index 0000000000..ff3bfc1470 --- /dev/null +++ b/tests/qemu-iotests/222 @@ -0,0 +1,155 @@ +#!/usr/bin/env python +# +# This test covers the basic fleecing workflow, which provides a +# point-in-time snapshot of a node that can be queried over NBD. +# +# Copyright (C) 2018 Red Hat, Inc. +# John helped, too. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Creator/Owner: John Snow <jsnow@redhat.com> + +import iotests +from iotests import log, qemu_img, qemu_io, qemu_io_silent + +iotests.verify_platform(['linux']) + +patterns = [("0x5d", "0", "64k"), + ("0xd5", "1M", "64k"), + ("0xdc", "32M", "64k"), + ("0xcd", "0x3ff0000", "64k")] # 64M - 64K + +overwrite = [("0xab", "0", "64k"), # Full overwrite + ("0xad", "0x00f8000", "64k"), # Partial-left (1M-32K) + ("0x1d", "0x2008000", "64k"), # Partial-right (32M+32K) + ("0xea", "0x3fe0000", "64k")] # Adjacent-left (64M - 128K) + +zeroes = [("0", "0x00f8000", "32k"), # Left-end of partial-left (1M-32K) + ("0", "0x2010000", "32k"), # Right-end of partial-right (32M+64K) + ("0", "0x3fe0000", "64k")] # overwrite[3] + +remainder = [("0xd5", "0x108000", "32k"), # Right-end of partial-left [1] + ("0xdc", "32M", "32k"), # Left-end of partial-right [2] + ("0xcd", "0x3ff0000", "64k")] # patterns[3] + +with iotests.FilePath('base.img') as base_img_path, \ + iotests.FilePath('fleece.img') as fleece_img_path, \ + iotests.FilePath('nbd.sock') as nbd_sock_path, \ + iotests.VM() as vm: + + log('--- Setting up images ---') + log('') + + assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0 + assert qemu_img('create', '-f', "qcow2", fleece_img_path, '64M') == 0 + + for p in patterns: + qemu_io('-f', iotests.imgfmt, + '-c', 'write -P%s %s %s' % p, base_img_path) + + log('Done') + + log('') + log('--- Launching VM ---') + log('') + + vm.add_drive(base_img_path) + vm.launch() + log('Done') + + log('') + log('--- Setting up Fleecing Graph ---') + log('') + + src_node = "drive0" + tgt_node = "fleeceNode" + + # create tgt_node backed by src_node + log(vm.qmp("blockdev-add", **{ + "driver": "qcow2", + "node-name": tgt_node, + "file": { + "driver": "file", + "filename": fleece_img_path, + }, + "backing": src_node, + })) + + # Establish COW from source to fleecing node + log(vm.qmp("blockdev-backup", + device=src_node, + target=tgt_node, + sync="none")) + + log('') + log('--- Setting up NBD Export ---') + log('') + + nbd_uri = 'nbd+unix:///%s?socket=%s' % (tgt_node, nbd_sock_path) + log(vm.qmp("nbd-server-start", + **{"addr": { "type": "unix", + "data": { "path": nbd_sock_path } } })) + + log(vm.qmp("nbd-server-add", device=tgt_node)) + + log('') + log('--- Sanity Check ---') + log('') + + for p in (patterns + zeroes): + cmd = "read -P%s %s %s" % p + log(cmd) + assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0 + + log('') + log('--- Testing COW ---') + log('') + + for p in overwrite: + cmd = "write -P%s %s %s" % p + log(cmd) + log(vm.hmp_qemu_io(src_node, cmd)) + + log('') + log('--- Verifying Data ---') + log('') + + for p in (patterns + zeroes): + cmd = "read -P%s %s %s" % p + log(cmd) + assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0 + + log('') + log('--- Cleanup ---') + log('') + + log(vm.qmp('block-job-cancel', device=src_node)) + log(vm.event_wait('BLOCK_JOB_CANCELLED'), + filters=[iotests.filter_qmp_event]) + log(vm.qmp('nbd-server-stop')) + log(vm.qmp('blockdev-del', node_name=tgt_node)) + vm.shutdown() + + log('') + log('--- Confirming writes ---') + log('') + + for p in (overwrite + remainder): + cmd = "read -P%s %s %s" % p + log(cmd) + assert qemu_io_silent(base_img_path, '-c', cmd) == 0 + + log('') + log('Done') diff --git a/tests/qemu-iotests/222.out b/tests/qemu-iotests/222.out new file mode 100644 index 0000000000..48f336a02b --- /dev/null +++ b/tests/qemu-iotests/222.out @@ -0,0 +1,67 @@ +--- Setting up images --- + +Done + +--- Launching VM --- + +Done + +--- Setting up Fleecing Graph --- + +{u'return': {}} +{u'return': {}} + +--- Setting up NBD Export --- + +{u'return': {}} +{u'return': {}} + +--- Sanity Check --- + +read -P0x5d 0 64k +read -P0xd5 1M 64k +read -P0xdc 32M 64k +read -P0xcd 0x3ff0000 64k +read -P0 0x00f8000 32k +read -P0 0x2010000 32k +read -P0 0x3fe0000 64k + +--- Testing COW --- + +write -P0xab 0 64k +{u'return': u''} +write -P0xad 0x00f8000 64k +{u'return': u''} +write -P0x1d 0x2008000 64k +{u'return': u''} +write -P0xea 0x3fe0000 64k +{u'return': u''} + +--- Verifying Data --- + +read -P0x5d 0 64k +read -P0xd5 1M 64k +read -P0xdc 32M 64k +read -P0xcd 0x3ff0000 64k +read -P0 0x00f8000 32k +read -P0 0x2010000 32k +read -P0 0x3fe0000 64k + +--- Cleanup --- + +{u'return': {}} +{u'timestamp': {u'seconds': 'SECS', u'microseconds': 'USECS'}, u'data': {u'device': u'drive0', u'type': u'backup', u'speed': 0, u'len': 67108864, u'offset': 393216}, u'event': u'BLOCK_JOB_CANCELLED'} +{u'return': {}} +{u'return': {}} + +--- Confirming writes --- + +read -P0xab 0 64k +read -P0xad 0x00f8000 64k +read -P0x1d 0x2008000 64k +read -P0xea 0x3fe0000 64k +read -P0xd5 0x108000 32k +read -P0xdc 32M 32k +read -P0xcd 0x3ff0000 64k + +Done diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 new file mode 100755 index 0000000000..b63b7a4f9e --- /dev/null +++ b/tests/qemu-iotests/223 @@ -0,0 +1,138 @@ +#!/bin/bash +# +# Test reading dirty bitmap over NBD +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +seq="$(basename $0)" +echo "QA output created by $seq" + +here="$PWD" +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + _cleanup_qemu + rm -f "$TEST_DIR/nbd" +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt qcow2 +_supported_proto file # uses NBD as well +_supported_os Linux + +function do_run_qemu() +{ + echo Testing: "$@" + $QEMU -nographic -qmp stdio -serial none "$@" + echo +} + +function run_qemu() +{ + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \ + | _filter_qemu | _filter_imgfmt \ + | _filter_actual_image_size +} + +echo +echo "=== Create partially sparse image, then add dirty bitmap ===" +echo + +_make_test_img 4M +$QEMU_IO -c 'w -P 0x11 1M 2M' "$TEST_IMG" | _filter_qemu_io +run_qemu <<EOF +{ "execute": "qmp_capabilities" } +{ "execute": "blockdev-add", + "arguments": { + "driver": "$IMGFMT", + "node-name": "n", + "file": { + "driver": "file", + "filename": "$TEST_IMG" + } + } +} +{ "execute": "block-dirty-bitmap-add", + "arguments": { + "node": "n", + "name": "b", + "persistent": true + } +} +{ "execute": "quit" } +EOF + +echo +echo "=== Write part of the file under active bitmap ===" +echo + +$QEMU_IO -c 'w -P 0x22 2M 2M' "$TEST_IMG" | _filter_qemu_io + +echo +echo "=== End dirty bitmap, and start serving image over NBD ===" +echo + +_launch_qemu 2> >(_filter_nbd) + +silent= +_send_qemu_cmd $QEMU_HANDLE '{"execute":"qmp_capabilities"}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"blockdev-add", + "arguments":{"driver":"qcow2", "node-name":"n", + "file":{"driver":"file", "filename":"'"$TEST_IMG"'"}}}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-block-dirty-bitmap-disable", + "arguments":{"node":"n", "name":"b"}}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-start", + "arguments":{"addr":{"type":"unix", + "data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", + "arguments":{"device":"n"}}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", + "arguments":{"name":"n", "bitmap":"b"}}' "return" + +echo +echo "=== Contrast normal status with dirty-bitmap status ===" +echo + +QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT +IMG="driver=nbd,export=n,server.type=unix,server.path=$TEST_DIR/nbd" +$QEMU_IO -r -c 'r -P 0 0 1m' -c 'r -P 0x11 1m 1m' \ + -c 'r -P 0x22 2m 2m' --image-opts "$IMG" | _filter_qemu_io +$QEMU_IMG map --output=json --image-opts \ + "$IMG" | _filter_qemu_img_map +$QEMU_IMG map --output=json --image-opts \ + "$IMG,x-dirty-bitmap=qemu:dirty-bitmap:b" | _filter_qemu_img_map + +echo +echo "=== End NBD server ===" +echo + +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove", + "arguments":{"name":"n"}}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "return" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return" + +# success, all done +echo '*** done' +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out new file mode 100644 index 0000000000..33021c8e6a --- /dev/null +++ b/tests/qemu-iotests/223.out @@ -0,0 +1,49 @@ +QA output created by 223 + +=== Create partially sparse image, then add dirty bitmap === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4194304 +wrote 2097152/2097152 bytes at offset 1048576 +2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Testing: +QMP_VERSION +{"return": {}} +{"return": {}} +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} + + +=== Write part of the file under active bitmap === + +wrote 2097152/2097152 bytes at offset 2097152 +2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== End dirty bitmap, and start serving image over NBD === + +{"return": {}} +{"return": {}} +{"return": {}} +{"return": {}} +{"return": {}} +{"return": {}} + +=== Contrast normal status with dirty-bitmap status === + +read 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 1048576/1048576 bytes at offset 1048576 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 2097152/2097152 bytes at offset 2097152 +2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false}, +{ "start": 1048576, "length": 3145728, "depth": 0, "zero": false, "data": true}] +[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true}, +{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": false}] + +=== End NBD server === + +{"return": {}} +{"return": {}} +{"return": {}} +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index eea75819d2..af309ebba7 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -220,3 +220,5 @@ 218 rw auto quick 219 rw auto 221 rw auto quick +222 rw auto quick +223 rw auto quick diff --git a/tests/test-crypto-tlssession.c b/tests/test-crypto-tlssession.c index 82f21c27f2..7bd811796e 100644 --- a/tests/test-crypto-tlssession.c +++ b/tests/test-crypto-tlssession.c @@ -21,7 +21,9 @@ #include "qemu/osdep.h" #include "crypto-tls-x509-helpers.h" +#include "crypto-tls-psk-helpers.h" #include "crypto/tlscredsx509.h" +#include "crypto/tlscredspsk.h" #include "crypto/tlssession.h" #include "qom/object_interfaces.h" #include "qapi/error.h" @@ -31,20 +33,9 @@ #ifdef QCRYPTO_HAVE_TLS_TEST_SUPPORT #define WORKDIR "tests/test-crypto-tlssession-work/" +#define PSKFILE WORKDIR "keys.psk" #define KEYFILE WORKDIR "key-ctx.pem" -struct QCryptoTLSSessionTestData { - const char *servercacrt; - const char *clientcacrt; - const char *servercrt; - const char *clientcrt; - bool expectServerFail; - bool expectClientFail; - const char *hostname; - const char *const *wildcards; -}; - - static ssize_t testWrite(const char *buf, size_t len, void *opaque) { int *fd = opaque; @@ -59,9 +50,150 @@ static ssize_t testRead(char *buf, size_t len, void *opaque) return read(*fd, buf, len); } -static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint, - const char *certdir, - Error **errp) +static QCryptoTLSCreds *test_tls_creds_psk_create( + QCryptoTLSCredsEndpoint endpoint, + const char *dir, + Error **errp) +{ + Error *err = NULL; + Object *parent = object_get_objects_root(); + Object *creds = object_new_with_props( + TYPE_QCRYPTO_TLS_CREDS_PSK, + parent, + (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? + "testtlscredsserver" : "testtlscredsclient"), + &err, + "endpoint", (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER ? + "server" : "client"), + "dir", dir, + "priority", "NORMAL", + NULL + ); + + if (err) { + error_propagate(errp, err); + return NULL; + } + return QCRYPTO_TLS_CREDS(creds); +} + + +static void test_crypto_tls_session_psk(void) +{ + QCryptoTLSCreds *clientCreds; + QCryptoTLSCreds *serverCreds; + QCryptoTLSSession *clientSess = NULL; + QCryptoTLSSession *serverSess = NULL; + int channel[2]; + bool clientShake = false; + bool serverShake = false; + Error *err = NULL; + int ret; + + /* We'll use this for our fake client-server connection */ + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, channel); + g_assert(ret == 0); + + /* + * We have an evil loop to do the handshake in a single + * thread, so we need these non-blocking to avoid deadlock + * of ourselves + */ + qemu_set_nonblock(channel[0]); + qemu_set_nonblock(channel[1]); + + clientCreds = test_tls_creds_psk_create( + QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, + WORKDIR, + &err); + g_assert(clientCreds != NULL); + + serverCreds = test_tls_creds_psk_create( + QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, + WORKDIR, + &err); + g_assert(serverCreds != NULL); + + /* Now the real part of the test, setup the sessions */ + clientSess = qcrypto_tls_session_new( + clientCreds, NULL, NULL, + QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, &err); + serverSess = qcrypto_tls_session_new( + serverCreds, NULL, NULL, + QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, &err); + + g_assert(clientSess != NULL); + g_assert(serverSess != NULL); + + /* For handshake to work, we need to set the I/O callbacks + * to read/write over the socketpair + */ + qcrypto_tls_session_set_callbacks(serverSess, + testWrite, testRead, + &channel[0]); + qcrypto_tls_session_set_callbacks(clientSess, + testWrite, testRead, + &channel[1]); + + /* + * Finally we loop around & around doing handshake on each + * session until we get an error, or the handshake completes. + * This relies on the socketpair being nonblocking to avoid + * deadlocking ourselves upon handshake + */ + do { + int rv; + if (!serverShake) { + rv = qcrypto_tls_session_handshake(serverSess, + &err); + g_assert(rv >= 0); + if (qcrypto_tls_session_get_handshake_status(serverSess) == + QCRYPTO_TLS_HANDSHAKE_COMPLETE) { + serverShake = true; + } + } + if (!clientShake) { + rv = qcrypto_tls_session_handshake(clientSess, + &err); + g_assert(rv >= 0); + if (qcrypto_tls_session_get_handshake_status(clientSess) == + QCRYPTO_TLS_HANDSHAKE_COMPLETE) { + clientShake = true; + } + } + } while (!clientShake && !serverShake); + + + /* Finally make sure the server & client validation is successful. */ + g_assert(qcrypto_tls_session_check_credentials(serverSess, &err) == 0); + g_assert(qcrypto_tls_session_check_credentials(clientSess, &err) == 0); + + object_unparent(OBJECT(serverCreds)); + object_unparent(OBJECT(clientCreds)); + + qcrypto_tls_session_free(serverSess); + qcrypto_tls_session_free(clientSess); + + close(channel[0]); + close(channel[1]); +} + + +struct QCryptoTLSSessionTestData { + const char *servercacrt; + const char *clientcacrt; + const char *servercrt; + const char *clientcrt; + bool expectServerFail; + bool expectClientFail; + const char *hostname; + const char *const *wildcards; +}; + +static QCryptoTLSCreds *test_tls_creds_x509_create( + QCryptoTLSCredsEndpoint endpoint, + const char *certdir, + Error **errp) { Error *err = NULL; Object *parent = object_get_objects_root(); @@ -104,7 +236,7 @@ static QCryptoTLSCreds *test_tls_creds_create(QCryptoTLSCredsEndpoint endpoint, * initiate a TLS session across them. Finally do * do actual cert validation tests */ -static void test_crypto_tls_session(const void *opaque) +static void test_crypto_tls_session_x509(const void *opaque) { struct QCryptoTLSSessionTestData *data = (struct QCryptoTLSSessionTestData *)opaque; @@ -159,13 +291,13 @@ static void test_crypto_tls_session(const void *opaque) g_assert(link(KEYFILE, CLIENT_CERT_DIR QCRYPTO_TLS_CREDS_X509_CLIENT_KEY) == 0); - clientCreds = test_tls_creds_create( + clientCreds = test_tls_creds_x509_create( QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, CLIENT_CERT_DIR, &err); g_assert(clientCreds != NULL); - serverCreds = test_tls_creds_create( + serverCreds = test_tls_creds_x509_create( QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, SERVER_CERT_DIR, &err); @@ -285,7 +417,13 @@ int main(int argc, char **argv) mkdir(WORKDIR, 0700); test_tls_init(KEYFILE); + test_tls_psk_init(PSKFILE); + + /* Simple initial test using Pre-Shared Keys. */ + g_test_add_func("/qcrypto/tlssession/psk", + test_crypto_tls_session_psk); + /* More complex tests using X.509 certificates. */ # define TEST_SESS_REG(name, caCrt, \ serverCrt, clientCrt, \ expectServerFail, expectClientFail, \ @@ -296,7 +434,7 @@ int main(int argc, char **argv) hostname, wildcards \ }; \ g_test_add_data_func("/qcrypto/tlssession/" # name, \ - &name, test_crypto_tls_session); \ + &name, test_crypto_tls_session_x509); \ # define TEST_SESS_REG_EXT(name, serverCaCrt, clientCaCrt, \ @@ -309,7 +447,7 @@ int main(int argc, char **argv) hostname, wildcards \ }; \ g_test_add_data_func("/qcrypto/tlssession/" # name, \ - &name, test_crypto_tls_session); \ + &name, test_crypto_tls_session_x509); \ /* A perfect CA, perfect client & perfect server */ @@ -518,6 +656,7 @@ int main(int argc, char **argv) test_tls_discard_cert(&clientcertlevel2breq); unlink(WORKDIR "cacertchain-sess.pem"); + test_tls_psk_cleanup(PSKFILE); test_tls_cleanup(KEYFILE); rmdir(WORKDIR); diff --git a/tests/test-cutils.c b/tests/test-cutils.c index 64a489c2e9..d85c3e0f6d 100644 --- a/tests/test-cutils.c +++ b/tests/test-cutils.c @@ -26,8 +26,9 @@ */ #include "qemu/osdep.h" - +#include "qemu/units.h" #include "qemu/cutils.h" +#include "qemu/units.h" static void test_parse_uint_null(void) { @@ -2022,7 +2023,7 @@ static void test_qemu_strtosz_units(void) /* default is M */ err = qemu_strtosz_MiB(none, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, M_BYTE); + g_assert_cmpint(res, ==, MiB); g_assert(endptr == none + 1); err = qemu_strtosz(b, &endptr, &res); @@ -2032,32 +2033,32 @@ static void test_qemu_strtosz_units(void) err = qemu_strtosz(k, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, K_BYTE); + g_assert_cmpint(res, ==, KiB); g_assert(endptr == k + 2); err = qemu_strtosz(m, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, M_BYTE); + g_assert_cmpint(res, ==, MiB); g_assert(endptr == m + 2); err = qemu_strtosz(g, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, G_BYTE); + g_assert_cmpint(res, ==, GiB); g_assert(endptr == g + 2); err = qemu_strtosz(t, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, T_BYTE); + g_assert_cmpint(res, ==, TiB); g_assert(endptr == t + 2); err = qemu_strtosz(p, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, P_BYTE); + g_assert_cmpint(res, ==, PiB); g_assert(endptr == p + 2); err = qemu_strtosz(e, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, E_BYTE); + g_assert_cmpint(res, ==, EiB); g_assert(endptr == e + 2); } @@ -2070,7 +2071,7 @@ static void test_qemu_strtosz_float(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, 0); - g_assert_cmpint(res, ==, 12.345 * M_BYTE); + g_assert_cmpint(res, ==, 12.345 * MiB); g_assert(endptr == str + 7); } @@ -2106,7 +2107,7 @@ static void test_qemu_strtosz_trailing(void) str = "123xxx"; err = qemu_strtosz_MiB(str, &endptr, &res); - g_assert_cmpint(res, ==, 123 * M_BYTE); + g_assert_cmpint(res, ==, 123 * MiB); g_assert(endptr == str + 3); err = qemu_strtosz(str, NULL, &res); diff --git a/tests/test-keyval.c b/tests/test-keyval.c index 63cb14629b..09b0ae3c68 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -11,6 +11,7 @@ */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qlist.h" @@ -457,11 +458,11 @@ static void test_keyval_visit_size(void) visit_type_size(v, "sz2", &sz, &error_abort); g_assert_cmpuint(sz, ==, 1536); visit_type_size(v, "sz3", &sz, &error_abort); - g_assert_cmphex(sz, ==, 2 * M_BYTE); + g_assert_cmphex(sz, ==, 2 * MiB); visit_type_size(v, "sz4", &sz, &error_abort); - g_assert_cmphex(sz, ==, G_BYTE / 10); + g_assert_cmphex(sz, ==, GiB / 10); visit_type_size(v, "sz5", &sz, &error_abort); - g_assert_cmphex(sz, ==, 16777215 * T_BYTE); + g_assert_cmphex(sz, ==, 16777215ULL * TiB); visit_check_struct(v, &error_abort); visit_end_struct(v, NULL); visit_free(v); diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c index 7092e216f7..ef96e84aed 100644 --- a/tests/test-qemu-opts.c +++ b/tests/test-qemu-opts.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" -#include "qemu/cutils.h" +#include "qemu/units.h" #include "qemu/option.h" #include "qemu/option_int.h" #include "qapi/error.h" @@ -704,13 +704,12 @@ static void test_opts_parse_size(void) g_assert_cmpuint(opts_count(opts), ==, 3); g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8); g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536); - g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * M_BYTE); + g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * MiB); opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T", false, &error_abort); g_assert_cmpuint(opts_count(opts), ==, 2); - g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, G_BYTE / 10); - g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), - ==, 16777215 * T_BYTE); + g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, GiB / 10); + g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 16777215ULL * TiB); /* Beyond limit with suffix */ opts = qemu_opts_parse(&opts_list_02, "size1=16777216T", |