HandshakeCertificate.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. size_t index = 0;
  32. bool valid_certificate = false;
  33. while (size > 0) {
  34. ++index;
  35. if (buffer.size() - res < 3) {
  36. dbgln_if(TLS_DEBUG, "not enough data for certificate length");
  37. return (i8)Error::NeedMoreData;
  38. }
  39. size_t certificate_size = buffer[res] * 0x10000 + buffer[res + 1] * 0x100 + buffer[res + 2];
  40. res += 3;
  41. if (buffer.size() - res < certificate_size) {
  42. dbgln_if(TLS_DEBUG, "not enough data for certificate body");
  43. return (i8)Error::NeedMoreData;
  44. }
  45. auto res_cert = res;
  46. auto remaining = certificate_size;
  47. size_t certificates_in_chain = 0;
  48. do {
  49. if (remaining <= 3) {
  50. dbgln("Ran out of data");
  51. break;
  52. }
  53. ++certificates_in_chain;
  54. if (buffer.size() < (size_t)res_cert + 3) {
  55. dbgln("not enough data to read cert size ({} < {})", buffer.size(), res_cert + 3);
  56. break;
  57. }
  58. size_t certificate_size_specific = buffer[res_cert] * 0x10000 + buffer[res_cert + 1] * 0x100 + buffer[res_cert + 2];
  59. res_cert += 3;
  60. remaining -= 3;
  61. if (certificate_size_specific > remaining) {
  62. dbgln("invalid certificate size (expected {} but got {})", remaining, certificate_size_specific);
  63. break;
  64. }
  65. remaining -= certificate_size_specific;
  66. auto certificate = Certificate::parse_asn1(buffer.slice(res_cert, certificate_size_specific), false);
  67. if (certificate.has_value()) {
  68. if (certificate.value().is_valid()) {
  69. m_context.certificates.append(certificate.value());
  70. valid_certificate = true;
  71. }
  72. }
  73. res_cert += certificate_size_specific;
  74. } while (remaining > 0);
  75. if (remaining) {
  76. dbgln("extraneous {} bytes left over after parsing certificates", remaining);
  77. }
  78. size -= certificate_size + 3;
  79. res += certificate_size;
  80. }
  81. if (!valid_certificate)
  82. return (i8)Error::UnsupportedCertificate;
  83. if ((size_t)res != buffer.size())
  84. dbgln("some data left unread: {} bytes out of {}", res, buffer.size());
  85. return res;
  86. }
  87. ssize_t TLSv12::handle_certificate_verify(ReadonlyBytes)
  88. {
  89. dbgln("FIXME: parse_verify");
  90. return 0;
  91. }
  92. }