|
@@ -1,29 +1,30 @@
|
|
|
-#if defined(USE_MBEDTLS) // USE_MBEDTLS used with NO_SSL
|
|
|
+#if defined(USE_MBEDTLS) // USE_MBEDTLS used with NO_SSL
|
|
|
|
|
|
-#include <string.h>
|
|
|
#include "mbedtls/certs.h"
|
|
|
-#include "mbedtls/ssl.h"
|
|
|
-#include "mbedtls/net.h"
|
|
|
-#include "mbedtls/pk.h"
|
|
|
-#include "mbedtls/x509.h"
|
|
|
-#include "mbedtls/x509_crt.h"
|
|
|
#include "mbedtls/ctr_drbg.h"
|
|
|
+#include "mbedtls/debug.h"
|
|
|
#include "mbedtls/entropy.h"
|
|
|
#include "mbedtls/error.h"
|
|
|
-#include "mbedtls/debug.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 */
|
|
|
+ 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
|
|
|
+
|
|
|
+/* 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);
|
|
@@ -31,153 +32,186 @@ 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 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;
|
|
|
-
|
|
|
- fprintf(stdout, "Initializing MbedTLS SSL\n");
|
|
|
- if (ctx == NULL || crt == NULL) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- mbedtls_entropy_init(&ctx->entropy);
|
|
|
-
|
|
|
- conf = &ctx->conf;
|
|
|
- mbedtls_ssl_config_init(conf);
|
|
|
-
|
|
|
- // set debug level
|
|
|
-#if defined(CONFIG_MBEDTLS_DEBUG)
|
|
|
- mbedtls_debug_set_threshold(2);
|
|
|
- mbedtls_ssl_conf_dbg(conf, mbed_debug, stdout);
|
|
|
+ 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_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) {
|
|
|
- fprintf(stderr, "Cannot seed rng\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (mbedtls_pk_parse_keyfile(&ctx->pkey, crt, NULL) != 0) {
|
|
|
- fprintf(stderr, "parse key file failed\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (mbedtls_x509_crt_parse_file(&ctx->cert, crt) != 0) {
|
|
|
- fprintf(stderr, "parse crt file faied\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if ((rc = mbedtls_ssl_config_defaults(conf,
|
|
|
- MBEDTLS_SSL_IS_SERVER,
|
|
|
- MBEDTLS_SSL_TRANSPORT_STREAM,
|
|
|
- MBEDTLS_SSL_PRESET_DEFAULT))
|
|
|
- != 0) {
|
|
|
- fprintf(stderr, "Cannot set mbedtls defaults\n");
|
|
|
- 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) {
|
|
|
- fprintf(stderr, "Cannot define certificate and private key\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
+ 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
|
|
|
+
|
|
|
+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);
|
|
|
+ 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) {
|
|
|
- fprintf(stderr, "malloc ssl failed\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- mbedtls_ssl_init(*ssl);
|
|
|
- mbedtls_ssl_setup(*ssl, &ssl_ctx->conf);
|
|
|
+ *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) {
|
|
|
- fprintf(stderr, "handshake failed\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- fprintf(stdout, "mbedtls mbed_ssl_accept state:%d\n", (*ssl)->state);
|
|
|
+ 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)
|
|
|
{
|
|
|
- fprintf(stdout, "mbedtls close\n");
|
|
|
- mbedtls_ssl_close_notify(ssl);
|
|
|
- mbedtls_ssl_free(ssl);
|
|
|
- ssl = NULL;
|
|
|
+ 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;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- fprintf(stdout, "mbedtls handshake rc:%d state:%d\n", rc, ssl->state);
|
|
|
- return rc;
|
|
|
+ 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);
|
|
|
- //fprintf(stdout, "mbedtls: mbedtls_ssl_read %d\n", rc);
|
|
|
- return rc;
|
|
|
+ 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);
|
|
|
- //fprintf(stdout, "mbedtls: mbedtls_ssl_write:%d\n", rc);
|
|
|
- return rc;
|
|
|
+ int rc = mbedtls_ssl_write(ssl, buf, len);
|
|
|
+ /* DEBUG_TRACE("mbedtls_ssl_write: %d", rc); */
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void
|
|
|
-mbed_debug(void *context, int level, const char *file, int line, const char *str)
|
|
|
+mbed_debug(void *user_param,
|
|
|
+ int level,
|
|
|
+ const char *file,
|
|
|
+ int line,
|
|
|
+ const char *str)
|
|
|
{
|
|
|
- (void)level;
|
|
|
- mbedtls_fprintf((FILE *)context, "file:%s line:%d str:%s", file, line, 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 */
|