You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2021/07/12 07:52:28 UTC

svn commit: r1891470 - in /httpd/httpd/trunk: changes-entries/ modules/md/

Author: icing
Date: Mon Jul 12 07:52:28 2021
New Revision: 1891470

URL: http://svn.apache.org/viewvc?rev=1891470&view=rev
Log:
  *) mod_md: fixed a potential null pointer dereference if ACME/OCSP
     server returned 2xx responses without content type. Reported by chuangwen.


Added:
    httpd/httpd/trunk/changes-entries/md_fix_potential_nullpointer.txt
Modified:
    httpd/httpd/trunk/modules/md/md_acme.c
    httpd/httpd/trunk/modules/md/md_acme_authz.c
    httpd/httpd/trunk/modules/md/md_crypt.c
    httpd/httpd/trunk/modules/md/md_crypt.h
    httpd/httpd/trunk/modules/md/md_curl.c
    httpd/httpd/trunk/modules/md/md_json.c
    httpd/httpd/trunk/modules/md/md_jws.c
    httpd/httpd/trunk/modules/md/md_ocsp.c
    httpd/httpd/trunk/modules/md/md_store_fs.c
    httpd/httpd/trunk/modules/md/md_util.c
    httpd/httpd/trunk/modules/md/md_util.h
    httpd/httpd/trunk/modules/md/md_version.h
    httpd/httpd/trunk/modules/md/mod_md.c
    httpd/httpd/trunk/modules/md/mod_md.h
    httpd/httpd/trunk/modules/md/mod_md_ocsp.c
    httpd/httpd/trunk/modules/md/mod_md_ocsp.h

Added: httpd/httpd/trunk/changes-entries/md_fix_potential_nullpointer.txt
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/changes-entries/md_fix_potential_nullpointer.txt?rev=1891470&view=auto
==============================================================================
--- httpd/httpd/trunk/changes-entries/md_fix_potential_nullpointer.txt (added)
+++ httpd/httpd/trunk/changes-entries/md_fix_potential_nullpointer.txt Mon Jul 12 07:52:28 2021
@@ -0,0 +1,3 @@
+  *) mod_md: fixed a potential null pointer dereference if ACME/OCSP
+     server returned 2xx responses without content type. Reported by chuangwen.
+     [chuangwen, Stefan Eissing]

