TLSSocket.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "TLSSocket.h"
  2. #include <mbedtls/ctr_drbg.h> // for mbedtls_ctr_drbg_free, mbedtls_ctr_...
  3. #include <mbedtls/entropy.h> // for mbedtls_entropy_free, mbedtls_entro...
  4. #include <mbedtls/net_sockets.h> // for mbedtls_net_connect, mbedtls_net_free
  5. #include <mbedtls/ssl.h> // for mbedtls_ssl_conf_authmode, mbedtls_...
  6. #include <cstring> // for strlen, NULL
  7. #include <stdexcept> // for runtime_error
  8. #include "BellLogger.h" // for AbstractLogger, BELL_LOG
  9. #include "X509Bundle.h" // for shouldVerify, attach
  10. /**
  11. * Platform TLSSocket implementation for the mbedtls
  12. */
  13. bell::TLSSocket::TLSSocket() {
  14. this->isClosed = false;
  15. mbedtls_net_init(&server_fd);
  16. mbedtls_ssl_init(&ssl);
  17. mbedtls_ssl_config_init(&conf);
  18. if (bell::X509Bundle::shouldVerify()) {
  19. bell::X509Bundle::attach(&conf);
  20. }
  21. mbedtls_ctr_drbg_init(&ctr_drbg);
  22. mbedtls_entropy_init(&entropy);
  23. const char* pers = "euphonium";
  24. int ret;
  25. if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
  26. (const unsigned char*)pers, strlen(pers))) !=
  27. 0) {
  28. BELL_LOG(error, "http_tls",
  29. "failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
  30. throw std::runtime_error("mbedtls_ctr_drbg_seed failed");
  31. }
  32. }
  33. void bell::TLSSocket::open(const std::string& hostUrl, uint16_t port) {
  34. int ret;
  35. if ((ret = mbedtls_net_connect(&server_fd, hostUrl.c_str(),
  36. std::to_string(port).c_str(),
  37. MBEDTLS_NET_PROTO_TCP)) != 0) {
  38. BELL_LOG(error, "http_tls", "failed! connect returned %d\n", ret);
  39. }
  40. if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
  41. MBEDTLS_SSL_TRANSPORT_STREAM,
  42. MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  43. BELL_LOG(error, "http_tls", "failed! config returned %d\n", ret);
  44. throw std::runtime_error("mbedtls_ssl_config_defaults failed");
  45. }
  46. // Only verify if the X509 bundle is present
  47. if (bell::X509Bundle::shouldVerify()) {
  48. mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
  49. } else {
  50. mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
  51. }
  52. mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
  53. mbedtls_ssl_setup(&ssl, &conf);
  54. if ((ret = mbedtls_ssl_set_hostname(&ssl, hostUrl.c_str())) != 0) {
  55. throw std::runtime_error("mbedtls_ssl_set_hostname failed");
  56. }
  57. mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
  58. NULL);
  59. while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
  60. if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
  61. BELL_LOG(error, "http_tls", "failed! config returned %d\n", ret);
  62. throw std::runtime_error("mbedtls_ssl_handshake error");
  63. }
  64. }
  65. }
  66. size_t bell::TLSSocket::read(uint8_t* buf, size_t len) {
  67. return mbedtls_ssl_read(&ssl, buf, len);
  68. }
  69. size_t bell::TLSSocket::write(uint8_t* buf, size_t len) {
  70. return mbedtls_ssl_write(&ssl, buf, len);
  71. }
  72. size_t bell::TLSSocket::poll() {
  73. return mbedtls_ssl_get_bytes_avail(&ssl);
  74. }
  75. bool bell::TLSSocket::isOpen() {
  76. return !isClosed;
  77. }
  78. void bell::TLSSocket::close() {
  79. if (!isClosed) {
  80. mbedtls_net_free(&server_fd);
  81. mbedtls_ssl_free(&ssl);
  82. mbedtls_ssl_config_free(&conf);
  83. mbedtls_ctr_drbg_free(&ctr_drbg);
  84. mbedtls_entropy_free(&entropy);
  85. this->isClosed = true;
  86. }
  87. }