You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2018/01/04 12:15:42 UTC

svn commit: r1820075 - in /httpd/httpd/branches/2.4.x: CHANGES modules/ssl/ssl_engine_init.c modules/ssl/ssl_engine_kernel.c modules/ssl/ssl_private.h modules/ssl/ssl_util_ssl.c modules/ssl/ssl_util_ssl.h

Author: icing
Date: Thu Jan  4 12:15:42 2018
New Revision: 1820075

URL: http://svn.apache.org/viewvc?rev=1820075&view=rev
Log:
On the 2.4.x branch:

merge of 1804530,1804531,1805186,1806939,1807232,1808122 from trunk.

Backport of mod_md support in mod_ssl.


Modified:
    httpd/httpd/branches/2.4.x/CHANGES
    httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_init.c
    httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_kernel.c
    httpd/httpd/branches/2.4.x/modules/ssl/ssl_private.h
    httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.c
    httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.h

Modified: httpd/httpd/branches/2.4.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/CHANGES?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x/CHANGES [utf-8] Thu Jan  4 12:15:42 2018
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.30
  
+  *) mod_ssl: support for mod_md added. [Stefan Eissing]
+  
   *) mod_proxy_html: process parsed comments immediately. 
      Fixes bug (seen in the wild when used with IBM's HTTPD bundle)
      where parsed comments may be lost. [Nick Kew]

Modified: httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_init.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_init.c?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_init.c (original)
+++ httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_init.c Thu Jan  4 12:15:42 2018
@@ -31,6 +31,22 @@
 #include "mod_ssl_openssl.h"
 #include "mpm_common.h"
 
+/* Use the header, once mod_md is backported. break the dependency loop for now. */
+#define MOD_MD_BACKPORTED   0
+#if MOD_MD_BACKPORTED
+#include "mod_md.h"
+#else 
+APR_DECLARE_OPTIONAL_FN(int, 
+                        md_is_managed, (struct server_rec *));
+APR_DECLARE_OPTIONAL_FN(apr_status_t, 
+                        md_get_certificate, (struct server_rec *, apr_pool_t *,
+                                             const char **pkeyfile, 
+                                             const char **pcertfile));
+APR_DECLARE_OPTIONAL_FN(int, 
+                        md_is_challenge, (struct conn_rec *, const char *,
+                                          X509 **pcert, EVP_PKEY **pkey));
+#endif
+
 APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server,
                                     (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
                                     (s,p,is_proxy,ctx), OK, DECLINED)
@@ -164,6 +180,24 @@ static void ssl_add_version_components(a
                  modver, AP_SERVER_BASEVERSION, incver);
 }
 
+/**************************************************************************************************/
+/* Managed Domains Interface */
+
+static APR_OPTIONAL_FN_TYPE(md_is_managed) *md_is_managed;
+static APR_OPTIONAL_FN_TYPE(md_get_certificate) *md_get_certificate;
+static APR_OPTIONAL_FN_TYPE(md_is_challenge) *md_is_challenge;
+
+int ssl_is_challenge(conn_rec *c, const char *servername, 
+                     X509 **pcert, EVP_PKEY **pkey)
+{
+    if (md_is_challenge) {
+        return md_is_challenge(c, servername, pcert, pkey);
+    }
+    *pcert = NULL;
+    *pkey = NULL;
+    return 0;
+}
+
 /*
  *  Per-module initialization
  */
