|
@@ -1737,6 +1737,7 @@ enum {
|
|
|
LISTENING_PORTS,
|
|
|
DOCUMENT_ROOT,
|
|
|
SSL_CERTIFICATE,
|
|
|
+ SSL_CERTIFICATE_CHAIN,
|
|
|
NUM_THREADS,
|
|
|
RUN_AS_USER,
|
|
|
REWRITE,
|
|
@@ -1825,6 +1826,7 @@ static struct mg_option config_options[] = {
|
|
|
{"listening_ports", CONFIG_TYPE_STRING, "8080"},
|
|
|
{"document_root", CONFIG_TYPE_DIRECTORY, NULL},
|
|
|
{"ssl_certificate", CONFIG_TYPE_FILE, NULL},
|
|
|
+ {"ssl_certificate_chain", CONFIG_TYPE_FILE, NULL},
|
|
|
{"num_threads", CONFIG_TYPE_NUMBER, "50"},
|
|
|
{"run_as_user", CONFIG_TYPE_STRING, NULL},
|
|
|
{"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
|
|
@@ -12227,7 +12229,8 @@ tls_dtor(void *key)
|
|
|
|
|
|
#if !defined(NO_SSL)
|
|
|
|
|
|
-static int ssl_use_pem_file(struct mg_context *ctx, const char *pem);
|
|
|
+static int
|
|
|
+ssl_use_pem_file(struct mg_context *ctx, const char *pem, const char *chain);
|
|
|
static const char *ssl_error(void);
|
|
|
|
|
|
|
|
@@ -12240,7 +12243,8 @@ refresh_trust(struct mg_connection *conn)
|
|
|
|
|
|
struct stat cert_buf;
|
|
|
long int t;
|
|
|
- char *pem;
|
|
|
+ const char *pem;
|
|
|
+ const char *chain;
|
|
|
int should_verify_peer;
|
|
|
|
|
|
if ((pem = conn->ctx->config[SSL_CERTIFICATE]) == NULL) {
|
|
@@ -12248,6 +12252,13 @@ refresh_trust(struct mg_connection *conn)
|
|
|
* refresh_trust still can not work. */
|
|
|
return 0;
|
|
|
}
|
|
|
+ chain = conn->ctx->config[SSL_CERTIFICATE_CHAIN];
|
|
|
+ if (chain == NULL) {
|
|
|
+ chain = pem;
|
|
|
+ }
|
|
|
+ if (*chain == 0) {
|
|
|
+ chain = NULL;
|
|
|
+ }
|
|
|
|
|
|
t = data_check;
|
|
|
if (stat(pem, &cert_buf) != -1) {
|
|
@@ -12280,7 +12291,7 @@ refresh_trust(struct mg_connection *conn)
|
|
|
}
|
|
|
|
|
|
if (1 == mg_atomic_inc(p_reload_lock)) {
|
|
|
- if (ssl_use_pem_file(conn->ctx, pem) == 0) {
|
|
|
+ if (ssl_use_pem_file(conn->ctx, pem, chain) == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
*p_reload_lock = 0;
|
|
@@ -12691,7 +12702,7 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
|
|
|
|
|
|
|
|
|
static int
|
|
|
-ssl_use_pem_file(struct mg_context *ctx, const char *pem)
|
|
|
+ssl_use_pem_file(struct mg_context *ctx, const char *pem, const char *chain)
|
|
|
{
|
|
|
if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, 1) == 0) {
|
|
|
mg_cry(fc(ctx),
|
|
@@ -12720,13 +12731,23 @@ ssl_use_pem_file(struct mg_context *ctx, const char *pem)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem) == 0) {
|
|
|
- mg_cry(fc(ctx),
|
|
|
- "%s: cannot use certificate chain file %s: %s",
|
|
|
- __func__,
|
|
|
- pem,
|
|
|
- ssl_error());
|
|
|
- return 0;
|
|
|
+ /* In contrast to OpenSSL, wolfSSL does not support certificate
|
|
|
+ * chain files that contain private keys and certificates in
|
|
|
+ * SSL_CTX_use_certificate_chain_file.
|
|
|
+ * The CivetWeb-Server used pem-Files that contained both information.
|
|
|
+ * In order to make wolfSSL work, it is split in two files.
|
|
|
+ * One file that contains key and certificate used by the server and
|
|
|
+ * an optional chain file for the ssl stack.
|
|
|
+ */
|
|
|
+ if (chain) {
|
|
|
+ if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, chain) == 0) {
|
|
|
+ mg_cry(fc(ctx),
|
|
|
+ "%s: cannot use certificate chain file %s: %s",
|
|
|
+ __func__,
|
|
|
+ pem,
|
|
|
+ ssl_error());
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|
|
|
return 1;
|
|
|
}
|
|
@@ -12770,6 +12791,7 @@ static int
|
|
|
set_ssl_option(struct mg_context *ctx)
|
|
|
{
|
|
|
const char *pem;
|
|
|
+ const char *chain;
|
|
|
int callback_ret;
|
|
|
int should_verify_peer;
|
|
|
const char *ca_path;
|
|
@@ -12792,6 +12814,13 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
&& ctx->callbacks.init_ssl == NULL) {
|
|
|
return 1;
|
|
|
}
|
|
|
+ chain = ctx->config[SSL_CERTIFICATE_CHAIN];
|
|
|
+ if (chain == NULL) {
|
|
|
+ chain = pem;
|
|
|
+ }
|
|
|
+ if (*chain == 0) {
|
|
|
+ chain = NULL;
|
|
|
+ }
|
|
|
|
|
|
if (!initialize_ssl(ebuf, sizeof(ebuf))) {
|
|
|
mg_cry(fc(ctx), "%s", ebuf);
|
|
@@ -12877,7 +12906,7 @@ set_ssl_option(struct mg_context *ctx)
|
|
|
sizeof(ssl_context_id));
|
|
|
|
|
|
if (pem != NULL) {
|
|
|
- if (!ssl_use_pem_file(ctx, pem)) {
|
|
|
+ if (!ssl_use_pem_file(ctx, pem, chain)) {
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
@@ -13387,7 +13416,9 @@ mg_connect_client_impl(const struct mg_client_options *client_options,
|
|
|
* SSL_VERIFY_PEER, verify_ssl_server); */
|
|
|
|
|
|
if (client_options->client_cert) {
|
|
|
- if (!ssl_use_pem_file(&fake_ctx, client_options->client_cert)) {
|
|
|
+ if (!ssl_use_pem_file(&fake_ctx,
|
|
|
+ client_options->client_cert,
|
|
|
+ NULL)) {
|
|
|
mg_snprintf(NULL,
|
|
|
NULL, /* No truncation check for ebuf */
|
|
|
ebuf,
|