summaryrefslogtreecommitdiff
path: root/Tests/LibTLS/TestTLSHandshake.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/LibTLS/TestTLSHandshake.cpp')
-rw-r--r--Tests/LibTLS/TestTLSHandshake.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/Tests/LibTLS/TestTLSHandshake.cpp b/Tests/LibTLS/TestTLSHandshake.cpp
new file mode 100644
index 0000000000..a38f1f7f3c
--- /dev/null
+++ b/Tests/LibTLS/TestTLSHandshake.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2021, Peter Bocan <me@pbocan.net>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibCore/ConfigFile.h>
+#include <LibCore/EventLoop.h>
+#include <LibCore/File.h>
+#include <LibCrypto/ASN1/ASN1.h>
+#include <LibTLS/TLSv12.h>
+#include <LibTest/TestCase.h>
+
+static const char* ca_certs_file = "./ca_certs.ini";
+static int port = 443;
+
+constexpr const char* DEFAULT_DIGEST_SUITE { "HMAC-SHA256" };
+constexpr const char* DEFAULT_CHECKSUM_SUITE { "CRC32" };
+constexpr const char* DEFAULT_HASH_SUITE { "SHA256" };
+constexpr const char* DEFAULT_CIPHER_SUITE { "AES_CBC" };
+constexpr const char* DEFAULT_SERVER { "www.google.com" };
+
+static ByteBuffer operator""_b(const char* string, size_t length)
+{
+ return ByteBuffer::copy(string, length);
+}
+
+Vector<Certificate> load_certificates();
+String locate_ca_certs_file();
+
+String locate_ca_certs_file()
+{
+ if (Core::File::exists(ca_certs_file)) {
+ return ca_certs_file;
+ }
+ auto on_target_path = String("/etc/ca_certs.ini");
+ if (Core::File::exists(on_target_path)) {
+ return on_target_path;
+ }
+ return "";
+}
+
+Vector<Certificate> load_certificates()
+{
+ Vector<Certificate> certificates;
+ auto ca_certs_filepath = locate_ca_certs_file();
+ if (ca_certs_filepath == "") {
+ warnln("Could not locate ca_certs.ini file.");
+ return certificates;
+ }
+
+ auto config = Core::ConfigFile::open(ca_certs_filepath);
+ auto now = Core::DateTime::now();
+ auto last_year = Core::DateTime::create(now.year() - 1);
+ auto next_year = Core::DateTime::create(now.year() + 1);
+ for (auto& entity : config->groups()) {
+ Certificate cert;
+ cert.subject.subject = entity;
+ cert.issuer.subject = config->read_entry(entity, "issuer_subject", entity);
+ cert.subject.country = config->read_entry(entity, "country");
+ cert.not_before = Crypto::ASN1::parse_generalized_time(config->read_entry(entity, "not_before", "")).value_or(last_year);
+ cert.not_after = Crypto::ASN1::parse_generalized_time(config->read_entry(entity, "not_after", "")).value_or(next_year);
+ certificates.append(move(cert));
+ }
+ return certificates;
+}
+
+static Vector<Certificate> s_root_ca_certificates = load_certificates();
+
+TEST_CASE(test_TLS_hello_handshake)
+{
+ Core::EventLoop loop;
+ RefPtr<TLS::TLSv12> tls = TLS::TLSv12::construct(nullptr);
+ tls->set_root_certificates(s_root_ca_certificates);
+ bool sent_request = false;
+ ByteBuffer contents = ByteBuffer::create_uninitialized(0);
+ tls->on_tls_ready_to_write = [&](TLS::TLSv12& tls) {
+ if (sent_request)
+ return;
+ sent_request = true;
+ if (!tls.write("GET / HTTP/1.1\r\nHost: "_b)) {
+ FAIL("write(0) failed");
+ loop.quit(0);
+ }
+ auto* the_server = DEFAULT_SERVER;
+ if (!tls.write(StringView(the_server).bytes())) {
+ FAIL("write(1) failed");
+ loop.quit(0);
+ }
+ if (!tls.write("\r\nConnection : close\r\n\r\n"_b)) {
+ FAIL("write(2) failed");
+ loop.quit(0);
+ }
+ };
+ tls->on_tls_ready_to_read = [&](TLS::TLSv12& tls) {
+ auto data = tls.read();
+ if (!data.has_value()) {
+ FAIL("No data received");
+ loop.quit(1);
+ } else {
+ // print_buffer(data.value(), 16);
+ contents.append(data.value().data(), data.value().size());
+ }
+ };
+ tls->on_tls_finished = [&] {
+ loop.quit(0);
+ };
+ tls->on_tls_error = [&](TLS::AlertDescription) {
+ FAIL("Connection failure");
+ loop.quit(1);
+ };
+ if (!tls->connect(DEFAULT_SERVER, port)) {
+ FAIL("connect() failed");
+ return;
+ }
+ loop.exec();
+}