@@ -204,6 +238,16 @@ apr_status_t ssl_init_Module(apr_pool_t
     ssl_config_global_create(base_server); /* just to avoid problems */
     ssl_config_global_fix(mc);
 
+    /* Initialize our interface to mod_md, if it is loaded 
+     */
+    md_is_managed = APR_RETRIEVE_OPTIONAL_FN(md_is_managed);
+    md_get_certificate = APR_RETRIEVE_OPTIONAL_FN(md_get_certificate);
+    md_is_challenge = APR_RETRIEVE_OPTIONAL_FN(md_is_challenge);
+    if (!md_is_managed || !md_get_certificate) {
+        md_is_managed = NULL;
+        md_get_certificate = NULL;
+    }
+
     /*
      *  try to fix the configuration and open the dedicated SSL
      *  logfile as early as possible
@@ -1606,6 +1650,53 @@ static apr_status_t ssl_init_server_ctx(
         return APR_EGENERAL;
     }
 
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10083)
+                 "Init: (%s) mod_md support is %s.", ssl_util_vhostid(p, s),
+                 md_is_managed? "available" : "unavailable");
+    if (md_is_managed && md_is_managed(s)) {
+        modssl_pk_server_t *const pks = sc->server->pks;
+        if (pks->cert_files->nelts > 0 || pks->key_files->nelts > 0) {
+            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10084)
+                         "Init: (%s) You configured certificate/key files on this host, but "
+                         "is is covered by a Managed Domain. You need to remove these directives "
+                         "for the Managed Domain to take over.", ssl_util_vhostid(p, s));
+        }
+        else {
+            const char *key_file, *cert_file, *chain_file;
+            
+            key_file = cert_file = chain_file = NULL;
+            
+            if (md_get_certificate) {
+                /* mod_md >= v0.9.0 */
+                rv = md_get_certificate(s, p, &key_file, &cert_file);
+            }
+            else {
+                rv = APR_ENOTIMPL;
+            }
+            
+            if (key_file && cert_file) {
+                ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, 
+                             "%s: installing key=%s, cert=%s, chain=%s", 
+                             ssl_util_vhostid(p, s), key_file, cert_file, chain_file);
+                APR_ARRAY_PUSH(pks->key_files, const char *) = key_file;
+                APR_ARRAY_PUSH(pks->cert_files, const char *) = cert_file;
+                sc->server->cert_chain = chain_file;
+            }
+            
+            if (APR_STATUS_IS_EAGAIN(rv)) {
+                /* Managed Domain not ready yet. This is not a reason to fail the config */
+                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
+                             "Init: %s will respond with '503 Service Unavailable' for now. This "
+                             "host is part of a Managed Domain, but no SSL certificate is "
+                             "available (yet).", ssl_util_vhostid(p, s));
+                pks->service_unavailable = 1;
+            }
+            else if (rv != APR_SUCCESS) {
+                return rv;
+            }
+        }
+    }
+    
     if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) {
         return rv;
     }

Modified: httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_kernel.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_kernel.c?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_kernel.c (original)
+++ httpd/httpd/branches/2.4.x/modules/ssl/ssl_engine_kernel.c Thu Jan  4 12:15:42 2018
@@ -264,6 +264,15 @@ int ssl_hook_ReadReq(request_rec *r)
         return DECLINED;
     }
 
+    if (sslconn->service_unavailable) {
+        /* This is set when the SSL properties of this connection are
+         * incomplete or if this connection was made to challenge a 
+         * particular hostname (ACME). We never serve any request on 
+         * such a connection. */
+         /* TODO: a retry-after indicator would be nice here */
+        return HTTP_SERVICE_UNAVAILABLE;
+    }
+
     if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) {
         apr_table_setn(r->notes, "error-notes",
                        "Reason: You're speaking plain HTTP to an SSL-enabled "
@@ -2110,6 +2119,8 @@ void ssl_callback_Info(const SSL *ssl, i
 static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
 {
     const char *servername;
+    X509 *cert;
+    EVP_PKEY *key;
     
     if (c) {
         SSLConnRec *sslcon = myConnConfig(c);
@@ -2126,8 +2137,35 @@ static apr_status_t init_vhost(conn_rec
                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
                               "SSL virtual host for servername %s found",
                               servername);
+                
                 return APR_SUCCESS;
             }
+            else if (ssl_is_challenge(c, servername, &cert, &key)) {
+            
+                sslcon->service_unavailable = 1;
+                if ((SSL_use_certificate(ssl, cert) < 1)) {
+                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086)
+                                  "Failed to configure challenge certificate %s",
+                                  servername);
+                    return APR_EGENERAL;
+                }
+                
+                if (!SSL_use_PrivateKey(ssl, key)) {
+                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087)
+                                  "error '%s' using Challenge key: %s",
+                                  ERR_error_string(ERR_peek_last_error(), NULL), 
+                                  servername);
+                    return APR_EGENERAL;
+                }
+                
+                if (SSL_check_private_key(ssl) < 1) {
+                    ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088)
+                                  "Challenbge certificate and private key %s "
+                                  "do not match", servername);
+                    return APR_EGENERAL;
+                }
+                
+            }
             else {
                 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044)
                               "No matching SSL virtual host for servername "
