[Spice-devel] [PATCH spice-common 2/2] test: Add a test for subject_to_x509_name function

Frediano Ziglio fziglio at redhat.com
Thu Dec 13 14:20:25 UTC 2018


Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 common/ssl_verify.c     |   5 +-
 common/ssl_verify.h     |   4 ++
 tests/Makefile.am       |  20 ++++++
 tests/test-ssl-verify.c | 141 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 169 insertions(+), 1 deletion(-)
 create mode 100644 tests/test-ssl-verify.c

diff --git a/common/ssl_verify.c b/common/ssl_verify.c
index 74f95bb..3ccb52d 100644
--- a/common/ssl_verify.c
+++ b/common/ssl_verify.c
@@ -278,7 +278,10 @@ static int verify_hostname(X509* cert, const char *hostname)
     return cn_match;
 }
 
-static X509_NAME* subject_to_x509_name(const char *subject, int *nentries)
+#if !ENABLE_EXTRA_CHECKS
+static
+#endif
+X509_NAME* subject_to_x509_name(const char *subject, int *nentries)
 {
     X509_NAME* in_subject;
     const char *p;
diff --git a/common/ssl_verify.h b/common/ssl_verify.h
index 3456c71..9a2c27b 100644
--- a/common/ssl_verify.h
+++ b/common/ssl_verify.h
@@ -62,6 +62,10 @@ SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verif
                                              const char *subject);
 void spice_openssl_verify_free(SpiceOpenSSLVerify* verify);
 
+#if ENABLE_EXTRA_CHECKS
+X509_NAME* subject_to_x509_name(const char *subject, int *nentries);
+#endif
+
 SPICE_END_DECLS
 
 #endif // H_SPICE_COMMON_SSL_VERIFY
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 926ac99..beed5ec 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -102,4 +102,24 @@ EXTRA_DIST =				\
 	test-marshallers.proto		\
 	$(NULL)
 
+if ENABLE_EXTRA_CHECKS
+noinst_PROGRAMS += test_ssl_verify
+
+test_ssl_verify_SOURCES =			\
+	test-ssl-verify.c			\
+	$(NULL)
+test_ssl_verify_CFLAGS =		\
+	-I$(top_srcdir)			\
+	$(GLIB2_CFLAGS)			\
+	$(PROTOCOL_CFLAGS)		\
+	$(OPENSSL_CFLAGS)		\
+	$(NULL)
+test_ssl_verify_LDADD =						\
+	$(top_builddir)/common/libspice-common-client.la	\
+	$(top_builddir)/common/libspice-common.la		\
+	$(GLIB2_LIBS)						\
+	$(OPENSSL_LIBS)						\
+	$(NULL)
+endif
+
 -include $(top_srcdir)/git.mk
diff --git a/tests/test-ssl-verify.c b/tests/test-ssl-verify.c
new file mode 100644
index 0000000..3c70c79
--- /dev/null
+++ b/tests/test-ssl-verify.c
@@ -0,0 +1,141 @@
+/*
+   Copyright (C) 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/>.
+*/
+#include <config.h>
+
+#define G_LOG_DOMAIN "Spice"
+
+#include <glib.h>
+
+#include "common/log.h"
+#include "common/ssl_verify.h"
+
+static gchar **result_set = NULL;
+static gchar **next_result = NULL;
+static int result_len = 0;
+
+// set expected result for next test, these will be checked
+// results will be separate by ':' which is not a special character
+static void setup_results(const char *results)
+{
+    g_assert_null(result_set);
+    g_assert_null(next_result);
+    result_set = g_strsplit_set(results, ":", -1);
+    guint len = g_strv_length(result_set);
+    g_assert_true(len % 2 == 0);
+    next_result = result_set;
+    result_len = len / 2;
+}
+
+// cleanup results and prepare for next test
+static void tear_results(void)
+{
+    g_assert_nonnull(next_result);
+    g_assert_null(*next_result);
+    g_strfreev(result_set);
+    result_set = NULL;
+    result_len = 0;
+    next_result = NULL;
+}
+
+// get next expected value
+static const char *get_next_result(void)
+{
+    g_assert_nonnull(next_result);
+    g_assert_nonnull(*next_result);
+    return *next_result++;
+}
+
+// This override the OpenSSL function
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set)
+{
+    g_assert_nonnull(name);
+    g_assert_nonnull(field);
+    g_assert_cmpint(type, ==, MBSTRING_UTF8);
+    g_assert_nonnull(bytes);
+    g_assert_cmpint(len, ==, -1);
+    g_assert_cmpint(loc, ==, -1);
+    g_assert_cmpint(set, ==, 0);
+    g_assert_cmpstr(field, ==, get_next_result());
+    g_assert_cmpstr((const char *)bytes, ==, get_next_result());
+    return 1;
+}
+
+typedef struct {
+    const char *input;
+    const char *output;
+    gboolean success;
+} TestGenericParams;
+
+static void test_generic(const void *arg)
+{
+    const TestGenericParams *params = arg;
+    X509_NAME *name;
+    int num_entries;
+
+    setup_results(params->output);
+    name = subject_to_x509_name(params->input, &num_entries);
+    if (params->success) {
+        g_assert_cmpint(num_entries, ==, result_len);
+        g_assert_nonnull(name);
+        X509_NAME_free(name);
+    } else {
+        g_assert_null(name);
+    }
+    tear_results();
+}
+
+int main(int argc, char *argv[])
+{
+    g_test_init(&argc, &argv, NULL);
+
+#define TEST_SUCCESS(name, input, output) \
+    const TestGenericParams test_ ## name = { input, output, TRUE }; \
+    g_test_add_data_func("/ssl_verify/" #name, &test_ ## name, test_generic)
+#define TEST_ERROR(name, input, output) \
+    const TestGenericParams test_ ## name = { input, output, FALSE }; \
+    g_test_add_data_func("/ssl_verify/" #name, &test_ ## name, test_generic)
+
+    // normal
+    TEST_SUCCESS(easy1, "C=UK", "C:UK");
+    TEST_SUCCESS(easy2, "a=b,c=d", "a:b:c:d");
+
+    // check spaces before keys are ignored
+    TEST_SUCCESS(space1, "    C=UK", "C:UK");
+    TEST_SUCCESS(space2, "C=UK,    A=B", "C:UK:A:B");
+
+    // empty key
+    TEST_SUCCESS(empty1, "", "");
+    TEST_SUCCESS(empty2, "a=b,", "a:b");
+    TEST_SUCCESS(empty3, "   ", "");
+    TEST_SUCCESS(empty4, "a=b,  ", "a:b");
+
+    // empty value
+    TEST_ERROR(empty5, "a=", "");
+
+    // quoting
+    TEST_SUCCESS(quote1, "\\,=a", ",:a");
+    TEST_SUCCESS(quote2, "\\\\=a", "\\:a");
+    TEST_SUCCESS(quote3, "a=\\,b,c=d", "a:,b:c:d");
+    TEST_ERROR(quote4, ",", "");
+
+    TEST_ERROR(no_value1, "a", "");
+    TEST_ERROR(no_value2, "a,b=c", "");
+
+    return g_test_run();
+}
-- 
2.17.2



More information about the Spice-devel mailing list