You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jo...@apache.org on 2018/05/03 13:06:46 UTC

svn commit: r1830819 - in /httpd/httpd/trunk: ./ docs/log-message-tags/ docs/manual/mod/ modules/ssl/

Author: jorton
Date: Thu May  3 13:06:46 2018
New Revision: 1830819

URL: http://svn.apache.org/viewvc?rev=1830819&view=rev
Log:
mod_ssl: Add support for loading private keys from ENGINEs.  Support
for PKCS#11 URIs only, and PIN entry is not threaded through
SSLPassPhraseDialog config yet.

* modules/ssl/ssl_util.c (modssl_is_engine_key): New function.

* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLCertificateKeyFile):
  Use it, skip check for file existence for engine keys.

* modules/ssl/ssl_engine_pphrase.c (modssl_load_engine_pkey):
  New function.

* modules/ssl/ssl_engine_init.c (ssl_init_server_certs):
  For engine keys, load via modssl_load_engine_pkey.

Submitted by: Anderson Sasaki <ansasaki redhat.com>, jorton

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/log-message-tags/next-number
    httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
    httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_init.c
    httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c
    httpd/httpd/trunk/modules/ssl/ssl_private.h
    httpd/httpd/trunk/modules/ssl/ssl_util.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu May  3 13:06:46 2018
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.1
 
+  *) mod_ssl: Support loading private keys from an OpenSSL engine using a
+     PKCS#11 URI.  [Anderson Sasaki <ansasaki redhat.com>, Joe Orton]
+
   *) mod_slomem_shm: Handle a generation number when the slotmem size changes,
      modifying the number of proxy balancers or balancer members on restart
      could have prevented the server to load, notably on Windows. PR 62308.

Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
+++ httpd/httpd/trunk/docs/log-message-tags/next-number Thu May  3 13:06:46 2018
@@ -1 +1 @@
-10130
+10134

Modified: httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml Thu May  3 13:06:46 2018
@@ -969,15 +969,17 @@ SSLCertificateFile "/usr/local/apache2/c
 <directivesynopsis>
 <name>SSLCertificateKeyFile</name>
 <description>Server PEM-encoded private key file</description>
-<syntax>SSLCertificateKeyFile <em>file-path</em></syntax>
+<syntax>SSLCertificateKeyFile <em>file-path</em>|<var>keyid</var></syntax>
 <contextlist><context>server config</context>
 <context>virtual host</context></contextlist>
+<compatibility><var>keyid</var> available in 2.5.1 and later.</compatibility>
 
 <usage>
 <p>
 This directive points to the PEM-encoded private key file for the
-server. If the contained private key is encrypted, the pass phrase
-dialog is forced at startup time.</p>
+server, or the key ID through a configured cryptographic token. If the
+contained private key is encrypted, the pass phrase dialog is forced
+at startup time.</p>
 
 <p>
 The directive can be used multiple times (referencing different filenames)
@@ -993,9 +995,21 @@ is highly discouraged. If it is used, th
 an embedded key must be configured after the certificates using a separate
 key file.</p>
 
+<p>As an alternative to storing private keys in files, a key
+identifier can be specified to identify a private key stored in a
+token.  Currently, only <a href="https://tools.ietf.org/html/rfc7512">PKCS#11 URIs</a> are recognized as private key
+identifiers, and can be used in conjunction with the OpenSSL
+<code>pkcs11</code> engine configured with <directive
+module="mod_ssl">SSLCryptoDevice</directive>.</p>
+
 <example><title>Example</title>
 <highlight language="config">
+# To use a private key from a PEM-encoded file:
 SSLCertificateKeyFile "/usr/local/apache2/conf/ssl.key/server.key"
+# To use a private key from a PKCS#11 token:
+SSLCryptoDevice pkcs11
+...
+SSLCertificateKeyFile "pkcs11:token=My%20Token%20Name;id=45"
 </highlight>
 </example>
 </usage>

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_config.c?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_config.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_config.c Thu May  3 13:06:46 2018
@@ -1032,7 +1032,9 @@ const char *ssl_cmd_SSLCertificateKeyFil
     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
     const char *err;
 