@@ -2233,6 +2271,8 @@ static int ssl_find_vhost(void *serverna
          */
         sslcon->server = s;
         sslcon->cipher_suite = sc->server->auth.cipher_suite;
+        sslcon->service_unavailable = sc->server->pks? 
+            sc->server->pks->service_unavailable : 0; 
         
         ap_update_child_status_from_server(c->sbh, SERVER_BUSY_READ, c, s);
         /*

Modified: httpd/httpd/branches/2.4.x/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/ssl/ssl_private.h?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/branches/2.4.x/modules/ssl/ssl_private.h Thu Jan  4 12:15:42 2018
@@ -524,6 +524,7 @@ typedef struct {
     server_rec *server;
     
     const char *cipher_suite; /* cipher suite used in last reneg */
+    int service_unavailable;  /* thouugh we negotiate SSL, no requests will be served */
 } SSLConnRec;
 
 /* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
@@ -600,6 +601,9 @@ typedef struct {
      * sent in the CertificateRequest message: */
     const char  *ca_name_path;
     const char  *ca_name_file;
+    
+    /* TLS service for this server is suspended */
+    int service_unavailable;
 } modssl_pk_server_t;
 
 typedef struct {
@@ -1063,6 +1067,9 @@ void ssl_init_ocsp_certificates(server_r
  * memory. */
 DH *modssl_get_dh_params(unsigned keylen);
 
+int ssl_is_challenge(conn_rec *c, const char *servername, 
+                     X509 **pcert, EVP_PKEY **pkey);
+
 #endif /* SSL_PRIVATE_H */
 /** @} */
 

Modified: httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.c?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.c (original)
+++ httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.c Thu Jan  4 12:15:42 2018
@@ -115,6 +115,33 @@ EVP_PKEY *modssl_read_privatekey(const c
     return rc;
 }
 
+typedef struct {
+    const char *pass;
+    int pass_len;
+} pass_ctx;
+
+static int provide_pass(char *buf, int size, int rwflag, void *baton)
+{
+    pass_ctx *ctx = baton;
+    if (ctx->pass_len > 0) {
+        if (ctx->pass_len < size) {
+            size = (int)ctx->pass_len;
+        }
+        memcpy(buf, ctx->pass, size);
+    }
+    return ctx->pass_len;
+}
+
+EVP_PKEY   *modssl_read_encrypted_pkey(const char *filename, EVP_PKEY **key, 
+                                       const char *pass, apr_size_t pass_len)
+{
+    pass_ctx ctx;
+    
+    ctx.pass = pass;
+    ctx.pass_len = pass_len;
+    return modssl_read_privatekey(filename, key, provide_pass, &ctx);
+}
+
 /*  _________________________________________________________________
 **
 **  Smart shutdown

Modified: httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.h?rev=1820075&r1=1820074&r2=1820075&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.h (original)
+++ httpd/httpd/branches/2.4.x/modules/ssl/ssl_util_ssl.h Thu Jan  4 12:15:42 2018
@@ -65,6 +65,7 @@ void        modssl_init_app_data2_idx(vo
 void       *modssl_get_app_data2(SSL *);
 void        modssl_set_app_data2(SSL *, void *);
 EVP_PKEY   *modssl_read_privatekey(const char *, EVP_PKEY **, pem_password_cb *, void *);
+EVP_PKEY   *modssl_read_encrypted_pkey(const char *, EVP_PKEY **, const char *, apr_size_t);
 int         modssl_smart_shutdown(SSL *ssl);
 BOOL        modssl_X509_getBC(X509 *, int *, int *);
 char       *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne);