TestTLSHandshake.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * Copyright (c) 2021, Peter Bocan <me@pbocan.net>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Base64.h>
  7. #include <LibCore/ConfigFile.h>
  8. #include <LibCore/EventLoop.h>
  9. #include <LibCrypto/ASN1/ASN1.h>
  10. #include <LibCrypto/ASN1/PEM.h>
  11. #include <LibFileSystem/FileSystem.h>
  12. #include <LibTLS/TLSv12.h>
  13. #include <LibTest/TestCase.h>
  14. static StringView ca_certs_file = "./cacert.pem"sv;
  15. static int port = 443;
  16. constexpr auto DEFAULT_SERVER = "www.google.com"sv;
  17. static ByteBuffer operator""_b(char const* string, size_t length)
  18. {
  19. return ByteBuffer::copy(string, length).release_value();
  20. }
  21. ErrorOr<Vector<Certificate>> load_certificates();
  22. ByteString locate_ca_certs_file();
  23. ByteString locate_ca_certs_file()
  24. {
  25. if (FileSystem::exists(ca_certs_file)) {
  26. return ca_certs_file;
  27. }
  28. auto on_target_path = ByteString("/etc/cacert.pem");
  29. if (FileSystem::exists(on_target_path)) {
  30. return on_target_path;
  31. }
  32. return "";
  33. }
  34. ErrorOr<Vector<Certificate>> load_certificates()
  35. {
  36. auto cacert_file = TRY(Core::File::open(locate_ca_certs_file(), Core::File::OpenMode::Read));
  37. auto data = TRY(cacert_file->read_until_eof());
  38. return TRY(DefaultRootCACertificates::parse_pem_root_certificate_authorities(data));
  39. }
  40. TEST_CASE(test_TLS_hello_handshake)
  41. {
  42. Core::EventLoop loop;
  43. TLS::Options options;
  44. options.set_root_certificates(TRY_OR_FAIL(load_certificates()));
  45. options.set_alert_handler([&](TLS::AlertDescription) {
  46. FAIL("Connection failure");
  47. loop.quit(1);
  48. });
  49. options.set_finish_callback([&] {
  50. loop.quit(0);
  51. });
  52. auto tls = TRY_OR_FAIL(TLS::TLSv12::connect(DEFAULT_SERVER, port, move(options)));
  53. ByteBuffer contents;
  54. tls->on_ready_to_read = [&] {
  55. (void)TRY_OR_FAIL(tls->read_some(contents.must_get_bytes_for_writing(4 * KiB)));
  56. loop.quit(0);
  57. };
  58. if (tls->write_until_depleted("GET / HTTP/1.1\r\nHost: "_b).is_error()) {
  59. FAIL("write(0) failed");
  60. return;
  61. }
  62. auto the_server = DEFAULT_SERVER;
  63. if (tls->write_until_depleted(the_server.bytes()).is_error()) {
  64. FAIL("write(1) failed");
  65. return;
  66. }
  67. if (tls->write_until_depleted("\r\nConnection : close\r\n\r\n"_b).is_error()) {
  68. FAIL("write(2) failed");
  69. return;
  70. }
  71. loop.exec();
  72. }