123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- #if defined(USE_MBEDTLS) // USE_MBEDTLS used with NO_SSL
- #include "mbedtls/certs.h"
- #include "mbedtls/ctr_drbg.h"
- #include "mbedtls/debug.h"
- #include "mbedtls/entropy.h"
- #include "mbedtls/error.h"
- #include "mbedtls/net.h"
- #include "mbedtls/pk.h"
- #include "mbedtls/platform.h"
- #include "mbedtls/ssl.h"
- #include "mbedtls/x509.h"
- #include "mbedtls/x509_crt.h"
- #include <string.h>
- typedef mbedtls_ssl_context SSL;
- typedef struct {
- mbedtls_ssl_config conf; /* SSL configuration */
- mbedtls_x509_crt cert; /* Certificate */
- mbedtls_ctr_drbg_context ctr; /* Counter random generator state */
- mbedtls_entropy_context entropy; /* Entropy context */
- mbedtls_pk_context pkey; /* Private key */
- } SSL_CTX;
- /* public api */
- int mbed_sslctx_init(SSL_CTX *ctx, const char *crt);
- void mbed_sslctx_uninit(SSL_CTX *ctx);
- void mbed_ssl_close(mbedtls_ssl_context *ssl);
- int mbed_ssl_accept(mbedtls_ssl_context **ssl, SSL_CTX *ssl_ctx, int *sock);
- int mbed_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, int len);
- int mbed_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, int len);
- static void mbed_debug(void *context,
- int level,
- const char *file,
- int line,
- const char *str);
- static int mbed_ssl_handshake(mbedtls_ssl_context *ssl);
- int
- mbed_sslctx_init(SSL_CTX *ctx, const char *crt)
- {
- mbedtls_ssl_config *conf;
- int rc;
- if (ctx == NULL || crt == NULL) {
- return -1;
- }
- DEBUG_TRACE("Initializing MbedTLS SSL");
- mbedtls_entropy_init(&ctx->entropy);
- conf = &ctx->conf;
- mbedtls_ssl_config_init(conf);
- /* Set mbedTLS debug level by defining MG_CONFIG_MBEDTLS_DEBUG:
- * 0 No debug = mbedTLS DEFAULT
- * 1 Error (default if "DEBUG" is set for CivetWeb)
- * 2 State change
- * 3 Informational
- * 4 Verbose
- */
- #if defined(DEBUG) or defined(MG_CONFIG_MBEDTLS_DEBUG)
- #if defined(MG_CONFIG_MBEDTLS_DEBUG)
- mbedtls_debug_set_threshold(MG_CONFIG_MBEDTLS_DEBUG);
- #else
- mbedtls_debug_set_threshold(1);
- #endif
- mbedtls_ssl_conf_dbg(conf, mbed_debug, (void *)ctx);
- #endif
- /* Initialize TLS key and cert */
- mbedtls_pk_init(&ctx->pkey);
- mbedtls_ctr_drbg_init(&ctx->ctr);
- mbedtls_x509_crt_init(&ctx->cert);
- if ((rc = mbedtls_ctr_drbg_seed(&ctx->ctr,
- mbedtls_entropy_func,
- &ctx->entropy,
- (unsigned char *)"CivetWeb",
- strlen("CivetWeb")))
- != 0) {
- DEBUG_TRACE("TLS random seed failed");
- return -1;
- }
- if (mbedtls_pk_parse_keyfile(&ctx->pkey, crt, NULL) != 0) {
- DEBUG_TRACE("TLS parse key file failed");
- return -1;
- }
- if (mbedtls_x509_crt_parse_file(&ctx->cert, crt) != 0) {
- DEBUG_TRACE("TLS parse crt file failed");
- return -1;
- }
- if ((rc = mbedtls_ssl_config_defaults(conf,
- MBEDTLS_SSL_IS_SERVER,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT))
- != 0) {
- DEBUG_TRACE("TLS set defaults failed");
- return -1;
- }
- mbedtls_ssl_conf_rng(conf, mbedtls_ctr_drbg_random, &ctx->ctr);
- /* Set auth mode if peer cert should be verified */
- mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
- mbedtls_ssl_conf_ca_chain(conf, NULL, NULL);
- /* Configure server cert and key */
- if ((rc = mbedtls_ssl_conf_own_cert(conf, &ctx->cert, &ctx->pkey)) != 0) {
- DEBUG_TRACE("TLS cannot set certificate and private key");
- return -1;
- }
- return 0;
- }
- void
- mbed_sslctx_uninit(SSL_CTX *ctx)
- {
- mbedtls_ctr_drbg_free(&ctx->ctr);
- mbedtls_pk_free(&ctx->pkey);
- mbedtls_x509_crt_free(&ctx->cert);
- mbedtls_entropy_free(&ctx->entropy);
- mbedtls_ssl_config_free(&ctx->conf);
- }
- int
- mbed_ssl_accept(mbedtls_ssl_context **ssl, SSL_CTX *ssl_ctx, int *sock)
- {
- *ssl = calloc(1, sizeof(**ssl));
- if (*ssl == NULL) {
- DEBUG_TRACE("TLS accept: malloc ssl failed (%i)", sizeof(**ssl));
- return -1;
- }
- mbedtls_ssl_init(*ssl);
- mbedtls_ssl_setup(*ssl, &ssl_ctx->conf);
- mbedtls_ssl_set_bio(*ssl, sock, mbedtls_net_send, mbedtls_net_recv, NULL);
- if (mbed_ssl_handshake(*ssl) != 0) {
- DEBUG_TRACE("TLS handshake failed");
- return -1;
- }
- DEBUG_TRACE("TLS connection accepted, state: %d", (*ssl)->state);
- return 0;
- }
- void
- mbed_ssl_close(mbedtls_ssl_context *ssl)
- {
- DEBUG_TRACE("TLS close");
- mbedtls_ssl_close_notify(ssl);
- mbedtls_ssl_free(ssl);
- ssl = NULL;
- }
- static int
- mbed_ssl_handshake(mbedtls_ssl_context *ssl)
- {
- int rc;
- while ((rc = mbedtls_ssl_handshake(ssl)) != 0) {
- if (rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE
- && rc != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
- break;
- }
- }
- DEBUG_TRACE("TLS handshake rc: %d, state: %d", rc, ssl->state);
- return rc;
- }
- int
- mbed_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, int len)
- {
- int rc = mbedtls_ssl_read(ssl, buf, len);
- /* DEBUG_TRACE("mbedtls_ssl_read: %d", rc); */
- return rc;
- }
- int
- mbed_ssl_write(mbedtls_ssl_context *ssl, const unsigned char *buf, int len)
- {
- int rc = mbedtls_ssl_write(ssl, buf, len);
- /* DEBUG_TRACE("mbedtls_ssl_write: %d", rc); */
- return rc;
- }
- static void
- mbed_debug(void *user_param,
- int level,
- const char *file,
- int line,
- const char *str)
- {
- (void)level; /* Ignored. Limit is set using mbedtls_debug_set_threshold */
- (void)user_param; /* Ignored. User parameter (context) is set using
- mbedtls_ssl_conf_dbg */
- DEBUG_TRACE("mbedTLS DEBUG: file: [%s] line: [%d] str: [%s]",
- file,
- line,
- str);
- }
- #endif /* USE_MBEDTLS */
|