Skip to content

Commit

Permalink
Revert "LibTLS+Everywhere: Switch to using WolfSSL"
Browse files Browse the repository at this point in the history
This reverts commit 8bb610b.
Linking wolfSSL seems to cause more legal trouble than it's worth due to
it being GPLv2, so let's undo this for now.
  • Loading branch information
alimpfard authored and ADKaster committed Jul 6, 2024
1 parent 8d593bc commit e0465b8
Show file tree
Hide file tree
Showing 28 changed files with 3,944 additions and 164 deletions.
3 changes: 2 additions & 1 deletion Ladybird/Android/src/main/cpp/RequestServerService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ ErrorOr<ByteString> find_certificates(StringView serenity_resource_root)
ErrorOr<int> service_main(int ipc_socket)
{
// Ensure the certificates are read out here.
TLS::WolfTLS::install_certificate_store_paths({ TRY(find_certificates(s_serenity_resource_root)) });
DefaultRootCACertificates::set_default_certificate_paths(Vector { TRY(find_certificates(s_serenity_resource_root)) });
[[maybe_unused]] auto& certs = DefaultRootCACertificates::the();

Core::EventLoop event_loop;

Expand Down
4 changes: 2 additions & 2 deletions Ladybird/RequestServer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
// Ensure the certificates are read out here.
if (certificates.is_empty())
certificates.append(TRY(find_certificates(serenity_resource_root)));

TLS::WolfTLS::install_certificate_store_paths(move(certificates));
DefaultRootCACertificates::set_default_certificate_paths(certificates.span());
[[maybe_unused]] auto& certs = DefaultRootCACertificates::the();

Core::EventLoop event_loop;

Expand Down
1 change: 1 addition & 0 deletions Meta/Lagom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ if (BUILD_TESTING)
endforeach()

# LibTLS needs a special working directory to find cacert.pem
lagom_test(../../Tests/LibTLS/TestTLSHandshake.cpp LibTLS LIBS LibTLS LibCrypto)
lagom_test(../../Tests/LibTLS/TestTLSCertificateParser.cpp LibTLS LIBS LibTLS LibCrypto)

# The FLAC tests need a special working directory to find the test files
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ At the moment, many core library support components are inherited from SerenityO
- LibWeb: Web rendering engine
- LibJS: JavaScript engine
- LibWasm: WebAssembly implementation
- LibCrypto: Cryptography primitives
- LibTLS: Some certificate parsing primitives
- LibCrypto/LibTLS: Cryptography primitives and Transport Layer Security
- LibHTTP: HTTP/1.1 client
- LibGfx: 2D Graphics Library, Image Decoding and Rendering
- LibArchive: Archive file format support
Expand Down
1 change: 1 addition & 0 deletions Tests/LibTLS/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(TEST_SOURCES
TestTLSCertificateParser.cpp
TestTLSHandshake.cpp
)

foreach(source IN LISTS TEST_SOURCES)
Expand Down
84 changes: 84 additions & 0 deletions Tests/LibTLS/TestTLSHandshake.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2021, Peter Bocan <me@pbocan.net>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <AK/Base64.h>
#include <LibCore/ConfigFile.h>
#include <LibCore/EventLoop.h>
#include <LibCrypto/ASN1/ASN1.h>
#include <LibCrypto/ASN1/PEM.h>
#include <LibFileSystem/FileSystem.h>
#include <LibTLS/TLSv12.h>
#include <LibTest/TestCase.h>

static StringView ca_certs_file = "./cacert.pem"sv;
static int port = 443;

constexpr auto DEFAULT_SERVER = "www.google.com"sv;

static ByteBuffer operator""_b(char const* string, size_t length)
{
return ByteBuffer::copy(string, length).release_value();
}

ErrorOr<Vector<Certificate>> load_certificates();
ByteString locate_ca_certs_file();

ByteString locate_ca_certs_file()
{
if (FileSystem::exists(ca_certs_file)) {
return ca_certs_file;
}
auto on_target_path = ByteString("/etc/cacert.pem");
if (FileSystem::exists(on_target_path)) {
return on_target_path;
}
return "";
}

ErrorOr<Vector<Certificate>> load_certificates()
{
auto cacert_file = TRY(Core::File::open(locate_ca_certs_file(), Core::File::OpenMode::Read));
auto data = TRY(cacert_file->read_until_eof());
return TRY(DefaultRootCACertificates::parse_pem_root_certificate_authorities(data));
}

TEST_CASE(test_TLS_hello_handshake)
{
Core::EventLoop loop;
TLS::Options options;
options.set_root_certificates(TRY_OR_FAIL(load_certificates()));
options.set_alert_handler([&](TLS::AlertDescription) {
FAIL("Connection failure");
loop.quit(1);
});
options.set_finish_callback([&] {
loop.quit(0);
});

auto tls = TRY_OR_FAIL(TLS::TLSv12::connect(DEFAULT_SERVER, port, move(options)));
ByteBuffer contents;
tls->on_ready_to_read = [&] {
(void)TRY_OR_FAIL(tls->read_some(contents.must_get_bytes_for_writing(4 * KiB)));
loop.quit(0);
};

if (tls->write_until_depleted("GET / HTTP/1.1\r\nHost: "_b).is_error()) {
FAIL("write(0) failed");
return;
}

auto the_server = DEFAULT_SERVER;
if (tls->write_until_depleted(the_server.bytes()).is_error()) {
FAIL("write(1) failed");
return;
}
if (tls->write_until_depleted("\r\nConnection : close\r\n\r\n"_b).is_error()) {
FAIL("write(2) failed");
return;
}

loop.exec();
}
2 changes: 0 additions & 2 deletions Userland/Libraries/LibCore/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,6 @@ class TCPSocket final : public Socket {

virtual ~TCPSocket() override { close(); }

int fd() { return m_helper.fd(); }

private:
explicit TCPSocket(PreventSIGPIPE prevent_sigpipe = PreventSIGPIPE::Yes)
: Socket(prevent_sigpipe)
Expand Down
4 changes: 2 additions & 2 deletions Userland/Libraries/LibCrypto/Authentication/HMAC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
#include <AK/Types.h>
#include <AK/Vector.h>

namespace Crypto::Authentication {

constexpr static auto IPAD = 0x36;
constexpr static auto OPAD = 0x5c;

namespace Crypto::Authentication {

template<typename HashT>
class HMAC {
public:
Expand Down
3 changes: 1 addition & 2 deletions Userland/Libraries/LibHTTP/HttpsJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace HTTP {

void HttpsJob::set_certificate(ByteString certificate, ByteString key)
{
(void)certificate;
(void)key;
m_received_client_certificates = TLS::TLSv12::parse_pem_certificate(certificate.bytes(), key.bytes());
}

}
10 changes: 7 additions & 3 deletions Userland/Libraries/LibTLS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ add_compile_options(-Wvla)

set(SOURCES
Certificate.cpp
Handshake.cpp
HandshakeCertificate.cpp
HandshakeClient.cpp
HandshakeServer.cpp
Record.cpp
Socket.cpp
TLSv12.cpp
)

find_package(WolfSSL REQUIRED)

serenity_lib(LibTLS tls)
target_link_libraries(LibTLS PRIVATE LibCore LibCrypto wolfssl::wolfssl)
target_link_libraries(LibTLS PRIVATE LibCore LibCrypto LibFileSystem)

include(ca_certificates_data)
19 changes: 19 additions & 0 deletions Userland/Libraries/LibTLS/Certificate.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,25 @@ class Certificate {
private:
Optional<bool> m_is_self_signed;
};

class DefaultRootCACertificates {
public:
DefaultRootCACertificates();

Vector<Certificate> const& certificates() const { return m_ca_certificates; }

static ErrorOr<Vector<Certificate>> parse_pem_root_certificate_authorities(ByteBuffer&);
static ErrorOr<Vector<Certificate>> load_certificates(Span<ByteString> custom_cert_paths = {});

static DefaultRootCACertificates& the();

static void set_default_certificate_paths(Span<ByteString> paths);

private:
Vector<Certificate> m_ca_certificates;
};

}

using TLS::Certificate;
using TLS::DefaultRootCACertificates;
90 changes: 90 additions & 0 deletions Userland/Libraries/LibTLS/CipherSuite.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <AK/Types.h>
#include <LibTLS/Extensions.h>

namespace TLS {

// Defined in RFC 5246 section 7.4.1.4.1
struct SignatureAndHashAlgorithm {
HashAlgorithm hash;
SignatureAlgorithm signature;
};

enum class KeyExchangeAlgorithm {
Invalid,
// Defined in RFC 5246 section 7.4.2 / RFC 4279 section 4
RSA_PSK,
// Defined in RFC 5246 section 7.4.3
DHE_DSS,
DHE_RSA,
DH_anon,
RSA,
DH_DSS,
DH_RSA,
// Defined in RFC 4492 section 2
ECDHE_RSA,
ECDH_ECDSA,
ECDH_RSA,
ECDHE_ECDSA,
ECDH_anon,
};

// Defined in RFC 5246 section 7.4.1.4.1
constexpr SignatureAlgorithm signature_for_key_exchange_algorithm(KeyExchangeAlgorithm algorithm)
{
switch (algorithm) {
case KeyExchangeAlgorithm::RSA:
case KeyExchangeAlgorithm::DHE_RSA:
case KeyExchangeAlgorithm::DH_RSA:
case KeyExchangeAlgorithm::RSA_PSK:
case KeyExchangeAlgorithm::ECDH_RSA:
case KeyExchangeAlgorithm::ECDHE_RSA:
return SignatureAlgorithm::RSA;
case KeyExchangeAlgorithm::DHE_DSS:
case KeyExchangeAlgorithm::DH_DSS:
return SignatureAlgorithm::DSA;
case KeyExchangeAlgorithm::ECDH_ECDSA:
case KeyExchangeAlgorithm::ECDHE_ECDSA:
return SignatureAlgorithm::ECDSA;
case KeyExchangeAlgorithm::DH_anon:
case KeyExchangeAlgorithm::ECDH_anon:
default:
return SignatureAlgorithm::ANONYMOUS;
}
}

enum class CipherAlgorithm {
Invalid,
AES_128_CBC,
AES_128_GCM,
AES_128_CCM,
AES_128_CCM_8,
AES_256_CBC,
AES_256_GCM,
};

constexpr size_t cipher_key_size(CipherAlgorithm algorithm)
{
switch (algorithm) {
case CipherAlgorithm::AES_128_CBC:
case CipherAlgorithm::AES_128_GCM:
case CipherAlgorithm::AES_128_CCM:
case CipherAlgorithm::AES_128_CCM_8:
return 128;
case CipherAlgorithm::AES_256_CBC:
case CipherAlgorithm::AES_256_GCM:
return 256;
case CipherAlgorithm::Invalid:
default:
return 0;
}
}

}
Loading

0 comments on commit e0465b8

Please sign in to comment.