From 1de4462974113ac18cf98f903e97cd1127fa842f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 25 Apr 2018 12:37:34 +0200 Subject: [PATCH] dirmngr: Allow redirection from https to http for CRLs * dirmngr/ks-engine.h (KS_HTTP_FETCH_NOCACHE): New flag. (KS_HTTP_FETCH_TRUST_CFG): Ditto. (KS_HTTP_FETCH_NO_CRL): Ditto. (KS_HTTP_FETCH_ALLOW_DOWNGRADE): Ditto. * dirmngr/ks-engine-http.c (ks_http_fetch): Replace args send_no_cache and extra_http_trust_flags by a new flags arg. Allow redirectiong from https to http it KS_HTTP_FETCH_ALLOW_DOWNGRADE is set. * dirmngr/loadswdb.c (fetch_file): Call with KS_HTTP_FETCH_NOCACHE. * dirmngr/ks-action.c (ks_action_get): Ditto. (ks_action_fetch): Ditto. * dirmngr/crlfetch.c (crl_fetch): Call with the appropriate flags. -- Signed-off-by: Werner Koch --- dirmngr/crlfetch.c | 13 ++++++++----- dirmngr/ks-action.c | 5 +++-- dirmngr/ks-engine-http.c | 31 ++++++++++++++++++++----------- dirmngr/ks-engine.h | 10 ++++++++-- dirmngr/loadswdb.c | 2 +- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c index 0d27aa0f1..57ac51b93 100644 --- a/dirmngr/crlfetch.c +++ b/dirmngr/crlfetch.c @@ -175,11 +175,14 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) else { /* Note that we also allow root certificates loaded from - * "/etc/gnupg/trusted-certs/". We also do not consult - * the CRL for the TLS connection - that may lwad to a - * loop. */ - err = ks_http_fetch (ctrl, url, 0, - (HTTP_FLAG_TRUST_CFG | HTTP_FLAG_NO_CRL), + * "/etc/gnupg/trusted-certs/". We also do not consult the + * CRL for the TLS connection - that may lead to a loop. + * Due to cacert.org redirecting their https URL to http we + * also allow such a downgrade. */ + err = ks_http_fetch (ctrl, url, + (KS_HTTP_FETCH_TRUST_CFG + | KS_HTTP_FETCH_NO_CRL + | KS_HTTP_FETCH_ALLOW_DOWNGRADE ), &httpfp); } diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index eb15e40dd..c1ecafb58 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -257,7 +257,8 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers, if (is_hkp_s) err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp); else if (is_http_s) - err = ks_http_fetch (ctrl, uri->parsed_uri->original, 1, 0, + err = ks_http_fetch (ctrl, uri->parsed_uri->original, + KS_HTTP_FETCH_NOCACHE, &infp); else BUG (); @@ -315,7 +316,7 @@ ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) if (parsed_uri->is_http) { - err = ks_http_fetch (ctrl, url, 1, 0, &infp); + err = ks_http_fetch (ctrl, url, KS_HTTP_FETCH_NOCACHE, &infp); if (!err) { err = copy_stream (infp, outfp); diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index a03580373..946c92769 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -67,11 +67,12 @@ ks_http_help (ctrl_t ctrl, parsed_uri_t uri) * data via https or http. */ gpg_error_t -ks_http_fetch (ctrl_t ctrl, const char *url, int send_no_cache, - unsigned int extra_http_trust_flags, estream_t *r_fp) +ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, + estream_t *r_fp) { gpg_error_t err; http_session_t session = NULL; + unsigned int session_flags; http_t http = NULL; int redirects_left = MAX_REDIRECTS; estream_t fp = NULL; @@ -85,14 +86,16 @@ ks_http_fetch (ctrl_t ctrl, const char *url, int send_no_cache, is_onion = uri->onion; is_https = uri->use_tls; - once_more: /* By default we only use the system provided certificates with this - * fetch command. However, EXTRA_HTTP_FLAGS can be used to add more - * flags. */ - err = http_session_new (&session, NULL, - ((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0) - | HTTP_FLAG_TRUST_SYS - | extra_http_trust_flags), + * fetch command. */ + session_flags = HTTP_FLAG_TRUST_SYS; + if ((flags & KS_HTTP_FETCH_NO_CRL) || ctrl->http_no_crl) + session_flags |= HTTP_FLAG_NO_CRL; + if ((flags & KS_HTTP_FETCH_TRUST_CFG)) + session_flags |= HTTP_FLAG_TRUST_CFG; + + once_more: + err = http_session_new (&session, NULL, session_flags, gnupg_http_tls_verify_cb, ctrl); if (err) goto leave; @@ -120,7 +123,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, int send_no_cache, /* Avoid caches to get the most recent copy of the key. We set * both the Pragma and Cache-Control versions of the header, so * we're good with both HTTP 1.0 and 1.1. */ - if (send_no_cache) + if ((flags & KS_HTTP_FETCH_NOCACHE)) es_fputs ("Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", fp); http_start_data (http); @@ -172,7 +175,13 @@ ks_http_fetch (ctrl_t ctrl, const char *url, int send_no_cache, if (err) goto leave; - if ((is_onion && ! uri->onion) || (is_https && ! uri->use_tls)) + if (is_onion && !uri->onion) + { + err = gpg_error (GPG_ERR_FORBIDDEN); + goto leave; + } + if (!(flags & KS_HTTP_FETCH_ALLOW_DOWNGRADE) + && is_https && !uri->use_tls) { err = gpg_error (GPG_ERR_FORBIDDEN); goto leave; diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h index ce51141bd..d28c6ab71 100644 --- a/dirmngr/ks-engine.h +++ b/dirmngr/ks-engine.h @@ -41,9 +41,15 @@ gpg_error_t ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen); /*-- ks-engine-http.c --*/ + +/* Flags for the ks_http_fetch. */ +#define KS_HTTP_FETCH_NOCACHE 1 /* Request no caching. */ +#define KS_HTTP_FETCH_TRUST_CFG 2 /* Requests HTTP_FLAG_TRUST_CFG. */ +#define KS_HTTP_FETCH_NO_CRL 4 /* Requests HTTP_FLAG_NO_CRL. */ +#define KS_HTTP_FETCH_ALLOW_DOWNGRADE 8 /* Allow redirect https -> http. */ + gpg_error_t ks_http_help (ctrl_t ctrl, parsed_uri_t uri); -gpg_error_t ks_http_fetch (ctrl_t ctrl, const char *url, int send_no_cache, - unsigned int extra_http_trust_flags, +gpg_error_t ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, estream_t *r_fp); diff --git a/dirmngr/loadswdb.c b/dirmngr/loadswdb.c index dfa027386..fb883722a 100644 --- a/dirmngr/loadswdb.c +++ b/dirmngr/loadswdb.c @@ -126,7 +126,7 @@ fetch_file (ctrl_t ctrl, const char *url, estream_t *r_fp) size_t nread, nwritten; char buffer[1024]; - if ((err = ks_http_fetch (ctrl, url, 1, 0, &httpfp))) + if ((err = ks_http_fetch (ctrl, url, KS_HTTP_FETCH_NOCACHE, &httpfp))) goto leave; /* We now read the data from the web server into a memory buffer.