Re: [PATCH v2 13/18] tests: add migration tests of TLS with x509 credentials

2022-11-11 Thread Daniel P . Berrangé
On Fri, Nov 11, 2022 at 08:56:20AM +0100, Thomas Huth wrote:
> On 10/03/2022 18.18, Daniel P. Berrangé wrote:
> > This validates that we correctly handle migration success and failure
> > scenarios when using TLS with x509 certificates. There are quite a few
> > different scenarios that matter in relation to hostname validation.
> > 
> > Signed-off-by: Daniel P. Berrangé 
> > ---
> [...]
> > +static void
> > +test_migrate_tls_x509_finish(QTestState *from,
> > + QTestState *to,
> > + void *opaque)
> > +{
> > +TestMigrateTLSX509Data *data = opaque;
> > +
> > +test_tls_cleanup(data->keyfile);
> > +unlink(data->cacert);
> > +unlink(data->servercert);
> > +unlink(data->serverkey);
> > +unlink(data->clientcert);
> > +unlink(data->clientkey);
> > +rmdir(data->workdir);
> > +
> > +g_free(data->workdir);
> > +g_free(data->keyfile);
> > +g_free(data);
> > +}
> 
>  Hi Daniel!
> 
> FYI, this seems to create a test failure with Clang 15 from Fedora 37:
> 
> https://gitlab.com/thuth/qemu/-/jobs/3304199277#L3761
> 
> Looks like data->clientcert has to be checked for NULL before unlink is
> called with it?

Yep, that's merely the clang santizers complaining, but we can fix
it anyway.

With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH v2 13/18] tests: add migration tests of TLS with x509 credentials

2022-11-11 Thread Thomas Huth

On 10/03/2022 18.18, Daniel P. Berrangé wrote:

This validates that we correctly handle migration success and failure
scenarios when using TLS with x509 certificates. There are quite a few
different scenarios that matter in relation to hostname validation.

Signed-off-by: Daniel P. Berrangé 
---

[...]

+static void
+test_migrate_tls_x509_finish(QTestState *from,
+ QTestState *to,
+ void *opaque)
+{
+TestMigrateTLSX509Data *data = opaque;
+
+test_tls_cleanup(data->keyfile);
+unlink(data->cacert);
+unlink(data->servercert);
+unlink(data->serverkey);
+unlink(data->clientcert);
+unlink(data->clientkey);
+rmdir(data->workdir);
+
+g_free(data->workdir);
+g_free(data->keyfile);
+g_free(data);
+}


 Hi Daniel!

FYI, this seems to create a test failure with Clang 15 from Fedora 37:

https://gitlab.com/thuth/qemu/-/jobs/3304199277#L3761

Looks like data->clientcert has to be checked for NULL before unlink is 
called with it?


 Thomas




[PATCH v2 13/18] tests: add migration tests of TLS with x509 credentials

2022-03-10 Thread Daniel P . Berrangé
This validates that we correctly handle migration success and failure
scenarios when using TLS with x509 certificates. There are quite a few
different scenarios that matter in relation to hostname validation.

Signed-off-by: Daniel P. Berrangé 
---
 meson.build  |   1 +
 tests/qtest/meson.build  |   5 +
 tests/qtest/migration-test.c | 382 ++-
 3 files changed, 386 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index 2d6601467f..89c0283ebe 100644
--- a/meson.build
+++ b/meson.build
@@ -1562,6 +1562,7 @@ config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
 config_host_data.set('CONFIG_GETTID', has_gettid)
 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
+config_host_data.set('CONFIG_TASN1', tasn1.found())
 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
 config_host_data.set('CONFIG_NETTLE', nettle.found())
 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 81e7b9d530..ce94380a08 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -281,6 +281,11 @@ tpmemu_files = ['tpm-emu.c', 'tpm-util.c', 'tpm-tests.c']
 migration_files = [files('migration-helpers.c')]
 if gnutls.found()
   migration_files += [files('../unit/crypto-tls-psk-helpers.c'), gnutls]
+
+  if tasn1.found()
+migration_files += [files('../unit/crypto-tls-x509-helpers.c',
+  '../unit/pkix_asn1_tab.c'), tasn1]
+  endif
 endif
 
 qtests = {
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index f733aa352e..c730697f74 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -29,6 +29,9 @@
 #include "tests/migration/migration-test.h"
 #ifdef CONFIG_GNUTLS
 # include "tests/unit/crypto-tls-psk-helpers.h"
+# ifdef CONFIG_TASN1
+#  include "tests/unit/crypto-tls-x509-helpers.h"
+# endif /* CONFIG_TASN1 */
 #endif /* CONFIG_GNUTLS */
 
 /* For dirty ring test; so far only x86_64 is supported */
@@ -736,6 +739,234 @@ test_migrate_tls_psk_finish(QTestState *from,
 g_free(data->pskfile);
 g_free(data);
 }
+
+#ifdef CONFIG_TASN1
+typedef struct {
+char *workdir;
+char *keyfile;
+char *cacert;
+char *servercert;
+char *serverkey;
+char *clientcert;
+char *clientkey;
+} TestMigrateTLSX509Data;
+
+typedef struct {
+bool verifyclient;
+bool clientcert;
+bool hostileclient;
+bool authzclient;
+const char *certhostname;
+const char *certipaddr;
+} TestMigrateTLSX509;
+
+static void *
+test_migrate_tls_x509_start_common(QTestState *from,
+   QTestState *to,
+   TestMigrateTLSX509 *args)
+{
+TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1);
+QDict *rsp;
+
+data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs);
+data->keyfile = g_strdup_printf("%s/key.pem", data->workdir);
+
+data->cacert = g_strdup_printf("%s/ca-cert.pem", data->workdir);
+data->serverkey = g_strdup_printf("%s/server-key.pem", data->workdir);
+data->servercert = g_strdup_printf("%s/server-cert.pem", data->workdir);
+if (args->clientcert) {
+data->clientkey = g_strdup_printf("%s/client-key.pem", data->workdir);
+data->clientcert = g_strdup_printf("%s/client-cert.pem", 
data->workdir);
+}
+
+mkdir(data->workdir, 0700);
+
+test_tls_init(data->keyfile);
+g_assert(link(data->keyfile, data->serverkey) == 0);
+if (args->clientcert) {
+g_assert(link(data->keyfile, data->clientkey) == 0);
+}
+
+TLS_ROOT_REQ_SIMPLE(cacertreq, data->cacert);
+if (args->clientcert) {
+TLS_CERT_REQ_SIMPLE_CLIENT(servercertreq, cacertreq,
+   args->hostileclient ?
+   QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
+   QCRYPTO_TLS_TEST_CLIENT_NAME,
+   data->clientcert);
+}
+
+TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
+   data->servercert,
+   args->certhostname,
+   args->certipaddr);
+
+rsp = wait_command(from,
+   "{ 'execute': 'object-add',"
+   "  'arguments': { 'qom-type': 'tls-creds-x509',"
+   " 'id': 'tlscredsx509client0',"
+   " 'endpoint': 'client',"
+   " 'dir': %s,"
+   " 'sanity-check': true,"
+   " 'verify-peer': true} }",
+   data->workdir);
+qobject_unref(rsp);
+migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0");
+if (args->certhostname) {
+