--- modules/ssl/ssl_engine_pphrase.c.ssldupkeys 2009-10-12 21:02:15.541223641 +0100 +++ modules/ssl/ssl_engine_pphrase.c 2011-02-11 13:09:02.339051917 +0000 @@ -132,6 +132,13 @@ arr->nelts = 0; } +/* Abandon all hope, ye who read this code. Don't believe the name: + * "passphrase handling" is really a peripheral (if complex) concern; + * the core purpose of this function to load into memory all + * configured certs and key from files. The private key handling in + * here should be split out into a separate function for improved + * readability. The myCtxVarGet abomination can be thrown away with + * SSLC support, vastly simplifying the code. */ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) { SSLModConfigRec *mc = myModConfig(s); @@ -157,7 +164,6 @@ int i, j; ssl_algo_t algoCert, algoKey, at; char *an; - char *cp; apr_time_t pkey_mtime = 0; int isterm = 1; apr_status_t rv; @@ -179,7 +185,8 @@ cpVHostID = ssl_util_vhostid(p, pServ); ap_log_error(APLOG_MARK, APLOG_INFO, 0, pServ, - "Loading certificate & private key of SSL-aware server"); + "Loading certificate & private key of SSL-aware server '%s'", + cpVHostID); /* * Read in server certificate(s): This is the easy part @@ -192,9 +199,17 @@ pServ->defn_name, pServ->defn_line_number); ssl_die(); } + + /* Bitmasks for all key algorithms configured for this server; + * initialize to zero. */ algoCert = SSL_ALGO_UNKNOWN; algoKey = SSL_ALGO_UNKNOWN; + + /* Iterate through configured certificate files for this + * cert. */ for (i = 0, j = 0; i < SSL_AIDX_MAX && sc->server->pks->cert_files[i] != NULL; i++) { + const char *key_id; + int using_cache = 0; apr_cpystrn(szPath, sc->server->pks->cert_files[i], sizeof(szPath)); if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) { @@ -225,6 +240,11 @@ } algoCert |= at; + /* Determine the hash key used for this (vhost, algo-type) + * pair used to index both the mc->tPrivateKey and + * mc->tPublicCert tables: */ + key_id = asn1_table_vhost_key(mc, p, cpVHostID, an); + /* * Insert the certificate into global module configuration to let it * survive the processing between the 1st Apache API init round (where @@ -232,9 +252,8 @@ * certificate is actually used to configure mod_ssl's per-server * configuration structures). */ - cp = asn1_table_vhost_key(mc, p, cpVHostID, an); length = i2d_X509(pX509Cert, NULL); - ucp = ssl_asn1_table_set(mc->tPublicCert, cp, length); + ucp = ssl_asn1_table_set(mc->tPublicCert, key_id, length); (void)i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */ /* @@ -320,22 +339,17 @@ * are used to give a better idea as to what failed. */ if (pkey_mtime) { - int i; - - for (i=0; i < SSL_AIDX_MAX; i++) { - const char *key_id = - ssl_asn1_table_keyfmt(p, cpVHostID, i); - ssl_asn1_t *asn1 = - ssl_asn1_table_get(mc->tPrivateKey, key_id); - - if (asn1 && (asn1->source_mtime == pkey_mtime)) { - ap_log_error(APLOG_MARK, APLOG_INFO, - 0, pServ, - "%s reusing existing " - "%s private key on restart", - cpVHostID, ssl_asn1_keystr(i)); - return; - } + ssl_asn1_t *asn1 = + ssl_asn1_table_get(mc->tPrivateKey, key_id); + + if (asn1 && (asn1->source_mtime == pkey_mtime)) { + ap_log_error(APLOG_MARK, APLOG_INFO, + 0, pServ, + "%s reusing existing " + "%s private key on restart", + cpVHostID, ssl_asn1_keystr(i)); + using_cache = 1; + break; } } @@ -439,6 +453,12 @@ ssl_die(); } + /* If a cached private key was found, nothing more to do + * here; loop through to the next configured cert for this + * vhost. */ + if (using_cache) + continue; + if (pPrivateKey == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Init: Unable to read server private key from " @@ -501,14 +521,13 @@ * because the SSL library uses static variables inside a * RSA structure which do not survive DSO reloads!) */ - cp = asn1_table_vhost_key(mc, p, cpVHostID, an); length = i2d_PrivateKey(pPrivateKey, NULL); - ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length); + ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length); (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ if (nPassPhraseDialogCur != 0) { /* remember mtime of encrypted keys */ - asn1 = ssl_asn1_table_get(mc->tPrivateKey, cp); + asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id); asn1->source_mtime = pkey_mtime; }