HandshakeCertificate.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Debug.h>
  7. #include <AK/Endian.h>
  8. #include <AK/Random.h>
  9. #include <LibCore/Timer.h>
  10. #include <LibCrypto/ASN1/DER.h>
  11. #include <LibCrypto/PK/Code/EMSA_PSS.h>
  12. #include <LibTLS/TLSv12.h>
  13. namespace TLS {
  14. ssize_t TLSv12::handle_certificate(ReadonlyBytes buffer)
  15. {
  16. ssize_t res = 0;
  17. if (buffer.size() < 3) {
  18. dbgln_if(TLS_DEBUG, "not enough certificate header data");
  19. return (i8)Error::NeedMoreData;
  20. }
  21. u32 certificate_total_length = buffer[0] * 0x10000 + buffer[1] * 0x100 + buffer[2];
  22. dbgln_if(TLS_DEBUG, "total length: {}", certificate_total_length);
  23. if (certificate_total_length <= 4)
  24. return 3 * certificate_total_length;
  25. res += 3;
  26. if (certificate_total_length > buffer.size() - res) {
  27. dbgln_if(TLS_DEBUG, "not enough data for claimed total cert length");
  28. return (i8)Error::NeedMoreData;
  29. }
  30. size_t size = certificate_total_length;
  31. bool valid_certificate = false;
  32. while (size > 0) {
  33. if (buffer.size() - res < 3) {
  34. dbgln_if(TLS_DEBUG, "not enough data for certificate length");
  35. return (i8)Error::NeedMoreData;
  36. }
  37. size_t certificate_size = buffer[res] * 0x10000 + buffer[res + 1] * 0x100 + buffer[res + 2];
  38. res += 3;
  39. if (buffer.size() - res < certificate_size) {
  40. dbgln_if(TLS_DEBUG, "not enough data for certificate body");
  41. return (i8)Error::NeedMoreData;
  42. }
  43. auto res_cert = res;
  44. auto remaining = certificate_size;
  45. do {
  46. if (remaining <= 3) {
  47. dbgln("Ran out of data");
  48. break;
  49. }
  50. if (buffer.size() < (size_t)res_cert + 3) {
  51. dbgln("not enough data to read cert size ({} < {})", buffer.size(), res_cert + 3);
  52. break;
  53. }
  54. size_t certificate_size_specific = buffer[res_cert] * 0x10000 + buffer[res_cert + 1] * 0x100 + buffer[res_cert + 2];
  55. res_cert += 3;
  56. remaining -= 3;
  57. if (certificate_size_specific > remaining) {
  58. dbgln("invalid certificate size (expected {} but got {})", remaining, certificate_size_specific);
  59. break;
  60. }
  61. remaining -= certificate_size_specific;
  62. auto certificate = Certificate::parse_certificate(buffer.slice(res_cert, certificate_size_specific), false);
  63. if (!certificate.is_error()) {
  64. m_context.certificates.empend(certificate.value());
  65. valid_certificate = true;
  66. } else {
  67. dbgln("Failed to parse client cert: {}", certificate.error());
  68. dbgln("{:hex-dump}", buffer.slice(res_cert, certificate_size_specific));
  69. dbgln("");
  70. }
  71. res_cert += certificate_size_specific;
  72. } while (remaining > 0);
  73. if (remaining) {
  74. dbgln("extraneous {} bytes left over after parsing certificates", remaining);
  75. }
  76. size -= certificate_size + 3;
  77. res += certificate_size;
  78. }
  79. if (!valid_certificate)
  80. return (i8)Error::UnsupportedCertificate;
  81. if ((size_t)res != buffer.size())
  82. dbgln("some data left unread: {} bytes out of {}", res, buffer.size());
  83. return res;
  84. }
  85. ssize_t TLSv12::handle_certificate_verify(ReadonlyBytes)
  86. {
  87. dbgln("FIXME: parse_verify");
  88. return 0;
  89. }
  90. }