]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
tests: New style fuzzing tools for TLS client/server
authorJouni Malinen <j@w1.fi>
Sun, 2 Jun 2019 10:03:58 +0000 (13:03 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 2 Jun 2019 10:11:56 +0000 (13:11 +0300)
These are newer versions of tests/test-tls tool.

Signed-off-by: Jouni Malinen <j@w1.fi>
tests/fuzzing/tls-client/Makefile [new file with mode: 0644]
tests/fuzzing/tls-client/corpus/server.msg [new file with mode: 0644]
tests/fuzzing/tls-client/tls-client.c [new file with mode: 0644]
tests/fuzzing/tls-server/Makefile [new file with mode: 0644]
tests/fuzzing/tls-server/corpus/client.msg [new file with mode: 0644]
tests/fuzzing/tls-server/tls-server.c [new file with mode: 0644]

diff --git a/tests/fuzzing/tls-client/Makefile b/tests/fuzzing/tls-client/Makefile
new file mode 100644 (file)
index 0000000..e91125e
--- /dev/null
@@ -0,0 +1,25 @@
+all: tls-client
+include ../rules.include
+
+LIBS += $(SRC)/common/libcommon.a
+LIBS += $(SRC)/crypto/libcrypto.a
+LIBS += $(SRC)/tls/libtls.a
+LIBS += $(SRC)/rsn_supp/librsn_supp.a
+LIBS += $(SRC)/eapol_supp/libeapol_supp.a
+LIBS += $(SRC)/eap_peer/libeap_peer.a
+LIBS += $(SRC)/eap_common/libeap_common.a
+LIBS += $(SRC)/l2_packet/libl2_packet.a
+LIBS += $(SRC)/utils/libutils.a
+
+ELIBS += $(SRC)/crypto/libcrypto.a
+ELIBS += $(SRC)/tls/libtls.a
+
+tls-client: tls-client.o $(OBJS) $(LIBS)
+       $(LDO) $(LDFLAGS) -o $@ $^ $(LIBS) $(ELIBS)
+
+clean:
+       $(MAKE) -C $(SRC) clean
+       $(MAKE) -C $(WPAS_SRC) clean
+       rm -f tls-client *~ *.o *.d ../*~ ../*.o ../*.d
+
+-include $(OBJS:%.o=%.d)
diff --git a/tests/fuzzing/tls-client/corpus/server.msg b/tests/fuzzing/tls-client/corpus/server.msg
new file mode 100644 (file)
index 0000000..0f842fd
Binary files /dev/null and b/tests/fuzzing/tls-client/corpus/server.msg differ
diff --git a/tests/fuzzing/tls-client/tls-client.c b/tests/fuzzing/tls-client/tls-client.c
new file mode 100644 (file)
index 0000000..b15b719
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Testing tool for TLSv1 client routines
+ * Copyright (c) 2019, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto/tls.h"
+#include "../fuzzer-common.h"
+
+#ifndef CERTDIR
+#define CERTDIR "../../hwsim/auth_serv/"
+#endif
+
+struct context {
+       const u8 *data;
+       size_t data_len;
+       size_t data_offset;
+};
+
+
+static struct wpabuf * read_msg(struct context *ctx)
+{
+       u16 msg_len;
+       struct wpabuf *msg;
+
+       if (ctx->data_len - ctx->data_offset < 2) {
+               wpa_printf(MSG_ERROR, "TEST-ERROR: Could not read msg len");
+               return NULL;
+       }
+       msg_len = WPA_GET_BE16(&ctx->data[ctx->data_offset]);
+       ctx->data_offset += 2;
+
+       msg = wpabuf_alloc(msg_len);
+       if (!msg)
+               return NULL;
+       if (msg_len > 0 && ctx->data_len - ctx->data_offset < msg_len) {
+               wpa_printf(MSG_ERROR, "TEST-ERROR: Truncated msg (msg_len=%u)",
+                          msg_len);
+               wpabuf_free(msg);
+               return NULL;
+       }
+       wpabuf_put_data(msg, &ctx->data[ctx->data_offset], msg_len);
+       ctx->data_offset += msg_len;
+       wpa_hexdump_buf(MSG_DEBUG, "TEST: Read message from file", msg);
+
+       return msg;
+}
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+       struct context ctx;
+       struct tls_config conf;
+       void *tls_client;
+       struct tls_connection_params params;
+       struct tls_connection *conn_client = NULL;
+       int ret = -1;
+       struct wpabuf *in = NULL, *out = NULL, *appl;
+
+       wpa_fuzzer_set_debug_level();
+
+       os_memset(&ctx, 0, sizeof(ctx));
+       ctx.data = data;
+       ctx.data_len = size;
+
+       os_memset(&conf, 0, sizeof(conf));
+       tls_client = tls_init(&conf);
+       if (!tls_client)
+               goto fail;
+
+       os_memset(&params, 0, sizeof(params));
+       params.ca_cert = CERTDIR "ca.pem";
+       params.client_cert = CERTDIR "server.pem";
+       params.private_key = CERTDIR "server.key";
+       params.dh_file = CERTDIR "dh.conf";
+
+       conn_client = tls_connection_init(tls_client);
+       if (!conn_client)
+               goto fail;
+
+       in = NULL;
+       for (;;) {
+               appl = NULL;
+               out = tls_connection_handshake(tls_client, conn_client, in,
+                                              &appl);
+               wpabuf_free(in);
+               in = NULL;
+               if (!out)
+                       goto fail;
+               if (tls_connection_get_failed(tls_client, conn_client)) {
+                       wpa_printf(MSG_ERROR, "TLS handshake failed");
+                       goto fail;
+               }
+               if (tls_connection_established(tls_client, conn_client))
+                       break;
+
+               appl = NULL;
+               in = read_msg(&ctx);
+               wpabuf_free(out);
+               out = NULL;
+               if (!in)
+                       goto fail;
+               if (tls_connection_established(tls_client, conn_client))
+                       break;
+       }
+
+       wpabuf_free(in);
+       in = wpabuf_alloc(100);
+       if (!in)
+               goto fail;
+       wpabuf_put_str(in, "PING");
+       wpabuf_free(out);
+       out = tls_connection_encrypt(tls_client, conn_client, in);
+       wpabuf_free(in);
+       in = NULL;
+       if (!out)
+               goto fail;
+
+       wpabuf_free(in);
+       in = wpabuf_alloc(100);
+       if (!in)
+               goto fail;
+       wpabuf_put_str(in, "PONG");
+       wpabuf_free(out);
+       out = read_msg(&ctx);
+       wpabuf_free(in);
+       in = NULL;
+       if (!out)
+               goto fail;
+
+       in = tls_connection_decrypt(tls_client, conn_client, out);
+       wpabuf_free(out);
+       out = NULL;
+       if (!in)
+               goto fail;
+       wpa_hexdump_buf(MSG_DEBUG, "Client decrypted ApplData", in);
+
+       ret = 0;
+fail:
+       if (tls_client) {
+               if (conn_client)
+                       tls_connection_deinit(tls_client, conn_client);
+               tls_deinit(tls_client);
+       }
+       wpabuf_free(in);
+       wpabuf_free(out);
+
+       return ret;
+}
diff --git a/tests/fuzzing/tls-server/Makefile b/tests/fuzzing/tls-server/Makefile
new file mode 100644 (file)
index 0000000..dbb53e5
--- /dev/null
@@ -0,0 +1,25 @@
+all: tls-server
+include ../rules.include
+
+LIBS += $(SRC)/common/libcommon.a
+LIBS += $(SRC)/crypto/libcrypto.a
+LIBS += $(SRC)/tls/libtls.a
+LIBS += $(SRC)/rsn_supp/librsn_supp.a
+LIBS += $(SRC)/eapol_supp/libeapol_supp.a
+LIBS += $(SRC)/eap_peer/libeap_peer.a
+LIBS += $(SRC)/eap_common/libeap_common.a
+LIBS += $(SRC)/l2_packet/libl2_packet.a
+LIBS += $(SRC)/utils/libutils.a
+
+ELIBS += $(SRC)/crypto/libcrypto.a
+ELIBS += $(SRC)/tls/libtls.a
+
+tls-server: tls-server.o $(OBJS) $(LIBS)
+       $(LDO) $(LDFLAGS) -o $@ $^ $(LIBS) $(ELIBS)
+
+clean:
+       $(MAKE) -C $(SRC) clean
+       $(MAKE) -C $(WPAS_SRC) clean
+       rm -f tls-server *~ *.o *.d ../*~ ../*.o ../*.d
+
+-include $(OBJS:%.o=%.d)
diff --git a/tests/fuzzing/tls-server/corpus/client.msg b/tests/fuzzing/tls-server/corpus/client.msg
new file mode 100644 (file)
index 0000000..cb39014
Binary files /dev/null and b/tests/fuzzing/tls-server/corpus/client.msg differ
diff --git a/tests/fuzzing/tls-server/tls-server.c b/tests/fuzzing/tls-server/tls-server.c
new file mode 100644 (file)
index 0000000..d64cd7a
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Testing tool for TLSv1 server routines
+ * Copyright (c) 2019, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "crypto/tls.h"
+#include "../fuzzer-common.h"
+
+#ifndef CERTDIR
+#define CERTDIR "../../hwsim/auth_serv/"
+#endif
+
+struct context {
+       const u8 *data;
+       size_t data_len;
+       size_t data_offset;
+};
+
+
+static struct wpabuf * read_msg(struct context *ctx)
+{
+       u16 msg_len;
+       struct wpabuf *msg;
+
+       if (ctx->data_len - ctx->data_offset < 2) {
+               wpa_printf(MSG_ERROR, "TEST-ERROR: Could not read msg len");
+               return NULL;
+       }
+       msg_len = WPA_GET_BE16(&ctx->data[ctx->data_offset]);
+       ctx->data_offset += 2;
+
+       msg = wpabuf_alloc(msg_len);
+       if (!msg)
+               return NULL;
+       if (msg_len > 0 && ctx->data_len - ctx->data_offset < msg_len) {
+               wpa_printf(MSG_ERROR, "TEST-ERROR: Truncated msg (msg_len=%u)",
+                          msg_len);
+               wpabuf_free(msg);
+               return NULL;
+       }
+       wpabuf_put_data(msg, &ctx->data[ctx->data_offset], msg_len);
+       ctx->data_offset += msg_len;
+       wpa_hexdump_buf(MSG_DEBUG, "TEST: Read message from file", msg);
+
+       return msg;
+}
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+       struct context ctx;
+       struct tls_config conf;
+       void *tls_server;
+       struct tls_connection_params params;
+       struct tls_connection *conn_server = NULL;
+       int ret = -1;
+       struct wpabuf *in = NULL, *out = NULL, *appl;
+
+       wpa_fuzzer_set_debug_level();
+
+       os_memset(&ctx, 0, sizeof(ctx));
+       ctx.data = data;
+       ctx.data_len = size;
+
+       os_memset(&conf, 0, sizeof(conf));
+       tls_server = tls_init(&conf);
+       if (!tls_server)
+               goto fail;
+
+       os_memset(&params, 0, sizeof(params));
+       params.ca_cert = CERTDIR "ca.pem";
+       params.client_cert = CERTDIR "server.pem";
+       params.private_key = CERTDIR "server.key";
+       params.dh_file = CERTDIR "dh.conf";
+
+       if (tls_global_set_params(tls_server, &params)) {
+               wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
+               goto fail;
+       }
+
+       conn_server = tls_connection_init(tls_server);
+       if (!conn_server)
+               goto fail;
+
+       in = NULL;
+       for (;;) {
+               appl = NULL;
+               out = read_msg(&ctx);
+               wpabuf_free(in);
+               in = NULL;
+               if (!out)
+                       goto fail;
+
+               appl = NULL;
+               in = tls_connection_server_handshake(tls_server, conn_server,
+                                                    out, &appl);
+               wpabuf_free(out);
+               out = NULL;
+               if (!in)
+                       goto fail;
+               if (tls_connection_get_failed(tls_server, conn_server)) {
+                       wpa_printf(MSG_ERROR, "TLS handshake failed");
+                       goto fail;
+               }
+               if (tls_connection_established(tls_server, conn_server))
+                       break;
+       }
+
+       wpabuf_free(in);
+       in = wpabuf_alloc(100);
+       if (!in)
+               goto fail;
+       wpabuf_put_str(in, "PING");
+       wpabuf_free(out);
+       out = read_msg(&ctx);
+       wpabuf_free(in);
+       in = NULL;
+       if (!out)
+               goto fail;
+
+       in = tls_connection_decrypt(tls_server, conn_server, out);
+       wpabuf_free(out);
+       out = NULL;
+       if (!in)
+               goto fail;
+       wpa_hexdump_buf(MSG_DEBUG, "Server decrypted ApplData", in);
+
+       wpabuf_free(in);
+       in = wpabuf_alloc(100);
+       if (!in)
+               goto fail;
+       wpabuf_put_str(in, "PONG");
+       wpabuf_free(out);
+       out = tls_connection_encrypt(tls_server, conn_server, in);
+       wpabuf_free(in);
+       in = NULL;
+       if (!out)
+               goto fail;
+
+       ret = 0;
+fail:
+       if (tls_server) {
+               if (conn_server)
+                       tls_connection_deinit(tls_server, conn_server);
+               tls_deinit(tls_server);
+       }
+       wpabuf_free(in);
+       wpabuf_free(out);
+
+       return ret;
+}