Commit 98051986 authored by Doug MacEachern's avatar Doug MacEachern
Browse files

reuse vhost keys for asn1 tables where keys are allocated out

of s->process->pool to prevent "leaking" each time we format
a vhost key.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/ssl@93616 13f79535-47bb-0310-9956-ffa450edef68
parent 5681beab
Loading
Loading
Loading
Loading
+1 −0
Changes for mod_ssl.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -516,6 +516,7 @@ typedef struct {
    apr_lock_t     *pMutex;
    apr_array_header_t   *aRandSeed;
    int             nScoreboardSize; /* used for builtin random seed */
    apr_hash_t     *tVHostKeys;
    apr_hash_t     *tTmpKeys;
    void           *pTmpKeys[SSL_TKPIDX_MAX];
    apr_hash_t     *tPublicCert;
+1 −0
Changes for ssl_engine_config.c: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
        mc->szMutexFile            = NULL;
        mc->pMutex                 = NULL;
        mc->aRandSeed              = apr_array_make(pPool, 4, sizeof(ssl_randseed_t));
        mc->tVHostKeys             = apr_hash_make(pPool);
        mc->tPrivateKey            = apr_hash_make(pPool);
        mc->tPublicCert            = apr_hash_make(pPool);
        mc->tTmpKeys               = apr_hash_make(pPool);
+36 −2
Changes for ssl_engine_pphrase.c: 36 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -90,6 +90,40 @@ static apr_status_t exists_and_readable(char *fname, apr_pool_t *pool, apr_time_
    return APR_SUCCESS;
}

/*
 * reuse vhost keys for asn1 tables where keys are allocated out
 * of s->process->pool to prevent "leaking" each time we format
 * a vhost key.  since the key is stored in a table with lifetime
 * of s->process->pool, the key needs to have the same lifetime.
 *
 * XXX: probably seems silly to use a hash table with keys and values
 * being the same, but it is easier than doing a linear search
 * and will make it easier to remove keys if needed in the future.
 * also have the problem with apr_array_header_t that if we
 * underestimate the number of vhost keys when we apr_array_make(),
 * the array will get resized when we push past the initial number
 * of elts.  this resizing in the s->process->pool means "leaking"
 * since apr_array_push() will apr_alloc arr->nalloc * 2 elts,
 * leaving the original arr->elts to waste.
 */
static char *asn1_table_vhost_key(SSLModConfigRec *mc, apr_pool_t *p,
                                  char *id, char *an)
{
    /* 'p' pool used here is cleared on restarts */
    char *key = apr_psprintf(p, "%s:%s", id, an);
    void *keyptr = apr_hash_get(mc->tVHostKeys, key,
                                APR_HASH_KEY_STRING);

    if (!keyptr) {
        /* make a copy out of s->process->pool */
        keyptr = apr_pstrdup(mc->pPool, key);
        apr_hash_set(mc->tVHostKeys, keyptr,
                     APR_HASH_KEY_STRING, keyptr);
    }

    return (char *)keyptr;
}

/*  _________________________________________________________________
**
**  Pass Phrase and Private Key Handling
@@ -199,7 +233,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
             * certificate is actually used to configure mod_ssl's per-server
             * configuration structures).
             */
            cp = apr_psprintf(mc->pPool, "%s:%s", cpVHostID, an);
            cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
            length = i2d_X509(pX509Cert, NULL);
            ucp = ssl_asn1_table_set(mc->tPublicCert, cp, length);
            (void)i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */
@@ -426,7 +460,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
             * because the SSL library uses static variables inside a
             * RSA structure which do not survive DSO reloads!)
             */
            cp = apr_psprintf(mc->pPool, "%s:%s", cpVHostID, an);
            cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
            length = i2d_PrivateKey(pPrivateKey, NULL);
            ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length);
            (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */