diff options
Diffstat (limited to 'src/tls.c')
| -rw-r--r-- | src/tls.c | 23 |
1 files changed, 20 insertions, 3 deletions
@@ -140,13 +140,24 @@ tls_host_init(struct gmnisrv_tls *tlsconf, struct gmnisrv_host *host) } X509 *x509 = PEM_read_X509(xf, NULL, NULL, NULL); - fclose(xf); if (!x509) { + fclose(xf); server_error("error loading certificate from %s", crtpath); fclose(kf); return 1; } + // Read any remaining certificates in the PEM file as the intermediate + // chain so CA-signed certs (e.g. Let's Encrypt fullchain.pem) are sent + // to the client for proper validation. + STACK_OF(X509) *chain = sk_X509_new_null(); + X509 *ca; + while ((ca = PEM_read_X509(xf, NULL, NULL, NULL)) != NULL) { + sk_X509_push(chain, ca); + } + ERR_clear_error(); + fclose(xf); + EVP_PKEY *pkey = PEM_read_PrivateKey(kf, NULL, NULL, NULL); fclose(kf); if (!pkey) { @@ -160,12 +171,15 @@ tls_host_init(struct gmnisrv_tls *tlsconf, struct gmnisrv_host *host) assert(r == 1); if (day < 0 || sec < 0) { server_log("%s certificate is expired", host->hostname); + sk_X509_pop_free(chain, X509_free); goto generate; } host->x509 = x509; host->pkey = pkey; - server_log("loaded certificate for %s", host->hostname); + host->chain = chain; + server_log("loaded certificate for %s (%d chain cert(s))", + host->hostname, sk_X509_num(chain)); return 0; generate: @@ -181,7 +195,7 @@ tls_init(struct gmnisrv_config *conf) conf->tls.ssl_ctx = SSL_CTX_new(TLS_server_method()); assert(conf->tls.ssl_ctx); - int r = SSL_CTX_set_min_proto_version(conf->tls.ssl_ctx, TLS1_2_VERSION); + int r = SSL_CTX_set_min_proto_version(conf->tls.ssl_ctx, TLS1_3_VERSION); assert(r == 1); r = SSL_CTX_set_cipher_list(conf->tls.ssl_ctx, @@ -238,4 +252,7 @@ tls_set_host(SSL *ssl, struct gmnisrv_host *host) { SSL_use_certificate(ssl, host->x509); SSL_use_PrivateKey(ssl, host->pkey); + if (host->chain && sk_X509_num(host->chain) > 0) { + SSL_set1_chain(ssl, host->chain); + } } |