-    if ((err = ssl_cmd_check_file(cmd, &arg))) {
+    /* Check keyfile exists for non-ENGINE keys. */
+    if (!modssl_is_engine_key(arg)
+        && (err = ssl_cmd_check_file(cmd, &arg))) {
         return err;
     }
 

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_init.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_init.c?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_init.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_init.c Thu May  3 13:06:46 2018
@@ -1250,6 +1250,8 @@ static apr_status_t ssl_init_server_cert
                 (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i,
                                           const char *));
          i++) {
+        EVP_PKEY *pkey;
+
         key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
 
         ERR_clear_error();
@@ -1284,12 +1286,26 @@ static apr_status_t ssl_init_server_cert
 
         ERR_clear_error();
 
-        if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
-                                         SSL_FILETYPE_PEM) < 1) &&
-            (ERR_GET_FUNC(ERR_peek_last_error())
-                != X509_F_X509_CHECK_PRIVATE_KEY)) {
+        if (modssl_is_engine_key(keyfile)) {
+            apr_status_t rv;
+
+            if ((rv = modssl_load_engine_pkey(s, ptemp, keyfile, &pkey))) {
+                return rv;
+            }
+            
+            if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) {
+                ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130)
+                             "Failed to configure private key %s from engine",
+                             keyfile);
+                ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+                return APR_EGENERAL;
+            }
+        }
+        else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
+                                              SSL_FILETYPE_PEM) < 1)
+                 && (ERR_GET_FUNC(ERR_peek_last_error())
+                     != X509_F_X509_CHECK_PRIVATE_KEY)) {
             ssl_asn1_t *asn1;
-            EVP_PKEY *pkey;
             const unsigned char *ptr;
 
             ERR_clear_error();

Modified: httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c Thu May  3 13:06:46 2018
@@ -600,3 +600,52 @@ int ssl_pphrase_Handle_CB(char *buf, int
      */
     return (len);
 }
+
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
+apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
+                                     const char *keyid, EVP_PKEY **ppkey)
+{
+    SSLModConfigRec *mc = myModConfig(s);
+    EVP_PKEY *pPrivateKey = NULL;
+    ENGINE *e;
+    UI_METHOD *ui_method;
+
+    if (!mc->szCryptoDevice) {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131)
+                     "Init: Cannot load private key `%s' without engine",
+                     keyid);
+        return ssl_die(s);
+    }
+
+    /*
+     * Using the builtin OpenSSL UI only, for now...
+     */
+    ui_method = UI_OpenSSL();
+
+    if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132)
+                     "Init: Failed to load Crypto Device API `%s'",
+                     mc->szCryptoDevice);
+        ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+        return ssl_die(s);
+    }
+
+    if (APLOGdebug(s)) {
+        ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0);
+    }
+    
+    pPrivateKey = ENGINE_load_private_key(e, keyid, ui_method, NULL);
+    if (pPrivateKey == NULL) {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
+                     "Init: Unable to get the private key");
+        ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+        return ssl_die(s);
+    }
+
+    *ppkey = pPrivateKey;
+
+    ENGINE_free(e);
+
+    return APR_SUCCESS;
+}
+#endif

Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Thu May  3 13:06:46 2018
@@ -996,6 +996,10 @@ BOOL         ssl_util_vhost_matches(cons
 /**  Pass Phrase Support  */
 apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
                                      const char *, apr_array_header_t **);
+/* Load private key from the configured ENGINE, returned as **pkey.
+ * Errors logged on failure. */
+apr_status_t modssl_load_engine_pkey(server_rec *s, apr_pool_t *p,
+                                     const char *keyid, EVP_PKEY **ppkey);
 
 /**  Diffie-Hellman Parameter Support  */
 DH           *ssl_dh_GetParamFromFile(const char *);
@@ -1101,6 +1105,10 @@ DH *modssl_get_dh_params(unsigned keylen
  * corresponding SSLConnRec structure for the connection. */
 int modssl_request_is_tls(const request_rec *r, SSLConnRec **sslconn);
 
+/* Returns non-zero if the cert/key filename should be handled through
+ * the configure ENGINE. */
+int modssl_is_engine_key(const char *name);
+
 #if HAVE_VALGRIND
 extern int ssl_running_on_valgrind;
 #endif

Modified: httpd/httpd/trunk/modules/ssl/ssl_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util.c?rev=1830819&r1=1830818&r2=1830819&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_util.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_util.c Thu May  3 13:06:46 2018
@@ -522,3 +522,13 @@ void ssl_util_thread_setup(apr_pool_t *p
 }
 
 #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
+
+int modssl_is_engine_key(const char *name)
+{
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
+    /* ### Can handle any other special ENGINE key names here? */
+    return strncmp(name, "pkcs11:", 7) == 0;
+#else
+    return 0;
+#endif
+}



Re: svn commit: r1830819 - in /httpd/httpd/trunk: ./ docs/log-message-tags/ docs/manual/mod/ modules/ssl/

Posted by Joe Orton <jo...@redhat.com>.
On Thu, May 03, 2018 at 10:20:23PM +0200, Christophe Jaillet wrote:
> Le 03/05/2018 à 15:06, jorton@apache.org a écrit :
> 
> > -<syntax>SSLCertificateKeyFile <em>file-path</em></syntax>
> > +<syntax>SSLCertificateKeyFile <em>file-path</em>|<var>keyid</var></syntax>
> 
> Mixing <em> and <var> looks odd, even if the result is the same.
> Just my 2c.

Fixed in r1830879 :)

Re: svn commit: r1830819 - in /httpd/httpd/trunk: ./ docs/log-message-tags/ docs/manual/mod/ modules/ssl/

Posted by Christophe Jaillet <ch...@wanadoo.fr>.
Le 03/05/2018 à 15:06, jorton@apache.org a écrit :

> -<syntax>SSLCertificateKeyFile <em>file-path</em></syntax>
> +<syntax>SSLCertificateKeyFile <em>file-path</em>|<var>keyid</var></syntax>

Mixing <em> and <var> looks odd, even if the result is the same.
Just my 2c.

CJ