summaryrefslogtreecommitdiff
path: root/tests/mini-xssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/mini-xssl.c')
-rw-r--r--tests/mini-xssl.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/tests/mini-xssl.c b/tests/mini-xssl.c
new file mode 100644
index 0000000000..e304e7aca9
--- /dev/null
+++ b/tests/mini-xssl.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS 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 GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Tests for the xssl interface */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+
+int main()
+{
+ exit(77);
+}
+
+#else
+
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/xssl.h>
+#include <signal.h>
+
+#include "utils.h"
+
+#define TOFU_DB_FILE "tofu.tmp.db"
+
+static void terminate(void);
+
+/* This program tests the robustness of record
+ * decoding.
+ */
+
+static time_t mytime (time_t * t)
+{
+ time_t then = 1359304177;
+
+ if (t)
+ *t = then;
+
+ return then;
+}
+
+
+static void
+server_log_func (int level, const char *str)
+{
+// fprintf (stderr, "server|<%d>| %s", level, str);
+}
+
+static void
+client_log_func (int level, const char *str)
+{
+ fprintf (stderr, "client|<%d>| %s", level, str);
+}
+
+static unsigned char ca_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDUDCCAgigAwIBAgIBADANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5HbnVU\n"
+ "TFMgVGVzdCBDQTAeFw0xMTA1MjgwODM2MzBaFw0zODEwMTIwODM2MzNaMBkxFzAV\n"
+ "BgNVBAMTDkdudVRMUyBUZXN0IENBMIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIB\n"
+ "OgKCATEAnORCsX1unl//fy2d1054XduIg/3CqVBaT3Hca65SEoDwh0KiPtQoOgZL\n"
+ "dKY2cobGs/ojYtOjcs0KnlPYdmtjEh6WEhuJU95v4TQdC4OLMiE56eIGq252hZAb\n"
+ "HoTL84Q14DxQWGuzQK830iml7fbw2WcIcRQ8vFGs8SzfXw63+MI6Fq6iMAQIqP08\n"
+ "WzGmRRzL5wvCiPhCVkrPmwbXoABub6AAsYwWPJB91M9/lx5gFH5k9/iPfi3s2Kg3\n"
+ "F8MOcppqFYjxDSnsfiz6eMh1+bYVIAo367vGVYHigXMEZC2FezlwIHaZzpEoFlY3\n"
+ "a7LFJ00yrjQ910r8UE+CEMTYzE40D0olCMo7FA9RCjeO3bUIoYaIdVTUGWEGHWSe\n"
+ "oxGei9Gkm6u+ASj8f+i0jxdD2qXsewIDAQABo0MwQTAPBgNVHRMBAf8EBTADAQH/\n"
+ "MA8GA1UdDwEB/wQFAwMHBgAwHQYDVR0OBBYEFE1Wt2oAWPFnkvSmdVUbjlMBA+/P\n"
+ "MA0GCSqGSIb3DQEBCwUAA4IBMQAesOgjGFi1zOYpA/N3gkUVRcBHDxmN7g2yOcqH\n"
+ "VfhFc+e4zhOehR11WCt2RgzNlnYVmV5zBmQBdTAt8Po/MVhLCDW1BULHlLvL0DFc\n"
+ "4sB1RlcGeQcCKQa4b+Q9VWf4f6TfuEWZQC5j5stiXjVgOqrOMrzKZ2eKWA4JsL9s\n"
+ "V+7ANSZE+hOt1X1mA8moyqe95U2Ecih+nFJSWSBd1WFiEzVnXv4FVWPXbH9HERDK\n"
+ "VbasjofWWmQO1YlQPishLgm1IbwqOkOk4sDgoLuUZ4GgP0DDeN6EmRDOzByrv+9u\n"
+ "f45Bl9IQf4IJNPLU9lEqjyMOydqT6kBi7fjV5ICuQZ4EeVJsOGuX7PqNyoDzJHLv\n"
+ "ferRfNLr6eQSHSxBhS0cVyDjb5gCawK6u7xTU+b7xikEie9k\n"
+ "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t ca_cert = { ca_pem,
+ sizeof (ca_pem)-1
+};
+
+static unsigned char server_cert_pem[] =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICsDCCAWigAwIBAgIETeC0kjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5H\n"
+ "bnVUTFMgVGVzdCBDQTAeFw0xMTA1MjgwODM4NDNaFw0zODEwMTIwODM4NDZaMDEx\n"
+ "LzAtBgNVBAMTJkdudVRMUyBUZXN0IHNlcnZlciAoRUNEU0EgY2VydGlmaWNhdGUp\n"
+ "ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAE0vMmf/W0rRoUqBxH5Uq+c/sR76ElmyZM\n"
+ "e2zj3U9PRJ0maKstEOHkpaDaSU6s2Hyi9L88wS1ZX0ijgY0wgYowDAYDVR0TAQH/\n"
+ "BAIwADAUBgNVHREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEw\n"
+ "DwYDVR0PAQH/BAUDAweAADAdBgNVHQ4EFgQUJ97Q83IFpLgqeOnT1rX/JzCvlTQw\n"
+ "HwYDVR0jBBgwFoAUTVa3agBY8WeS9KZ1VRuOUwED788wDQYJKoZIhvcNAQELBQAD\n"
+ "ggExAErP9z8CCwt7YwA+SHoulNjqcXsngeKAKN9fVgV/XuspG6L2nU1WZvCjjFj6\n"
+ "jggMbJSElyCuLZJKlTC/DihXUgRXyswOzg9qQ7dDv+V/Qi95XH5slXNzYxMQSdoA\n"
+ "IaULVVDZcMFMVSc+TyAchJ6XwUY9umiysz3lSOioMQCch4MA366ZNqqnq5OD4moH\n"
+ "1SUX8CbRjA6SLpvffexLTB2Af+mFi8ReTkXCwB1LGEH1HRp/XzBc+/F9mavy3g/6\n"
+ "Hnjf2E1h2GDYXcJCVfE+ArjNS+R94jJwRMFBvwD/x2hsvpSajDpO0+GIxlGGKdyh\n"
+ "7o4puz/BqHwSzX9h7I7RvFEogDUNUzLgHMdcjq5usnmQpdWNUP8Xs/WqLjML+/PT\n"
+ "+jyCwmll0lPlC2RqAx3pM1XrjjQ=\n"
+ "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t server_cert = { server_cert_pem,
+ sizeof (server_cert_pem)-1
+};
+
+static unsigned char server_key_pem[] =
+ "-----BEGIN EC PRIVATE KEY-----\n"
+ "MGgCAQEEHHX3xeBOGgIxxtuhhpbwdwZnJztR7+uZTHnYuL+gBwYFK4EEACGhPAM6\n"
+ "AATS8yZ/9bStGhSoHEflSr5z+xHvoSWbJkx7bOPdT09EnSZoqy0Q4eSloNpJTqzY\n"
+ "fKL0vzzBLVlfSA==\n"
+ "-----END EC PRIVATE KEY-----\n";
+
+const gnutls_datum_t server_key = { server_key_pem,
+ sizeof (server_key_pem)-1
+};
+
+#define LINE1 "hello there people\n"
+#define LINE2 "how are you doing today, all well?\n"
+
+static const char* test = NULL;
+
+#define err_quit(r) {fail("%s: Error in line %d: %s\n", test, __LINE__, gnutls_strerror(r)); exit(1);}
+
+static void
+client (int fd, unsigned int vmethod, unsigned use_cert)
+{
+ int ret;
+ char *line = NULL;
+ size_t line_len;
+ xssl_cred_t cred;
+ xssl_t sb;
+ gnutls_cinput_st aux[2];
+ unsigned int status;
+ unsigned aux_size = 0;
+
+ gnutls_global_init ();
+ gnutls_global_set_time_function (mytime);
+
+ if (debug)
+ {
+ gnutls_global_set_log_function (client_log_func);
+ gnutls_global_set_log_level (7);
+ }
+
+ if (vmethod & GNUTLS_VMETHOD_GIVEN_CAS)
+ {
+ aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+ aux[aux_size].contents = GNUTLS_CINPUT_CAS;
+ aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+ aux[aux_size].i1.mem = ca_cert;
+ aux_size++;
+ }
+
+ if (use_cert != 0)
+ {
+ aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+ aux[aux_size].contents = GNUTLS_CINPUT_KEYPAIR;
+ aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+ aux[aux_size].i1.mem = server_cert;
+ aux[aux_size].i2.mem = server_key;
+ aux_size++;
+ }
+
+ if (vmethod & GNUTLS_VMETHOD_TOFU)
+ {
+ aux[aux_size].type = GNUTLS_CINPUT_TYPE_FILE;
+ aux[aux_size].contents = GNUTLS_CINPUT_TOFU_DB;
+ aux[aux_size].i1.file = TOFU_DB_FILE;
+ aux_size++;
+ }
+
+ ret = xssl_cred_init(&cred, vmethod, aux, aux_size);
+ if (ret < 0)
+ err_quit(ret);
+
+ /* Initialize TLS session
+ */
+ ret = xssl_client_init(&sb, "localhost", NULL, (gnutls_transport_ptr_t)fd,
+ NULL, cred, &status, 0);
+ if (ret < 0)
+ {
+ if (ret == GNUTLS_E_AUTH_ERROR)
+ {
+ gnutls_datum_t txt;
+
+ gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509,
+ &txt, 0);
+
+ fprintf(stderr, "auth[%x]: %s\n", status, txt.data);
+ gnutls_free(txt.data);
+ }
+ err_quit(ret);
+ }
+
+ ret = xssl_getline(sb, &line, &line_len);
+ if (ret < 0)
+ err_quit(ret);
+
+ if (strcmp(line, LINE1) != 0)
+ {
+ fail("Error comparing first line\n");
+ exit(1);
+ }
+
+ ret = xssl_getline(sb, &line, &line_len);
+ if (ret < 0)
+ err_quit(ret);
+
+ if (strcmp(line, LINE2) != 0)
+ {
+ fail("Error comparing first line\n");
+ exit(1);
+ }
+
+ gnutls_free(line);
+
+ xssl_deinit(sb);
+
+ close (fd);
+
+ xssl_cred_deinit (cred);
+
+ gnutls_global_deinit ();
+}
+
+
+/* These are global */
+pid_t child;
+
+static void terminate(void)
+{
+ kill(child, SIGTERM);
+ exit(1);
+}
+
+static void
+server (int fd, unsigned vmethod)
+{
+ int ret;
+ xssl_cred_t cred;
+ xssl_t sb;
+ gnutls_cinput_st aux[2];
+ unsigned aux_size = 0;
+
+ gnutls_global_init ();
+
+ if (debug)
+ {
+ gnutls_global_set_log_function (client_log_func);
+ gnutls_global_set_log_level (7);
+ }
+
+
+ aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+ aux[aux_size].contents = GNUTLS_CINPUT_KEYPAIR;
+ aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+ aux[aux_size].i1.mem = server_cert;
+ aux[aux_size].i2.mem = server_key;
+ aux_size++;
+
+ if (vmethod & GNUTLS_VMETHOD_GIVEN_CAS)
+ {
+ aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+ aux[aux_size].contents = GNUTLS_CINPUT_CAS;
+ aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+ aux[aux_size].i1.mem = ca_cert;
+ aux_size++;
+ }
+
+ ret = xssl_cred_init(&cred, vmethod, aux, aux_size);
+ if (ret < 0)
+ err_quit(ret);
+
+ /* Initialize TLS session
+ */
+ ret = xssl_server_init(&sb, (gnutls_transport_ptr_t)fd,
+ NULL, cred, NULL, 0);
+ if (ret < 0)
+ err_quit(ret);
+
+ ret = xssl_write(sb, LINE1, sizeof(LINE1)-1);
+ if (ret < 0)
+ err_quit(ret);
+
+ ret = xssl_write(sb, LINE2, sizeof(LINE2)-1);
+ if (ret < 0)
+ err_quit(ret);
+
+ ret = xssl_flush(sb);
+ if (ret < 0)
+ err_quit(ret);
+
+ xssl_deinit(sb);
+
+ close (fd);
+
+ xssl_cred_deinit (cred);
+
+ gnutls_global_deinit ();
+
+}
+
+static void start (unsigned vc, unsigned vs, unsigned ccert)
+{
+ int fd[2];
+ int ret;
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
+ if (ret < 0)
+ {
+ perror("socketpair");
+ exit(1);
+ }
+
+ child = fork ();
+ if (child < 0)
+ {
+ perror ("fork");
+ fail ("fork");
+ exit(1);
+ }
+
+ if (child)
+ {
+ /* parent */
+ close(fd[1]);
+ server (fd[0], vs);
+ waitpid(-1, NULL, 0);
+ //kill(child, SIGTERM);
+ }
+ else
+ {
+ close(fd[0]);
+ client (fd[1], vc, ccert);
+ exit(0);
+ }
+}
+
+static void ch_handler(int sig)
+{
+int status = 0;
+
+ waitpid(-1, &status, 0);
+ if (WEXITSTATUS(status) != 0 ||
+ (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV))
+ {
+ if (WIFSIGNALED(status))
+ fail("Child died with sigsegv\n");
+ else
+ fail("Child died with status %d\n", WEXITSTATUS(status));
+ terminate();
+ }
+ return;
+}
+
+void
+doit (void)
+{
+ signal(SIGCHLD, ch_handler);
+
+ test = "test1: no auth";
+ start(GNUTLS_VMETHOD_NO_AUTH, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+ test = "test2: server auth";
+ start(GNUTLS_VMETHOD_GIVEN_CAS, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+ test = "test3: mutual auth";
+ start(GNUTLS_VMETHOD_GIVEN_CAS, GNUTLS_VMETHOD_GIVEN_CAS, 1);
+
+ remove(TOFU_DB_FILE);
+ test = "test4: trust on first use p1";
+ start(GNUTLS_VMETHOD_TOFU, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+ test = "test5: trust on first use p2";
+ start(GNUTLS_VMETHOD_TOFU, GNUTLS_VMETHOD_NO_AUTH, 0);
+ remove(TOFU_DB_FILE);
+
+}
+
+#endif /* _WIN32 */