mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
240 lines
6.2 KiB
Plaintext
240 lines
6.2 KiB
Plaintext
|
#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,
|
||
|
struct mg_context *phys_ctx);
|
||
|
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("%s", "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) || 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);
|
||
|
|
||
|
rc = mbedtls_ctr_drbg_seed(&ctx->ctr,
|
||
|
mbedtls_entropy_func,
|
||
|
&ctx->entropy,
|
||
|
(unsigned char *)"CivetWeb",
|
||
|
strlen("CivetWeb"));
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS random seed failed (%i)", rc);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
rc = mbedtls_pk_parse_keyfile(&ctx->pkey, crt, NULL);
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS parse key file failed (%i)", rc);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
rc = mbedtls_x509_crt_parse_file(&ctx->cert, crt);
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS parse crt file failed (%i)", rc);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
rc = mbedtls_ssl_config_defaults(conf,
|
||
|
MBEDTLS_SSL_IS_SERVER,
|
||
|
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||
|
MBEDTLS_SSL_PRESET_DEFAULT);
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS set defaults failed (%i)", rc);
|
||
|
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 */
|
||
|
rc = mbedtls_ssl_conf_own_cert(conf, &ctx->cert, &ctx->pkey);
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS cannot set certificate and private key (%i)", rc);
|
||
|
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,
|
||
|
struct mg_context *phys_ctx)
|
||
|
{
|
||
|
int rc;
|
||
|
(void)phys_ctx; /* unused, if server statistics is not turned on */
|
||
|
|
||
|
DEBUG_TRACE("TLS accept processing %p", ssl);
|
||
|
|
||
|
*ssl = (mbedtls_ssl_context *)mg_calloc_ctx(1,
|
||
|
sizeof(mbedtls_ssl_context),
|
||
|
phys_ctx);
|
||
|
if (*ssl == NULL) {
|
||
|
DEBUG_TRACE("TLS accept: malloc ssl failed (%i)",
|
||
|
(int)sizeof(mbedtls_ssl_context));
|
||
|
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);
|
||
|
rc = mbed_ssl_handshake(*ssl);
|
||
|
if (rc != 0) {
|
||
|
DEBUG_TRACE("TLS handshake failed (%i)", rc);
|
||
|
mbedtls_ssl_free(*ssl);
|
||
|
mg_free(*ssl);
|
||
|
*ssl = NULL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
DEBUG_TRACE("TLS connection %p accepted, state: %d", ssl, (*ssl)->state);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
mbed_ssl_close(mbedtls_ssl_context *ssl)
|
||
|
{
|
||
|
DEBUG_TRACE("TLS connection %p closed", ssl);
|
||
|
mbedtls_ssl_close_notify(ssl);
|
||
|
mbedtls_ssl_free(ssl);
|
||
|
mg_free(ssl); /* mg_free for mg_calloc in mbed_ssl_accept */
|
||
|
}
|
||
|
|
||
|
|
||
|
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 */
|