Commit 91bed1b2 authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the trunk:

  *) mod_md: v0.9.1:
     - various fixes in MDRenewWindow handling when specifying percent. Serialization changed. If 
       someone already used percent configurations, it is advised to change these to a new value,
       reload and change back to the wanted ones.
     - various fixes in handling of MDPrivateKeys when specifying 2048 bits (the default) explicitly.
     - mod_md version removed from top level md_store.json file. The store has its own format version
       to facilitate upgrades.
 


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1807347 13f79535-47bb-0310-9956-ffa450edef68
parent 659d1ee7
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_md: v0.9.1:
     - various fixes in MDRenewWindow handling when specifying percent. Serialization changed. If 
       someone already used percent configurations, it is advised to change these to a new value,
       reload and change back to the wanted ones.
     - various fixes in handling of MDPrivateKeys when specifying 2048 bits (the default) explicitly.
     - mod_md version removed from top level md_store.json file. The store has its own format version
       to facilitate upgrades.
    [Stefan Eissing]

  *) mod_http2: DoS flow control protection is less agressive as long as active tasks stay
     below worker capacity. Intended to fix problems with media streaming. [Stefan Eissing]
     
+9 −2
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ struct md_srv_conf_t;
struct md_pkey_spec_t;

#define MD_TLSSNI01_DNS_SUFFIX     ".acme.invalid"
#define MD_PKEY_RSA_BITS_DEF       2048U

#define MD_PKEY_RSA_BITS_MIN       2048
#define MD_PKEY_RSA_BITS_DEF       2048