Modified: httpd/httpd/trunk/modules/md/md_acme.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_acme.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_acme.c (original)
+++ httpd/httpd/trunk/modules/md/md_acme.c Mon Jul 12 07:52:28 2021
@@ -227,7 +227,8 @@ static apr_status_t inspect_problem(md_a
 static apr_status_t acmev2_req_init(md_acme_req_t *req, md_json_t *jpayload)
 {
     md_data_t payload;
-    
+
+    md_data_null(&payload);
     if (!req->acme->acct) {
         return APR_EINVAL;
     }

Modified: httpd/httpd/trunk/modules/md/md_acme_authz.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_acme_authz.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_acme_authz.c (original)
+++ httpd/httpd/trunk/modules/md/md_acme_authz.c Mon Jul 12 07:52:28 2021
@@ -321,7 +321,7 @@ static apr_status_t cha_tls_alpn_01_setu
      * The server will need to answer a TLS connection with SNI == authz->domain
      * and ALPN procotol "acme-tls/1" with this certificate.
      */
-    MD_DATA_SET_STR(&data, cha->key_authz);
+    md_data_init_str(&data, cha->key_authz);
     rv = md_crypt_sha256_digest_hex(&token, p, &data);
     if (APR_SUCCESS != rv) {
         md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create tls-alpn-01 validation token",
@@ -420,7 +420,7 @@ static apr_status_t cha_dns_01_setup(md_
         goto out;
     }
     
-    MD_DATA_SET_STR(&data, cha->key_authz);
+    md_data_init_str(&data, cha->key_authz);
     rv = md_crypt_sha256_digest64(&token, p, &data);
     if (APR_SUCCESS != rv) {
         md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: create dns-01 token for %s",

Modified: httpd/httpd/trunk/modules/md/md_crypt.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_crypt.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_crypt.c (original)
+++ httpd/httpd/trunk/modules/md/md_crypt.c Mon Jul 12 07:52:28 2021
@@ -677,6 +677,7 @@ static apr_status_t pkey_to_buffer(md_da
         return APR_EINVAL;
     }
 
+    md_data_null(buf);
     i = BIO_pending(bio);
     if (i > 0) {
         buf->data = apr_palloc(p, (apr_size_t)i);
@@ -904,8 +905,7 @@ static const char *bn64(const BIGNUM *b,
     if (b) {
         md_data_t buffer;
 
-        buffer.len = (apr_size_t)BN_num_bytes(b);
-        buffer.data = apr_pcalloc(p, buffer.len);
+        md_data_pinit(&buffer, (apr_size_t)BN_num_bytes(b), p);
         if (buffer.data) {
             BN_bn2bin(b, (unsigned char *)buffer.data);
             return md_util_base64url_encode(&buffer, p);
@@ -946,9 +946,8 @@ apr_status_t md_crypt_sign64(const char
     unsigned int blen;
     const char *sign64 = NULL;
     apr_status_t rv = APR_ENOMEM;
-    
-    buffer.len = (apr_size_t)EVP_PKEY_size(pkey->pkey);
-    buffer.data = apr_pcalloc(p, buffer.len);
+
+    md_data_pinit(&buffer, (apr_size_t)EVP_PKEY_size(pkey->pkey), p);
     if (buffer.data) {
         ctx = EVP_MD_CTX_create();
         if (ctx) {
@@ -987,11 +986,9 @@ static apr_status_t sha256_digest(md_dat
     apr_status_t rv = APR_ENOMEM;
     unsigned int dlen;
 
-    digest = apr_palloc(p, sizeof(*digest));
+    digest = md_data_pmake(EVP_MAX_MD_SIZE, p);
     if (!digest) goto leave;
-    digest->data = apr_pcalloc(p, EVP_MAX_MD_SIZE);
-    if (!digest->data) goto leave;
-    
+
     ctx = EVP_MD_CTX_create();
     if (ctx) {
         rv = APR_ENOTIMPL;
@@ -1303,7 +1300,8 @@ apr_status_t md_cert_fsave(md_cert_t *ce
 {
     md_data_t buffer;
     apr_status_t rv;
-    
+
+    md_data_null(&buffer);
     if (APR_SUCCESS == (rv = cert_to_buffer(&buffer, cert, p))) {
         return md_util_freplace(fname, perms, p, fwrite_buffer, &buffer); 
     }
@@ -1314,7 +1312,8 @@ apr_status_t md_cert_to_base64url(const
 {
     md_data_t buffer;
     apr_status_t rv;
-    
+
+    md_data_null(&buffer);
     if (APR_SUCCESS == (rv = cert_to_buffer(&buffer, cert, p))) {
         *ps64 = md_util_base64url_encode(&buffer, p);
         return APR_SUCCESS;
@@ -1328,11 +1327,9 @@ apr_status_t md_cert_to_sha256_digest(md
     md_data_t *digest;
     unsigned int dlen;
     apr_status_t rv = APR_ENOMEM;
-    
-    digest = apr_palloc(p, sizeof(*digest));
+
+    digest = md_data_pmake(EVP_MAX_MD_SIZE, p);
     if (!digest) goto leave;
-    digest->data = apr_pcalloc(p, EVP_MAX_MD_SIZE);
-    if (!digest->data) goto leave;
 
     X509_digest(cert->x509, EVP_sha256(), (unsigned char*)digest->data, &dlen);
     digest->len = dlen;
@@ -1346,7 +1343,7 @@ apr_status_t md_cert_to_sha256_fingerpri
 {
     md_data_t *digest;
     apr_status_t rv;
-    
+
     rv = md_cert_to_sha256_digest(&digest, cert, p);
     if (APR_SUCCESS == rv) {
         return md_data_to_hex(pfinger, 0, p, digest);
@@ -1679,7 +1676,8 @@ apr_status_t md_cert_req_create(const ch
     int csr_der_len;
     
     assert(domains->nelts > 0);
-    
+    md_data_null(&csr_der);
+
     if (NULL == (csr = X509_REQ_new()) 
         || NULL == (exts = sk_X509_EXTENSION_new_null())
         || NULL == (n = X509_NAME_new())) {
@@ -1975,10 +1973,10 @@ apr_status_t md_cert_get_ct_scts(apr_arr
                     sct->version = SCT_get_version(sct_handle);
                     sct->timestamp = apr_time_from_msec(SCT_get_timestamp(sct_handle));
                     len = SCT_get0_log_id(sct_handle, (unsigned char**)&data);
-                    sct->logid = md_data_create(p, data, len);
+                    sct->logid = md_data_make_pcopy(p, data, len);
                     sct->signature_type_nid = SCT_get_signature_nid(sct_handle);
                     len = SCT_get0_signature(sct_handle,  (unsigned char**)&data);
-                    sct->signature = md_data_create(p, data, len);
+                    sct->signature = md_data_make_pcopy(p, data, len);
                     
                     APR_ARRAY_PUSH(scts, md_sct*) = sct;
                 }
@@ -1995,3 +1993,24 @@ apr_status_t md_cert_get_ct_scts(apr_arr
     return APR_ENOTIMPL;
 #endif
 }
+
+apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert)
+{
+    STACK_OF(OPENSSL_STRING) *ssk;
+    apr_status_t rv = APR_SUCCESS;
+    const char *url = NULL;
+
+    ssk = X509_get1_ocsp(md_cert_get_X509(cert));
+    if (!ssk) {
+        rv = APR_ENOENT;
+        goto cleanup;
+    }
+    url = apr_pstrdup(p, sk_OPENSSL_STRING_value(ssk, 0));
+    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, p, "ocsp responder found '%s'", url);
+
+cleanup:
+    if (ssk) X509_email_free(ssk);
+    *purl = url;
+    return rv;
+}
+

Modified: httpd/httpd/trunk/modules/md/md_crypt.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_crypt.h?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_crypt.h (original)
+++ httpd/httpd/trunk/modules/md/md_crypt.h Mon Jul 12 07:52:28 2021
@@ -41,8 +41,6 @@ apr_status_t md_crypt_sha256_digest64(co
 apr_status_t md_crypt_sha256_digest_hex(const char **pdigesthex, apr_pool_t *p, 
                                         const struct md_data_t *data);
 
-#define MD_DATA_SET_STR(d, s)       do { (d)->data = (s); (d)->len = strlen(s); } while(0)
-
 /**************************************************************************************************/
 /* private keys */
 
@@ -218,6 +216,8 @@ apr_status_t md_cert_make_tls_alpn_01(md
 
 apr_status_t md_cert_get_ct_scts(apr_array_header_t *scts, apr_pool_t *p, const md_cert_t *cert);
 
+apr_status_t md_cert_get_ocsp_responder_url(const char **purl, apr_pool_t *p, const md_cert_t *cert);
+
 /**************************************************************************************************/
 /* X509 certificate transparency */
 

Modified: httpd/httpd/trunk/modules/md/md_curl.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_curl.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_curl.c (original)
+++ httpd/httpd/trunk/modules/md/md_curl.c Mon Jul 12 07:52:28 2021
@@ -213,8 +213,7 @@ static int curl_debug_log(CURL *curl, cu
             if (md_log_is_level(req->pool, MD_LOG_TRACE5)) {
                 md_data_t d;
                 const char *s;
-                d.data = data;
-                d.len = size;
+                md_data_init(&d, data, size);
                 md_data_to_hex(&s, 0, req->pool, &d);
                 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE5, 0, req->pool, 
                               "req[%d]: data(hex) -->  %s", req->id, s);
@@ -226,8 +225,7 @@ static int curl_debug_log(CURL *curl, cu
             if (md_log_is_level(req->pool, MD_LOG_TRACE5)) {
                 md_data_t d;
                 const char *s;
-                d.data = data;
-                d.len = size;
+                md_data_init(&d, data, size);
                 md_data_to_hex(&s, 0, req->pool, &d);
                 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE5, 0, req->pool, 
                               "req[%d]: data(hex) <-- %s", req->id, s);

Modified: httpd/httpd/trunk/modules/md/md_json.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_json.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_json.c (original)
+++ httpd/httpd/trunk/modules/md/md_json.c Mon Jul 12 07:52:28 2021
@@ -1185,15 +1185,18 @@ apr_status_t md_json_readf(md_json_t **p
 apr_status_t md_json_read_http(md_json_t **pjson, apr_pool_t *pool, const md_http_response_t *res)
 {
     apr_status_t rv = APR_ENOENT;
-    const char *ctype = apr_table_get(res->headers, "content-type"), *p;
+    const char *ctype, *p;
 
     *pjson = NULL;
-    ctype = md_util_parse_ct(res->req->pool, ctype);
+    if (!res->body) goto cleanup;
+    ctype = md_util_parse_ct(res->req->pool, apr_table_get(res->headers, "content-type"));
+    if (!ctype) goto cleanup;
     p = ctype + strlen(ctype) +1;
-    if (ctype && res->body && (!strcmp(p - sizeof("/json"), "/json") ||
-                               !strcmp(p - sizeof("+json"), "+json"))) {
+    if (!strcmp(p - sizeof("/json"), "/json")
+        || !strcmp(p - sizeof("+json"), "+json")) {
         rv = md_json_readb(pjson, pool, res->body);
     }
+cleanup:
     return rv;
 }
 

Modified: httpd/httpd/trunk/modules/md/md_jws.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_jws.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_jws.c (original)
+++ httpd/httpd/trunk/modules/md/md_jws.c Mon Jul 12 07:52:28 2021
@@ -38,7 +38,6 @@ apr_status_t md_jws_sign(md_json_t **pms
     md_json_t *msg, *jprotected;
     const char *prot64, *pay64, *sign64, *sign, *prot;
     apr_status_t rv = APR_SUCCESS;
-    md_data_t data;
 
     *pmsg = NULL;
     
@@ -64,8 +63,9 @@ apr_status_t md_jws_sign(md_json_t **pms
     }
     
     if (rv == APR_SUCCESS) {
-        data.data = prot;
-        data.len = strlen(prot);
+        md_data_t data;
+
+        md_data_init(&data, prot, strlen(prot));
         prot64 = md_util_base64url_encode(&data, p);
         md_json_sets(prot64, msg, "protected", NULL);
         pay64 = md_util_base64url_encode(payload, p);
@@ -104,7 +104,7 @@ apr_status_t md_jws_pkey_thumb(const cha
 
     /* whitespace and order is relevant, since we hand out a digest of this */
     s = apr_psprintf(p, "{\"e\":\"%s\",\"kty\":\"RSA\",\"n\":\"%s\"}", e64, n64);
-    MD_DATA_SET_STR(&data, s);
+    md_data_init_str(&data, s);
     rv = md_crypt_sha256_digest64(pthumb, p, &data);
     return rv;
 }

Modified: httpd/httpd/trunk/modules/md/md_ocsp.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_ocsp.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_ocsp.c (original)
+++ httpd/httpd/trunk/modules/md/md_ocsp.c Mon Jul 12 07:52:28 2021
@@ -99,6 +99,11 @@ struct md_ocsp_id_map_t {
     md_data_t external_id;
 };
 
+static void md_openssl_free(void *d)
+{
+    OPENSSL_free(d);
+}
+
 const char *md_ocsp_cert_stat_name(md_ocsp_cert_stat_t stat)
 {
     switch (stat) {
@@ -121,11 +126,11 @@ apr_status_t md_ocsp_init_id(md_data_t *
     X509 *x = md_cert_get_X509(cert);
     unsigned int ulen = 0;
     
+    md_data_null(id);
     if (X509_digest(x, EVP_sha1(), iddata, &ulen) != 1) {
         return APR_EGENERAL;
     }
-    id->len = ulen;
-    id->data = apr_pmemdup(p, iddata, id->len);
+    md_data_assign_pcopy(id, (const char*)iddata, ulen, p);
     return APR_SUCCESS;
 }
 
@@ -135,11 +140,7 @@ static void ostat_req_cleanup(md_ocsp_st
         OCSP_REQUEST_free(ostat->ocsp_req);
         ostat->ocsp_req = NULL;
     }
-    if (ostat->req_der.data) {
-        OPENSSL_free((void*)ostat->req_der.data);
-        ostat->req_der.data = NULL;
-        ostat->req_der.len = 0;
-    }
+    md_data_clear(&ostat->req_der);
 }
 
 static int ostat_cleanup(void *ctx, const void *key, apr_ssize_t klen, const void *val)
@@ -155,11 +156,7 @@ static int ostat_cleanup(void *ctx, cons
         OCSP_CERTID_free(ostat->certid);
         ostat->certid = NULL;
     }
-    if (ostat->resp_der.data) {
-        OPENSSL_free((void*)ostat->resp_der.data);
-        ostat->resp_der.data = NULL;
-        ostat->resp_der.len = 0;
-    }
+    md_data_clear(&ostat->resp_der);
     return 1;
 }
 
@@ -174,27 +171,12 @@ static int ostat_should_renew(md_ocsp_st
 static apr_status_t ostat_set(md_ocsp_status_t *ostat, md_ocsp_cert_stat_t stat,
                               md_data_t *der, md_timeperiod_t *valid, apr_time_t mtime)
 {
-    apr_status_t rv = APR_SUCCESS;
-    char *s = (char*)der->data;
-    
-    if (der->len) {
-        s = OPENSSL_malloc(der->len);
-        if (!s) {
-            rv = APR_ENOMEM;
-            goto cleanup;
-        }
-        memcpy((char*)s, der->data, der->len);
-    }
- 
-    if (ostat->resp_der.data) {
-        OPENSSL_free((void*)ostat->resp_der.data);
-        ostat->resp_der.data = NULL;
-        ostat->resp_der.len = 0;
-    }
-    
+    apr_status_t rv;
+
+    rv = md_data_assign_copy(&ostat->resp_der, der->data, der->len);
+    if (APR_SUCCESS != rv) goto cleanup;
+
     ostat->resp_stat = stat;
-    ostat->resp_der.data = s;
-    ostat->resp_der.len = der->len;
     ostat->resp_valid = *valid;
     ostat->resp_mtime = mtime;
     
@@ -328,8 +310,7 @@ apr_status_t md_ocsp_prime(md_ocsp_reg_t
                            md_cert_t *cert, md_cert_t *issuer, const md_t *md)
 {
     md_ocsp_status_t *ostat;
-    STACK_OF(OPENSSL_STRING) *ssk = NULL;
-    const char *name, *s;
+    const char *name;
     md_data_t id;
     apr_status_t rv = APR_SUCCESS;
     
@@ -355,19 +336,13 @@ apr_status_t md_ocsp_prime(md_ocsp_reg_t
 
     md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
                   "md[%s]: getting ocsp responder from cert", name);
-    ssk = X509_get1_ocsp(md_cert_get_X509(cert));
-    if (!ssk) {
-        rv = APR_ENOENT;
-        md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, reg->p, 
-                      "md[%s]: certificate with serial %s has not OCSP responder URL", 
+    rv = md_cert_get_ocsp_responder_url(&ostat->responder_url, reg->p, cert);
+    if (APR_SUCCESS != rv) {
+        md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, reg->p,
+                      "md[%s]: certificate with serial %s has not OCSP responder URL",
                       name, md_cert_get_serial_number(cert, reg->p));
         goto cleanup;
     }
-    s = sk_OPENSSL_STRING_value(ssk, 0);
-    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, 0, reg->p, 
-                  "md[%s]: ocsp responder found '%s'", name, s);
-    ostat->responder_url = apr_pstrdup(reg->p, s);
-    X509_email_free(ssk);
 
     ostat->certid = OCSP_cert_to_id(NULL, md_cert_get_X509(cert), md_cert_get_X509(issuer));
     if (!ostat->certid) {
@@ -529,8 +504,9 @@ static const char *certid_as_hex(const O
     
     memset(&der, 0, sizeof(der));
     der.len = (apr_size_t)i2d_OCSP_CERTID((OCSP_CERTID*)certid, (unsigned char**)&der.data);
+    der.free_data = md_openssl_free;
     md_data_to_hex(&hex, 0, p, &der);
-    OPENSSL_free((void*)der.data);
+    md_data_clear(&der);
     return hex;
 }
 
@@ -716,8 +692,9 @@ static apr_status_t ostat_on_resp(const
         md_result_log(update->result, MD_LOG_WARNING);
         goto cleanup;
     }
-    nstat = (bstatus == V_OCSP_CERTSTATUS_GOOD)? MD_OCSP_CERT_ST_GOOD : MD_OCSP_CERT_ST_REVOKED;
     new_der.len = (apr_size_t)n;
+    new_der.free_data = md_openssl_free;
+    nstat = (bstatus == V_OCSP_CERTSTATUS_GOOD)? MD_OCSP_CERT_ST_GOOD : MD_OCSP_CERT_ST_REVOKED;
     valid.start = bup? md_asn1_generalized_time_get(bup) : apr_time_now();
     valid.end = md_asn1_generalized_time_get(bnextup);
     
@@ -740,7 +717,7 @@ static apr_status_t ostat_on_resp(const
     md_result_log(update->result, MD_LOG_DEBUG);
 
 cleanup:
-    if (new_der.data) OPENSSL_free((void*)new_der.data);
+    md_data_clear(&new_der);
     if (basic_resp) OCSP_BASICRESP_free(basic_resp);
     if (ocsp_resp) OCSP_RESPONSE_free(ocsp_resp);
     return rv;
@@ -781,18 +758,52 @@ typedef struct {
     int max_parallel;
 } md_ocsp_todo_ctx_t;
 
+static apr_status_t ocsp_req_make(OCSP_REQUEST **pocsp_req, OCSP_CERTID *certid)
+{
+    OCSP_REQUEST *req = NULL;
+    OCSP_CERTID *id_copy = NULL;
+    apr_status_t rv = APR_ENOMEM;
+
+    req = OCSP_REQUEST_new();
+    if (!req) goto cleanup;
+    id_copy = OCSP_CERTID_dup(certid);
+    if (!id_copy) goto cleanup;
+    if (!OCSP_request_add0_id(req, id_copy)) goto cleanup;
+    id_copy = NULL;
+    OCSP_request_add1_nonce(req, 0, -1);
+    rv = APR_SUCCESS;
+cleanup:
+    if (id_copy) OCSP_CERTID_free(id_copy);
+    if (APR_SUCCESS != rv && req) {
+        OCSP_REQUEST_free(req);
+        req = NULL;
+    }
+    *pocsp_req = req;
+    return rv;
+}
+
+static apr_status_t ocsp_req_assign_der(md_data_t *d, OCSP_REQUEST *ocsp_req)
+{
+    int len;
+
+    md_data_clear(d);
+    len = i2d_OCSP_REQUEST(ocsp_req, (unsigned char**)&d->data);
+    if (len < 0) return APR_ENOMEM;
+    d->len = (apr_size_t)len;
+    d->free_data = md_openssl_free;
+    return APR_SUCCESS;
+}
+
 static apr_status_t next_todo(md_http_request_t **preq, void *baton, 
                               md_http_t *http, int in_flight)
 {
     md_ocsp_todo_ctx_t *ctx = baton;
     md_ocsp_update_t *update, **pupdate;    
     md_ocsp_status_t *ostat;
-    OCSP_CERTID *certid = NULL;
     md_http_request_t *req = NULL;
     apr_status_t rv = APR_ENOENT;
     apr_table_t *headers;
-    int len;
-    
+
     if (in_flight < ctx->max_parallel) {
         pupdate = apr_array_pop(ctx->todos);
         if (pupdate) {
@@ -804,18 +815,12 @@ static apr_status_t next_todo(md_http_re
             md_job_start_run(update->job, update->result, ctx->reg->store);
              
             if (!ostat->ocsp_req) {
-                ostat->ocsp_req = OCSP_REQUEST_new();
-                if (!ostat->ocsp_req) goto cleanup;
-                certid = OCSP_CERTID_dup(ostat->certid);
-                if (!certid) goto cleanup;
-                if (!OCSP_request_add0_id(ostat->ocsp_req, certid)) goto cleanup;
-                OCSP_request_add1_nonce(ostat->ocsp_req, 0, -1);
-                certid = NULL;
+                rv = ocsp_req_make(&ostat->ocsp_req, ostat->certid);
+                if (APR_SUCCESS != rv) goto cleanup;
             }
             if (0 == ostat->req_der.len) {
-                len = i2d_OCSP_REQUEST(ostat->ocsp_req, (unsigned char**)&ostat->req_der.data);
-                if (len < 0) goto cleanup;
-                ostat->req_der.len = (apr_size_t)len;
+                rv = ocsp_req_assign_der(&ostat->req_der, ostat->ocsp_req);
+                if (APR_SUCCESS != rv) goto cleanup;
             }
             md_result_activity_printf(update->result, "status of certid %s, "
                                       "contacting %s", ostat->hexid, ostat->responder_url);
@@ -831,7 +836,6 @@ static apr_status_t next_todo(md_http_re
     }
 cleanup:
     *preq = (APR_SUCCESS == rv)? req : NULL;
-    if (certid) OCSP_CERTID_free(certid);
     return rv;
 }
 

Modified: httpd/httpd/trunk/modules/md/md_store_fs.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_store_fs.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_store_fs.c (original)
+++ httpd/httpd/trunk/modules/md/md_store_fs.c Mon Jul 12 07:52:28 2021
@@ -110,8 +110,7 @@ static apr_status_t init_store_file(md_s
     
     md_json_setn(MD_STORE_VERSION, json, MD_KEY_STORE, MD_KEY_VERSION, NULL);
 
-    s_fs->key.len = FS_STORE_KLEN;
-    s_fs->key.data = apr_pcalloc(p, FS_STORE_KLEN);
+    md_data_pinit(&s_fs->key, FS_STORE_KLEN, p);
     if (APR_SUCCESS != (rv = md_rand_bytes((unsigned char*)s_fs->key.data, s_fs->key.len, p))) {
         return rv;
     }
@@ -316,18 +315,29 @@ apr_status_t md_store_fs_init(md_store_t
     s_fs->group_perms[MD_SG_OCSP].file = MD_FPROT_F_UALL_WREAD;
 
     s_fs->base = apr_pstrdup(p, path);
-    
-    if (APR_STATUS_IS_ENOENT(rv = md_util_is_dir(s_fs->base, p))
-        && MD_OK(apr_dir_make_recursive(s_fs->base, s_fs->def_perms.dir, p))) {
+
+    rv = md_util_is_dir(s_fs->base, p);
+    if (APR_STATUS_IS_ENOENT(rv)) {
+        md_log_perror(MD_LOG_MARK, MD_LOG_INFO, rv, p,
+            "store directory does not exist, creating %s", s_fs->base);
+        rv = apr_dir_make_recursive(s_fs->base, s_fs->def_perms.dir, p);
+        if (APR_SUCCESS != rv) goto cleanup;
         rv = apr_file_perms_set(s_fs->base, MD_FPROT_D_UALL_WREAD);
         if (APR_STATUS_IS_ENOTIMPL(rv)) {
             rv = APR_SUCCESS;
         }
+        if (APR_SUCCESS != rv) goto cleanup;
     }
-    
-    if ((APR_SUCCESS != rv) || !MD_OK(md_util_pool_vdo(setup_store_file, s_fs, p, NULL))) {
-        md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "init fs store at %s", path);
+    else if (APR_SUCCESS != rv) {
+        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p,
+            "not a plain directory, maybe a symlink? %s", s_fs->base);
     }
+
+    rv = md_util_pool_vdo(setup_store_file, s_fs, p, NULL);
+    if (APR_SUCCESS != rv) {
+        md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "init fs store at %s", s_fs->base);
+    }
+cleanup:
     *pstore = (rv == APR_SUCCESS)? &(s_fs->s) : NULL;
     return rv;
 }
@@ -493,21 +503,24 @@ static apr_status_t mk_group_dir(const c
     
     perms = gperms(s_fs, group);
 
-    if (MD_OK(fs_get_dname(pdir, &s_fs->s, group, name, p)) && (MD_SG_NONE != group)) {
-        if (  !MD_OK(md_util_is_dir(*pdir, p))
-            && MD_OK(apr_dir_make_recursive(*pdir, perms->dir, p))) {
-            rv = dispatch(s_fs, MD_S_FS_EV_CREATED, group, *pdir, APR_DIR, p);
-        }
-        
-        if (APR_SUCCESS == rv) {
-            rv = apr_file_perms_set(*pdir, perms->dir);
-            md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "mk_group_dir %s perm set", *pdir);
-            if (APR_STATUS_IS_ENOTIMPL(rv)) {
-                rv = APR_SUCCESS;
-            }
-        }
+    rv = fs_get_dname(pdir, &s_fs->s, group, name, p);
+    if ((APR_SUCCESS != rv) || (MD_SG_NONE == group)) goto cleanup;
+
+    rv = md_util_is_dir(*pdir, p);
+    if (APR_STATUS_IS_ENOENT(rv)) {
+        md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "not a directory, creating %s", *pdir);
+        rv = apr_dir_make_recursive(*pdir, perms->dir, p);
+        if (APR_SUCCESS != rv) goto cleanup;
+        dispatch(s_fs, MD_S_FS_EV_CREATED, group, *pdir, APR_DIR, p);
+    }
+
+    rv = apr_file_perms_set(*pdir, perms->dir);
+    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "mk_group_dir %s perm set", *pdir);
+    if (APR_STATUS_IS_ENOTIMPL(rv)) {
+        rv = APR_SUCCESS;
     }
-    md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, p, "mk_group_dir %d %s", group, name);
+cleanup:
+    md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, p, "mk_group_dir %d %s", group, name);
     return rv;
 }
 

Modified: httpd/httpd/trunk/modules/md/md_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_util.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_util.c (original)
+++ httpd/httpd/trunk/modules/md/md_util.c Mon Jul 12 07:52:28 2021
@@ -76,28 +76,73 @@ apr_status_t md_util_pool_vdo(md_util_va
 /**************************************************************************************************/
 /* data chunks */
 
-md_data_t *md_data_create(apr_pool_t *p, const char *data, apr_size_t len)
+void md_data_pinit(md_data_t *d, apr_size_t len, apr_pool_t *p)
+{
+    md_data_null(d);
+    d->data = apr_pcalloc(p, len);
+    d->len = len;
+}
+
+md_data_t *md_data_pmake(apr_size_t len, apr_pool_t *p)
 {
     md_data_t *d;
     
     d = apr_palloc(p, sizeof(*d));
-    d->len = len;
-    d->data = len? apr_pstrndup(p, data, len) : NULL;
+    md_data_pinit(d, len, p);
     return d;
 }
 
-md_data_t *md_data_make(apr_pool_t *p, apr_size_t len)
+void md_data_init(md_data_t *d, const char *data, apr_size_t len)
+{
+    md_data_null(d);
+    d->len = len;
+    d->data = data;
+}
+
+void md_data_init_str(md_data_t *d, const char *str)
+{
+    md_data_init(d, str, strlen(str));
+}
+
+void md_data_null(md_data_t *d)
+{
+    memset(d, 0, sizeof(*d));
+}
+
+void md_data_clear(md_data_t *d)
+{
+    if (d) {
+        if (d->data && d->free_data) d->free_data((void*)d->data);
+        memset(d, 0, sizeof(*d));
+    }
+}
+
+md_data_t *md_data_make_pcopy(apr_pool_t *p, const char *data, apr_size_t len)
 {
     md_data_t *d;
-    
+
     d = apr_palloc(p, sizeof(*d));
     d->len = len;
-    d->data = apr_pcalloc(p, len);
+    d->data = len? apr_pmemdup(p, data, len) : NULL;
     return d;
 }
 
+apr_status_t md_data_assign_copy(md_data_t *dest, const char *src, apr_size_t src_len)
+{
+    md_data_clear(dest);
+    if (src && src_len) {
+        dest->data = malloc(src_len);
+        if (!dest->data) return APR_ENOMEM;
+        memcpy((void*)dest->data, src, src_len);
+        dest->len = src_len;
+        dest->free_data = free;
+    }
+    return APR_SUCCESS;
+}
+
 void md_data_assign_pcopy(md_data_t *dest, const char *src, apr_size_t src_len, apr_pool_t *p)
 {
+    md_data_clear(dest);
     dest->data = (src && src_len)? apr_pmemdup(p, src, src_len) : NULL;
     dest->len = dest->data? src_len : 0;
 }

Modified: httpd/httpd/trunk/modules/md/md_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_util.h?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_util.h (original)
+++ httpd/httpd/trunk/modules/md/md_util.h Mon Jul 12 07:52:28 2021
@@ -35,17 +35,48 @@ apr_status_t md_util_pool_vdo(md_util_va
 /**************************************************************************************************/
 /* data chunks */
 
+typedef void md_data_free_fn(void *data);
+
 typedef struct md_data_t md_data_t;
 struct md_data_t {
     const char *data;
     apr_size_t len;
+    md_data_free_fn *free_data;
 };
 
-#define MD_DATA_CWRAP(d, buffer)       md_data_t d = { buffer, sizeof(buffer) }
+/**
+ * Init the data to empty, overwriting any content.
+ */
+void md_data_null(md_data_t *d);
+
+/**
+ * Create a new md_data_t, providing `len` bytes allocated from pool `p`.
+ */
+md_data_t *md_data_pmake(apr_size_t len, apr_pool_t *p);
+/**
+ * Initialize md_data_t 'd', providing `len` bytes allocated from pool `p`.
+ */
+void md_data_pinit(md_data_t *d, apr_size_t len, apr_pool_t *p);
+/**
+ * Initialize md_data_t 'd', by borrowing 'len' bytes in `data` without copying.
+ * `d` will not take ownership.
+ */
+void md_data_init(md_data_t *d, const char *data, apr_size_t len);
+
+/**
+ * Initialize md_data_t 'd', by borrowing the NUL-terminated `str`.
+ * `d` will not take ownership.
+ */
+void md_data_init_str(md_data_t *d, const char *str);
+
+/**
+ * Free any present data and clear (NULL) it. Passing NULL is permitted.
+ */
+void md_data_clear(md_data_t *d);
 
-md_data_t *md_data_make(apr_pool_t *p, apr_size_t len);
-md_data_t *md_data_create(apr_pool_t *p, const char *data, apr_size_t len);
+md_data_t *md_data_make_pcopy(apr_pool_t *p, const char *data, apr_size_t len);
 
+apr_status_t md_data_assign_copy(md_data_t *dest, const char *src, apr_size_t src_len);
 void md_data_assign_pcopy(md_data_t *dest, const char *src, apr_size_t src_len, apr_pool_t *p);
 
 apr_status_t md_data_to_hex(const char **phex, char separator,

Modified: httpd/httpd/trunk/modules/md/md_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_version.h?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_version.h (original)
+++ httpd/httpd/trunk/modules/md/md_version.h Mon Jul 12 07:52:28 2021
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the md module as c string
  */
-#define MOD_MD_VERSION "2.4.2"
+#define MOD_MD_VERSION "2.4.3"
 
 /**
  * @macro
@@ -35,7 +35,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_MD_VERSION_NUM 0x020402
+#define MOD_MD_VERSION_NUM 0x020403
 
 #define MD_ACME_DEF_URL    "https://acme-v02.api.letsencrypt.org/directory"
 

Modified: httpd/httpd/trunk/modules/md/mod_md.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md.c Mon Jul 12 07:52:28 2021
@@ -1501,16 +1501,11 @@ static void md_hooks(apr_pool_t *pool)
     ap_hook_ssl_add_cert_files(md_add_cert_files, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_ssl_add_fallback_cert_files(md_add_fallback_cert_files, NULL, NULL, APR_HOOK_MIDDLE);
 
-#if AP_MODULE_MAGIC_AT_LEAST(20210420, 0)
+#if AP_MODULE_MAGIC_AT_LEAST(20120211, 105)
     ap_hook_ssl_ocsp_prime_hook(md_ocsp_prime_status, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_ssl_ocsp_get_resp_hook(md_ocsp_provide_status, NULL, NULL, APR_HOOK_MIDDLE);
 #else
-
-#ifndef SSL_CERT_HOOKS
-#error "This version of mod_md requires Apache httpd 2.4.41 or newer."
-#endif
-    APR_OPTIONAL_HOOK(ssl, init_stapling_status, md_ocsp_init_stapling_status, NULL, NULL, APR_HOOK_MIDDLE);
-    APR_OPTIONAL_HOOK(ssl, get_stapling_status, md_ocsp_get_stapling_status, NULL, NULL, APR_HOOK_MIDDLE);
+#error "This version of mod_md requires Apache httpd 2.4.48 or newer."
 #endif /* AP_MODULE_MAGIC_AT_LEAST() */
 }
 

Modified: httpd/httpd/trunk/modules/md/mod_md.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md.h?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md.h (original)
+++ httpd/httpd/trunk/modules/md/mod_md.h Mon Jul 12 07:52:28 2021
@@ -17,31 +17,4 @@
 #ifndef mod_md_mod_md_h
 #define mod_md_mod_md_h
 
-#include <openssl/evp.h>
-#include <openssl/x509v3.h>
-
-struct server_rec;
-
-APR_DECLARE_OPTIONAL_FN(int, 
-                        md_is_managed, (struct server_rec *));
-
-/**
- * Get the certificate/key for the managed domain (md_is_managed != 0).
- * 
- * @return APR_EAGAIN if the real certificate is not available yet
- */
-APR_DECLARE_OPTIONAL_FN(apr_status_t, 
-                        md_get_certificate, (struct server_rec *, apr_pool_t *,
-                                             const char **pkeyfile, 
-                                             const char **pcertfile));
-
-APR_DECLARE_OPTIONAL_FN(int, 
-                        md_is_challenge, (struct conn_rec *, const char *,
-                                          X509 **pcert, EVP_PKEY **pkey));
-
-APR_DECLARE_OPTIONAL_FN(apr_status_t,
-                        md_answer_challenges, (conn_rec *c, const char *servername,
-                                               apr_array_header_t *certs,
-                                               apr_array_header_t *pkeys));
-
 #endif /* mod_md_mod_md_h */

Modified: httpd/httpd/trunk/modules/md/mod_md_ocsp.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_ocsp.c?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_ocsp.c (original)
+++ httpd/httpd/trunk/modules/md/mod_md_ocsp.c Mon Jul 12 07:52:28 2021
@@ -53,29 +53,6 @@ static int staple_here(md_srv_conf_t *sc
             && md_config_geti(sc, MD_CONFIG_STAPLE_OTHERS));
 }
 
-int md_ocsp_init_stapling_status(server_rec *s, apr_pool_t *p, 
-                                 X509 *cert, X509 *issuer)
-{
-    md_srv_conf_t *sc;
-    const md_t *md;
-    apr_status_t rv;
-
-    sc = md_config_get(s);
-    if (!staple_here(sc)) goto declined;
-    md = ((sc->assigned && sc->assigned->nelts == 1)?
-          APR_ARRAY_IDX(sc->assigned, 0, const md_t*) : NULL);
-
-    rv = md_ocsp_prime(sc->mc->ocsp, NULL, 0, md_cert_wrap(p, cert),
-                       md_cert_wrap(p, issuer), md);
-    ap_log_error(APLOG_MARK, APLOG_TRACE1, rv, s, "init stapling for: %s", 
-                 md? md->name : s->server_hostname);
-    if (APR_SUCCESS == rv) {
-        return OK;
-    }
-declined:
-    return DECLINED;
-}
-
 int md_ocsp_prime_status(server_rec *s, apr_pool_t *p,
                          const char *id, apr_size_t id_len, const char *pem)
 {
@@ -118,51 +95,6 @@ typedef struct {
     apr_size_t der_len;
 } ocsp_copy_ctx_t;
 
-static void ocsp_copy_der(const unsigned char *der, apr_size_t der_len, void *userdata)
-{
-    ocsp_copy_ctx_t *ctx = userdata;
-
-    memset(ctx, 0, sizeof(*ctx));
-    if (der && der_len > 0) {
-        ctx->der = OPENSSL_malloc(der_len);
-        if (ctx->der != NULL) {
-            ctx->der_len = der_len;
-            memcpy(ctx->der, der, der_len);
-        }
-    }
-}
-
-int md_ocsp_get_stapling_status(unsigned char **pder, int *pderlen,
-                                         conn_rec *c, server_rec *s, X509 *x)
-{
-    md_srv_conf_t *sc;
-    const md_t *md;
-    md_cert_t *cert;
-    md_data_t id;
-    apr_status_t rv;
-    ocsp_copy_ctx_t ctx;
-
-    sc = md_config_get(s);
-    if (!staple_here(sc)) goto declined;
-    
-    md = ((sc->assigned && sc->assigned->nelts == 1)?
-          APR_ARRAY_IDX(sc->assigned, 0, const md_t*) : NULL);
-    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, "get stapling for: %s", 
-                  md? md->name : s->server_hostname);
-    cert = md_cert_wrap(c->pool, x);
-    rv = md_ocsp_init_id(&id, c->pool, cert);
-    if (APR_SUCCESS != rv) goto declined;
-
-    rv = md_ocsp_get_status(ocsp_copy_der, &ctx, sc->mc->ocsp, id.data, id.len, c->pool, md);
-    if (APR_STATUS_IS_ENOENT(rv)) goto declined;
-    *pder = ctx.der;
-    *pderlen = (int)ctx.der_len;
-    return OK;
-    
-declined:
-    return DECLINED;
-}
-
 int md_ocsp_provide_status(server_rec *s, conn_rec *c,
                            const char *id, apr_size_t id_len,
                            ap_ssl_ocsp_copy_resp *cb, void *userdata)

Modified: httpd/httpd/trunk/modules/md/mod_md_ocsp.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/mod_md_ocsp.h?rev=1891470&r1=1891469&r2=1891470&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/mod_md_ocsp.h (original)
+++ httpd/httpd/trunk/modules/md/mod_md_ocsp.h Mon Jul 12 07:52:28 2021
@@ -18,12 +18,6 @@
 #define mod_md_md_ocsp_h
 
 
-int md_ocsp_init_stapling_status(server_rec *s, apr_pool_t *p, 
-                                 X509 *cert, X509 *issuer);
-
-int md_ocsp_get_stapling_status(unsigned char **pder, int *pderlen, 
-                                conn_rec *c, server_rec *s, X509 *cert);
-                          
 int md_ocsp_prime_status(server_rec *s, apr_pool_t *p,
                          const char *id, apr_size_t id_len, const char *pem);