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/04 17:56:32 UTC

svn commit: r1830927 - in /httpd/httpd/trunk/modules/ssl: ssl_engine_pphrase.c ssl_private.h ssl_util.c

Author: jorton
Date: Fri May  4 17:56:32 2018
New Revision: 1830927

URL: http://svn.apache.org/viewvc?rev=1830927&view=rev
Log:
Simplify the ssl_asn1_table API, remove abstraction (it is used only
to cache serialized EVP_PKEYs not any char * blobs), and document.

* modules/ssl/ssl_util.c (ssl_asn1_table_set): Take the EVP_PKEY and
  serialize internally.  Use ap_realloc.  Return the ssl_asn1_t *
  pointer.  Don't call apr_hash_set() for unchanged pointer case.

* modules/ssl/ssl_engine_pphrase.c (ssl_load_encrypted_pkey):
  Adjust for the above.

* modules/ssl/ssl_private.h: Adjust as above, add docs.

Modified:
    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/modules/ssl/ssl_engine_pphrase.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c?rev=1830927&r1=1830926&r2=1830927&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_engine_pphrase.c Fri May  4 17:56:32 2018
@@ -137,8 +137,6 @@ apr_status_t ssl_load_encrypted_pkey(ser
     const char *key_id = asn1_table_vhost_key(mc, p, sc->vhost_id, idx);
     EVP_PKEY *pPrivateKey = NULL;
     ssl_asn1_t *asn1;
-    unsigned char *ucp;
-    long int length;
     int nPassPhrase = (*pphrases)->nelts;
     int nPassPhraseRetry = 0;
     apr_time_t pkey_mtime = 0;
@@ -345,19 +343,12 @@ apr_status_t ssl_load_encrypted_pkey(ser
         nPassPhrase++;
     }
 
-    /*
-     * Insert private key into the global module configuration
-     * (we convert it to a stand-alone DER byte sequence
-     * because the SSL library uses static variables inside a
-     * RSA structure which do not survive DSO reloads!)
-     */
-    length = i2d_PrivateKey(pPrivateKey, NULL);
-    ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length);
-    (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */
+    /* Cache the private key in the global module configuration so it
+     * can be used after subsequent reloads. */
+    asn1 = ssl_asn1_table_set(mc->tPrivateKey, key_id, pPrivateKey);
 
     if (ppcb_arg.nPassPhraseDialogCur != 0) {
         /* remember mtime of encrypted keys */
-        asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id);
         asn1->source_mtime = pkey_mtime;
     }
 

Modified: httpd/httpd/trunk/modules/ssl/ssl_private.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_private.h?rev=1830927&r1=1830926&r2=1830927&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_private.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_private.h Fri May  4 17:56:32 2018
@@ -1007,15 +1007,14 @@ DH           *ssl_dh_GetParamFromFile(co
 EC_GROUP     *ssl_ec_GetParamFromFile(const char *);
 #endif
 
-unsigned char *ssl_asn1_table_set(apr_hash_t *table,
-                                  const char *key,
-                                  long int length);
-
-ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
-                               const char *key);
-
-void ssl_asn1_table_unset(apr_hash_t *table,
-                          const char *key);
+/* Store the EVP_PKEY key (serialized into DER) in the hash table with
+ * key, returning the ssl_asn1_t structure pointer. */
+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
+                               EVP_PKEY *pkey);
+/* Retrieve the ssl_asn1_t structure with given key from the hash. */
+ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, const char *key);
+/* Remove and free the ssl_asn1_t structure with given key. */
+void ssl_asn1_table_unset(apr_hash_t *table, const char *key);
 
 /**  Mutex Support  */
 int          ssl_mutex_init(server_rec *, apr_pool_t *);

Modified: httpd/httpd/trunk/modules/ssl/ssl_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util.c?rev=1830927&r1=1830926&r2=1830927&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_util.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_util.c Fri May  4 17:56:32 2018
@@ -192,45 +192,37 @@ BOOL ssl_util_path_check(ssl_pathcheck_t
     return TRUE;
 }
 
-/*
- * certain key data needs to survive restarts,
- * which are stored in the user data table of s->process->pool.
- * to prevent "leaking" of this data, we use malloc/free
- * rather than apr_palloc and these wrappers to help make sure
- * we do not leak the malloc-ed data.
- */
-unsigned char *ssl_asn1_table_set(apr_hash_t *table,
-                                  const char *key,
-                                  long int length)
+/* Decrypted private keys are cached to survive restarts.  The cached
+ * data must have lifetime of the process (hence malloc/free rather
+ * than pools), and uses raw DER since the EVP_PKEY structure
+ * internals may not survive across a module reload. */
+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
+                               EVP_PKEY *pkey)
 {
     apr_ssize_t klen = strlen(key);
     ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
+    apr_size_t length = i2d_PrivateKey(pkey, NULL);
+    unsigned char *p;
 
-    /*
-     * if a value for this key already exists,
-     * reuse as much of the already malloc-ed data
-     * as possible.
-     */
+    /* Re-use structure if cached previously. */
     if (asn1) {
         if (asn1->nData != length) {
-            free(asn1->cpData); /* XXX: realloc? */
-            asn1->cpData = NULL;
+            asn1->cpData = ap_realloc(asn1->cpData, length);
         }
     }
     else {
         asn1 = ap_malloc(sizeof(*asn1));
         asn1->source_mtime = 0; /* used as a note for encrypted private keys */
-        asn1->cpData = NULL;
-    }
-
-    asn1->nData = length;
-    if (!asn1->cpData) {
         asn1->cpData = ap_malloc(length);
+
+        apr_hash_set(table, key, klen, asn1);
     }
 
-    apr_hash_set(table, key, klen, asn1);
+    asn1->nData = length;
+    p = asn1->cpData;
+    i2d_PrivateKey(pkey, &p); /* increases p by length */
 
-    return asn1->cpData; /* caller will assign a value to this */
+    return asn1;
 }
 
 ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,