typedef enum {
    MD_S_UNKNOWN,                   /* MD has not been analysed yet */
@@ -121,7 +123,7 @@ struct md_t {
#define MD_KEY_PKEY             "privkey"
#define MD_KEY_PROTO            "proto"
#define MD_KEY_REGISTRATION     "registration"
#define MD_KEY_RENEW_NORM       "renew-norm"
#define MD_KEY_RENEW            "renew"
#define MD_KEY_RENEW_WINDOW     "renew-window"
#define MD_KEY_RESOURCE         "resource"
#define MD_KEY_STATE            "state"
@@ -237,6 +239,11 @@ md_t *md_merge(apr_pool_t *p, const md_t *add, const md_t *base);
struct md_json_t *md_to_json (const md_t *md, apr_pool_t *p);
md_t *md_from_json(struct md_json_t *json, apr_pool_t *p);

/**
 * Determine if MD should renew its cert (if it has one)
 */
int md_should_renew(const md_t *md);

/**************************************************************************************************/
/* domain credentials */

+41 −3
Original line number Diff line number Diff line
@@ -201,6 +201,33 @@ md_t *md_create(apr_pool_t *p, apr_array_header_t *domains)
    return md;
}

int md_should_renew(const md_t *md) 
{
    apr_time_t now = apr_time_now();

    if (md->expires <= now) {
        return 1;
    }
    else if (md->expires > 0) {
        apr_interval_time_t renew_win, left, life;
        
        renew_win = md->renew_window;
        if (md->renew_norm > 0 
            && md->renew_norm > renew_win
            && md->expires > md->valid_from) {
            /* Calc renewal days as fraction of cert lifetime - if known */
            life = md->expires - md->valid_from; 
            renew_win = (apr_time_t)(life * ((double)renew_win / md->renew_norm));
        }
        
        left = md->expires - now;
        if (left <= renew_win) {
            return 1;
        }                
    }
    return 0;
}

/**************************************************************************************************/
/* lifetime */

@@ -304,12 +331,13 @@ md_json_t *md_to_json(const md_t *md, apr_pool_t *p)
            md_json_sets(ts, json, MD_KEY_CERT, MD_KEY_VALID_FROM, NULL);
        }
        if (md->renew_norm > 0) {
            md_json_setl((long)apr_time_sec(md->renew_norm), json, MD_KEY_RENEW_NORM, NULL);
            md_json_setl((long)apr_time_sec(md->renew_window), json, MD_KEY_RENEW_WINDOW, NULL);
            md_json_sets(apr_psprintf(p, "%ld%%", (long)(md->renew_window * 100L / md->renew_norm)), 
                                      json, MD_KEY_RENEW_WINDOW, NULL);
        }
        else {
            md_json_setl((long)apr_time_sec(md->renew_window), json, MD_KEY_RENEW_WINDOW, NULL);
        }
        md_json_setb(md_should_renew(md), json, MD_KEY_RENEW, NULL);
        if (md->ca_challenges && md->ca_challenges->nelts > 0) {
            apr_array_header_t *na;
            na = md_array_str_compact(p, md->ca_challenges, 0);
@@ -348,8 +376,18 @@ md_t *md_from_json(md_json_t *json, apr_pool_t *p)
        if (s && *s) {
            md->valid_from = apr_date_parse_rfc(s);
        }
        md->renew_norm = apr_time_from_sec(md_json_getl(json, MD_KEY_RENEW_NORM, NULL));
        md->renew_norm = 0;
        md->renew_window = apr_time_from_sec(md_json_getl(json, MD_KEY_RENEW_WINDOW, NULL));
        if (md->renew_window <= 0) {
            const char *s = md_json_gets(json, MD_KEY_RENEW_WINDOW, NULL);
            if (s && strchr(s, '%')) {
                int percent = atoi(s);
                if (0 < percent && percent < 100) {
                    md->renew_norm = apr_time_from_sec(100 * MD_SECS_PER_DAY);
                    md->renew_window = apr_time_from_sec(percent * MD_SECS_PER_DAY);
                }
            }
        }
        if (md_json_has_key(json, MD_KEY_CA, MD_KEY_CHALLENGES, NULL)) {
            md->ca_challenges = apr_array_make(p, 5, sizeof(const char*));
            md_json_dupsa(md->ca_challenges, p, json, MD_KEY_CA, MD_KEY_CHALLENGES, NULL);
+25 −3
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ md_json_t *md_pkey_spec_to_json(const md_pkey_spec_t *spec, apr_pool_t *p)
                break;
            case MD_PKEY_TYPE_RSA:
                md_json_sets("RSA", json, MD_KEY_TYPE, NULL);
                if (spec->params.rsa.bits > 2048) {
                if (spec->params.rsa.bits >= MD_PKEY_RSA_BITS_MIN) {
                    md_json_setl(spec->params.rsa.bits, json, MD_KEY_BITS, NULL);
                }
                break;
@@ -217,14 +217,36 @@ md_pkey_spec_t *md_pkey_spec_from_json(struct md_json_t *json, apr_pool_t *p)
        else if (!apr_strnatcasecmp("RSA", s)) {
            spec->type = MD_PKEY_TYPE_RSA;
            l = md_json_getl(json, MD_KEY_BITS, NULL);
            if (l > 2048) {
            if (l >= MD_PKEY_RSA_BITS_MIN) {
                spec->params.rsa.bits = (unsigned int)l;
            }
            else {
                spec->params.rsa.bits = MD_PKEY_RSA_BITS_DEF;
            }
        }
    }
    return spec;
}

int md_pkey_spec_eq(md_pkey_spec_t *spec1, md_pkey_spec_t *spec2)
{
    if (spec1 == spec2) {
        return 1;
    }
    if (spec1 && spec2 && spec1->type == spec2->type) {
        switch (spec1->type) {
            case MD_PKEY_TYPE_DEFAULT:
                return 1;
            case MD_PKEY_TYPE_RSA:
                if (spec1->params.rsa.bits == spec2->params.rsa.bits) {
                    return 1;
                }
                break;
        }
    }
    return 0;
}

static md_pkey_t *make_pkey(apr_pool_t *p) 
{
    md_pkey_t *pkey = apr_pcalloc(p, sizeof(*pkey));
@@ -363,7 +385,7 @@ static apr_status_t gen_rsa(md_pkey_t **ppkey, apr_pool_t *p, unsigned int bits)
        rv = APR_SUCCESS;
    }
    else {
        md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, "unable to generate new key"); 
        md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, "error generate pkey RSA %d", bits); 
        *ppkey = NULL;
        rv = APR_EGENERAL;
    }
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ void *md_pkey_get_EVP_PKEY(struct md_pkey_t *pkey);

struct md_json_t *md_pkey_spec_to_json(const md_pkey_spec_t *spec, apr_pool_t *p);
md_pkey_spec_t *md_pkey_spec_from_json(struct md_json_t *json, apr_pool_t *p);
int md_pkey_spec_eq(md_pkey_spec_t *spec1, md_pkey_spec_t *spec2);

/**************************************************************************************************/
/* X509 certificates */
Loading