mod_mbedtls.inl 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #if defined(USE_MBEDTLS) // USE_MBEDTLS used with NO_SSL
  2. #include "mbedtls/ctr_drbg.h"
  3. #include "mbedtls/debug.h"
  4. #include "mbedtls/entropy.h"
  5. #include "mbedtls/error.h"
  6. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  7. // The file include/mbedtls/net.h was removed in v3.0.0 because its only
  8. // function was to include mbedtls/net_sockets.h which now should be included
  9. // directly.
  10. #include "mbedtls/net_sockets.h"
  11. #else
  12. #include "mbedtls/net.h"
  13. #endif
  14. #include "mbedtls/pk.h"
  15. #include "mbedtls/platform.h"
  16. #include "mbedtls/ssl.h"
  17. #include "mbedtls/x509.h"
  18. #include "mbedtls/x509_crt.h"
  19. #include <string.h>
  20. typedef mbedtls_ssl_context SSL;
  21. typedef struct {
  22. mbedtls_ssl_config conf; /* SSL configuration */
  23. mbedtls_x509_crt cert; /* Certificate */
  24. mbedtls_ctr_drbg_context ctr; /* Counter random generator state */
  25. mbedtls_entropy_context entropy; /* Entropy context */
  26. mbedtls_pk_context pkey; /* Private key */
  27. } SSL_CTX;
  28. /* public api */
  29. int mbed_sslctx_init(SSL_CTX *ctx, const char *crt);
  30. void mbed_sslctx_uninit(SSL_CTX *ctx);
  31. void mbed_ssl_close(mbedtls_ssl_context *ssl);
  32. int mbed_ssl_accept(mbedtls_ssl_context **ssl,
  33. SSL_CTX *ssl_ctx,
  34. int *sock,
  35. struct mg_context *phys_ctx);
  36. int mbed_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, int len);
  37. int mbed_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, int len);
  38. static void mbed_debug(void *context,
  39. int level,
  40. const char *file,
  41. int line,
  42. const char *str);
  43. static int mbed_ssl_handshake(mbedtls_ssl_context *ssl);
  44. int
  45. mbed_sslctx_init(SSL_CTX *ctx, const char *crt)
  46. {
  47. mbedtls_ssl_config *conf;
  48. int rc;
  49. if (ctx == NULL || crt == NULL) {
  50. return -1;
  51. }
  52. DEBUG_TRACE("%s", "Initializing MbedTLS SSL");
  53. mbedtls_entropy_init(&ctx->entropy);
  54. conf = &ctx->conf;
  55. mbedtls_ssl_config_init(conf);
  56. /* Set mbedTLS debug level by defining MG_CONFIG_MBEDTLS_DEBUG:
  57. * 0 No debug = mbedTLS DEFAULT
  58. * 1 Error (default if "DEBUG" is set for CivetWeb)
  59. * 2 State change
  60. * 3 Informational
  61. * 4 Verbose
  62. */
  63. #if defined(DEBUG) || defined(MG_CONFIG_MBEDTLS_DEBUG)
  64. #if defined(MG_CONFIG_MBEDTLS_DEBUG)
  65. mbedtls_debug_set_threshold(MG_CONFIG_MBEDTLS_DEBUG);
  66. #else
  67. mbedtls_debug_set_threshold(1);
  68. #endif
  69. mbedtls_ssl_conf_dbg(conf, mbed_debug, (void *)ctx);
  70. #endif
  71. /* Initialize TLS key and cert */
  72. mbedtls_pk_init(&ctx->pkey);
  73. mbedtls_ctr_drbg_init(&ctx->ctr);
  74. mbedtls_x509_crt_init(&ctx->cert);
  75. rc = mbedtls_ctr_drbg_seed(&ctx->ctr,
  76. mbedtls_entropy_func,
  77. &ctx->entropy,
  78. (unsigned char *)"CivetWeb",
  79. strlen("CivetWeb"));
  80. if (rc != 0) {
  81. DEBUG_TRACE("TLS random seed failed (%i)", rc);
  82. return -1;
  83. }
  84. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  85. // mbedtls_pk_parse_keyfile() has changed in mbedTLS 3.0. You now need
  86. // to pass a properly seeded, cryptographically secure RNG when calling
  87. // these functions. It is used for blinding, a countermeasure against
  88. // side-channel attacks.
  89. // https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#some-functions-gained-an-rng-parameter
  90. rc = mbedtls_pk_parse_keyfile(&ctx->pkey, crt, NULL, mbedtls_ctr_drbg_random, &ctx->ctr);
  91. #else
  92. rc = mbedtls_pk_parse_keyfile(&ctx->pkey, crt, NULL);
  93. #endif
  94. if (rc != 0) {
  95. DEBUG_TRACE("TLS parse key file failed (%i)", rc);
  96. return -1;
  97. }
  98. rc = mbedtls_x509_crt_parse_file(&ctx->cert, crt);
  99. if (rc != 0) {
  100. DEBUG_TRACE("TLS parse crt file failed (%i)", rc);
  101. return -1;
  102. }
  103. rc = mbedtls_ssl_config_defaults(conf,
  104. MBEDTLS_SSL_IS_SERVER,
  105. MBEDTLS_SSL_TRANSPORT_STREAM,
  106. MBEDTLS_SSL_PRESET_DEFAULT);
  107. if (rc != 0) {
  108. DEBUG_TRACE("TLS set defaults failed (%i)", rc);
  109. return -1;
  110. }
  111. mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &ctx->ctr);
  112. /* Set auth mode if peer cert should be verified */
  113. mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
  114. mbedtls_ssl_conf_ca_chain(conf, NULL, NULL);
  115. /* Configure server cert and key */
  116. rc = mbedtls_ssl_conf_own_cert(conf, &ctx->cert, &ctx->pkey);
  117. if (rc != 0) {
  118. DEBUG_TRACE("TLS cannot set certificate and private key (%i)", rc);
  119. return -1;
  120. }
  121. return 0;
  122. }
  123. void
  124. mbed_sslctx_uninit(SSL_CTX *ctx)
  125. {
  126. mbedtls_ctr_drbg_free(&ctx->ctr);
  127. mbedtls_pk_free(&ctx->pkey);
  128. mbedtls_x509_crt_free(&ctx->cert);
  129. mbedtls_entropy_free(&ctx->entropy);
  130. mbedtls_ssl_config_free(&ctx->conf);
  131. }
  132. int
  133. mbed_ssl_accept(mbedtls_ssl_context **ssl,
  134. SSL_CTX *ssl_ctx,
  135. int *sock,
  136. struct mg_context *phys_ctx)
  137. {
  138. int rc;
  139. (void)phys_ctx; /* unused, if server statistics is not turned on */
  140. DEBUG_TRACE("TLS accept processing %p", ssl);
  141. *ssl = (mbedtls_ssl_context *)mg_calloc_ctx(1,
  142. sizeof(mbedtls_ssl_context),
  143. phys_ctx);
  144. if (*ssl == NULL) {
  145. DEBUG_TRACE("TLS accept: malloc ssl failed (%i)",
  146. (int)sizeof(mbedtls_ssl_context));
  147. return -1;
  148. }
  149. mbedtls_ssl_init(*ssl);
  150. mbedtls_ssl_setup(*ssl, &ssl_ctx->conf);
  151. mbedtls_ssl_set_bio(*ssl, sock, mbedtls_net_send, mbedtls_net_recv, NULL);
  152. rc = mbed_ssl_handshake(*ssl);
  153. if (rc != 0) {
  154. DEBUG_TRACE("TLS handshake failed (%i)", rc);
  155. mbedtls_ssl_free(*ssl);
  156. mg_free(*ssl);
  157. *ssl = NULL;
  158. return -1;
  159. }
  160. DEBUG_TRACE("TLS connection %p accepted, state: %d", ssl, (*ssl)->state);
  161. return 0;
  162. }
  163. void
  164. mbed_ssl_close(mbedtls_ssl_context *ssl)
  165. {
  166. DEBUG_TRACE("TLS connection %p closed", ssl);
  167. mbedtls_ssl_close_notify(ssl);
  168. mbedtls_ssl_free(ssl);
  169. mg_free(ssl); /* mg_free for mg_calloc in mbed_ssl_accept */
  170. }
  171. static int
  172. mbed_ssl_handshake(mbedtls_ssl_context *ssl)
  173. {
  174. int rc;
  175. while ((rc = mbedtls_ssl_handshake(ssl)) != 0) {
  176. if (rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE
  177. && rc != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
  178. break;
  179. }
  180. }
  181. DEBUG_TRACE("TLS handshake rc: %d, state: %d", rc, ssl->state);
  182. return rc;
  183. }
  184. int
  185. mbed_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, int len)
  186. {
  187. int rc = mbedtls_ssl_read(ssl, buf, len);
  188. /* DEBUG_TRACE("mbedtls_ssl_read: %d", rc); */
  189. return rc;
  190. }
  191. int
  192. mbed_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, int len)
  193. {
  194. int rc = mbedtls_ssl_write(ssl, buf, len);
  195. /* DEBUG_TRACE("mbedtls_ssl_write: %d", rc); */
  196. return rc;
  197. }
  198. static void
  199. mbed_debug(void *user_param,
  200. int level,
  201. const char *file,
  202. int line,
  203. const char *str)
  204. {
  205. (void)level; /* Ignored. Limit is set using mbedtls_debug_set_threshold */
  206. (void)user_param; /* Ignored. User parameter (context) is set using
  207. mbedtls_ssl_conf_dbg */
  208. DEBUG_TRACE("mbedTLS DEBUG: file: [%s] line: [%d] str: [%s]",
  209. file,
  210. line,
  211. str);
  212. }
  213. #endif /* USE_MBEDTLS */