summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2019-10-30 23:39:35 +0100
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-02-10 16:49:37 +0100
commit29f178bddfdbd11218fbcba0b8060297696968e3 (patch)
treea44efcd919c122d9c6ff38c61b14676b002aa010
parentbcbb30afe2ef51c7affaaa7ce4db67e26e7ff6b7 (diff)
Generalize the HTTP client so far implemented mostly in crypto/ocsp/ocsp_ht.c
The new client has become an independent libcrpyto module in crypto/http/ and * can handle any types of requests and responses (ASN.1-encoded and plain) * does not include potentially busy loops when waiting for responses but * makes use of a new timeout mechanism integrated with socket-based BIO * supports the use of HTTP proxies and TLS, including HTTPS over proxies * supports HTTP redirection via codes 301 and 302 for GET requests * returns more useful diagnostics in various error situations Also adapts - and strongly simplifies - hitherto uses of HTTP in crypto/ocsp/, crypto/x509/x_all.c, apps/lib/apps.c, and apps/{ocsp,s_client,s_server}.c Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> (Merged from https://github.com/openssl/openssl/pull/10667)
-rw-r--r--apps/include/apps.h26
-rw-r--r--apps/lib/apps.c187
-rw-r--r--apps/ocsp.c123
-rw-r--r--apps/s_client.c130
-rw-r--r--apps/s_server.c13
-rw-r--r--crypto/build.info2
-rw-r--r--crypto/cmp/cmp_ctx.c2
-rw-r--r--crypto/cmp/cmp_err.c2
-rw-r--r--crypto/cmp/cmp_local.h2
-rw-r--r--crypto/err/err.c1
-rw-r--r--crypto/err/err_all.c2
-rw-r--r--crypto/err/openssl.ec1
-rw-r--r--crypto/err/openssl.txt28
-rw-r--r--crypto/http/build.info2
-rw-r--r--crypto/http/http_client.c1238
-rw-r--r--crypto/http/http_err.c67
-rw-r--r--crypto/http/http_lib.c116
-rw-r--r--crypto/http/http_local.h51
-rw-r--r--crypto/ocsp/build.info2
-rw-r--r--crypto/ocsp/ocsp_err.c5
-rw-r--r--crypto/ocsp/ocsp_ht.c502
-rw-r--r--crypto/ocsp/ocsp_http.c65
-rw-r--r--crypto/ocsp/ocsp_lib.c107
-rw-r--r--crypto/x509/x_all.c29
-rw-r--r--doc/man3/OCSP_sendreq_new.pod49
-rw-r--r--doc/man3/OSSL_CMP_CTX_new.pod47
-rw-r--r--doc/man3/OSSL_HTTP_transfer.pod210
-rw-r--r--doc/man3/X509_load_http.pod63
-rw-r--r--include/openssl/cmp.h10
-rw-r--r--include/openssl/cmperr.h1
-rw-r--r--include/openssl/err.h2
-rw-r--r--include/openssl/http.h72
-rw-r--r--include/openssl/httperr.h55
-rw-r--r--include/openssl/ocsp.h35
-rw-r--r--include/openssl/ocsperr.h5
-rw-r--r--include/openssl/types.h2
-rw-r--r--include/openssl/x509.h13
-rw-r--r--test/build.info8
-rw-r--r--test/cmp_ctx_test.c9
-rw-r--r--test/http_test.c181
-rw-r--r--test/recipes/80-test_http.t21
-rwxr-xr-xutil/err-to-raise1
-rw-r--r--util/libcrypto.num16
-rw-r--r--util/missingcrypto.txt3
-rw-r--r--util/other.syms5
45 files changed, 2495 insertions, 1016 deletions
diff --git a/apps/include/apps.h b/apps/include/apps.h
index c33a98772b..78be647619 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -28,12 +28,14 @@
# include <openssl/txt_db.h>
# include <openssl/engine.h>
# include <openssl/ocsp.h>
+# include <openssl/http.h>
# include <signal.h>
# include "apps_ui.h"
# include "opt.h"
# include "fmt.h"
# include "platform.h"
+/* also in include/internal/sockets.h */
# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE)
# define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
# else
@@ -215,6 +217,30 @@ void print_cert_checks(BIO *bio, X509 *x,
void store_setup_crl_download(X509_STORE *st);
+typedef struct app_http_tls_info_st {
+ const char *server;
+ const char *port;
+ int use_proxy;
+ long timeout;
+ SSL_CTX *ssl_ctx;
+} APP_HTTP_TLS_INFO;
+BIO *app_http_tls_cb(BIO *hbio, /* APP_HTTP_TLS_INFO */ void *arg,
+ int connect, int detail);
+# ifndef OPENSSL_NO_SOCK
+ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
+ const char *proxy_port, SSL_CTX *ssl_ctx,
+ const STACK_OF(CONF_VALUE) *headers,
+ long timeout, const char *expected_content_type,
+ const ASN1_ITEM *it);
+ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
+ const char *path, const char *proxy,
+ const char *proxy_port, SSL_CTX *ctx,
+ const STACK_OF(CONF_VALUE) *headers,
+ const char *content_type,
+ ASN1_VALUE *req, const ASN1_ITEM *req_it,
+ long timeout, const ASN1_ITEM *rsp_it);
+# endif
+
# define EXT_COPY_NONE 0
# define EXT_COPY_ADD 1
# define EXT_COPY_ALL 2
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 3a18cd007c..bf20254463 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -441,62 +441,14 @@ static int load_pkcs12(BIO *in, const char *desc,
return ret;
}
-#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
-static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl)
-{
- char *host = NULL, *port = NULL, *path = NULL;
- BIO *bio = NULL;
- OCSP_REQ_CTX *rctx = NULL;
- int use_ssl, rv = 0;
- if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl))
- goto err;
- if (use_ssl) {
- BIO_puts(bio_err, "https not supported\n");
- goto err;
- }
- bio = BIO_new_connect(host);
- if (!bio || !BIO_set_conn_port(bio, port))
- goto err;
- rctx = OCSP_REQ_CTX_new(bio, 1024);
- if (rctx == NULL)
- goto err;
- if (!OCSP_REQ_CTX_http(rctx, "GET", path))
- goto err;
- if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host))
- goto err;
- if (pcert) {
- do {
- rv = X509_http_nbio(rctx, pcert);
- } while (rv == -1);
- } else {
- do {
- rv = X509_CRL_http_nbio(rctx, pcrl);
- } while (rv == -1);
- }
-
- err:
- OPENSSL_free(host);
- OPENSSL_free(path);
- OPENSSL_free(port);
- BIO_free_all(bio);
- OCSP_REQ_CTX_free(rctx);
- if (rv != 1) {
- BIO_printf(bio_err, "Error loading %s from %s\n",
- pcert ? "certificate" : "CRL", url);
- ERR_print_errors(bio_err);
- }
- return rv;
-}
-#endif
-
X509 *load_cert(const char *file, int format, const char *cert_descrip)
{
X509 *x = NULL;
BIO *cert;
if (format == FORMAT_HTTP) {
-#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
- load_cert_crl_http(file, &x, NULL);
+#if !defined(OPENSSL_NO_SOCK)
+ x = X509_load_http(file, NULL, NULL, 0 /* timeout */);
#endif
return x;
}
@@ -537,8 +489,8 @@ X509_CRL *load_crl(const char *infile, int format)
BIO *in = NULL;
if (format == FORMAT_HTTP) {
-#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
- load_cert_crl_http(infile, NULL, &x);
+#if !defined(OPENSSL_NO_SOCK)
+ x = X509_CRL_load_http(infile, NULL, NULL, 0 /* timeout */);
#endif
return x;
}
@@ -1981,6 +1933,137 @@ void store_setup_crl_download(X509_STORE *st)
X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
}
+#ifndef OPENSSL_NO_SOCK
+static const char *tls_error_hint(void)
+{
+ unsigned long err = ERR_peek_error();
+
+ if (ERR_GET_LIB(err) != ERR_LIB_SSL)
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) != ERR_LIB_SSL)
+ return NULL;
+
+ switch (ERR_GET_REASON(err)) {
+ case SSL_R_WRONG_VERSION_NUMBER:
+ return "The server does not support (a suitable version of) TLS";
+ case SSL_R_UNKNOWN_PROTOCOL:
+ return "The server does not support HTTPS";
+ case SSL_R_CERTIFICATE_VERIFY_FAILED:
+ return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status";
+ case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA:
+ return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status";
+ case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE:
+ return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it";
+ default: /* no error or no hint available for error */
+ return NULL;
+ }
+}
+
+/* HTTP callback function that supports TLS connection also via HTTPS proxy */
+BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
+{
+ APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
+ SSL_CTX *ssl_ctx = info->ssl_ctx;
+ SSL *ssl;
+ BIO *sbio = NULL;
+
+ if (connect && detail) { /* connecting with TLS */
+ if ((info->use_proxy
+ && !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
+ NULL, NULL, /* no proxy credentials */
+ info->timeout, bio_err, opt_getprog()))
+ || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
+ return NULL;
+ }
+ if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) {
+ BIO_free(sbio);
+ return NULL;
+ }
+
+ SSL_set_tlsext_host_name(ssl, info->server);
+
+ SSL_set_connect_state(ssl);
+ BIO_set_ssl(sbio, ssl, BIO_CLOSE);
+
+ hbio = BIO_push(sbio, hbio);
+ } else if (!connect && !detail) { /* disconnecting after error */
+ const char *hint = tls_error_hint();
+ if (hint != NULL)
+ ERR_add_error_data(1, hint);
+ /*
+ * If we pop sbio and BIO_free() it this may lead to libssl double free.
+ * Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
+ */
+ }
+ return hbio;
+}
+
+ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
+ const char *proxy_port, SSL_CTX *ssl_ctx,
+ const STACK_OF(CONF_VALUE) *headers,
+ long timeout, const char *expected_content_type,
+ const ASN1_ITEM *it)
+{
+ APP_HTTP_TLS_INFO info;
+ char *server;
+ char *port;
+ int use_ssl;
+ ASN1_VALUE *resp = NULL;
+
+ if (url == NULL || it == NULL) {
+ HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if (!OSSL_HTTP_parse_url(url, &server, &port, NULL /* ppath */, &use_ssl))
+ return NULL;
+ if (use_ssl && ssl_ctx == NULL) {
+ HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
+ ERR_add_error_data(1, "missing SSL_CTX");
+ goto end;
+ }
+
+ info.server = server;
+ info.port = port;
+ info.use_proxy = proxy != NULL;
+ info.timeout = timeout;
+ info.ssl_ctx = ssl_ctx;
+ resp = OSSL_HTTP_get_asn1(url, proxy, proxy_port,
+ NULL, NULL, app_http_tls_cb, &info,
+ headers, 0 /* maxline */, 0 /* max_resp_len */,
+ timeout, expected_content_type, it);
+ end:
+ OPENSSL_free(server);
+ OPENSSL_free(port);
+ return resp;
+
+}
+
+ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
+ const char *path, const char *proxy,
+ const char *proxy_port, SSL_CTX *ssl_ctx,
+ const STACK_OF(CONF_VALUE) *headers,
+ const char *content_type,
+ ASN1_VALUE *req, const ASN1_ITEM *req_it,
+ long timeout, const ASN1_ITEM *rsp_it)
+{
+ APP_HTTP_TLS_INFO info;
+
+ info.server = host;
+ info.port = port;
+ info.use_proxy = proxy != NULL;
+ info.timeout = timeout;
+ info.ssl_ctx = ssl_ctx;
+ return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
+ proxy, proxy_port,
+ NULL, NULL, app_http_tls_cb, &info,
+ headers, content_type, req, req_it,
+ 0 /* maxline */,
+ 0 /* max_resp_len */, timeout, NULL, rsp_it);
+}
+
+#endif
+
/*
* Platform-specific sections
*/
diff --git a/apps/ocsp.c b/apps/ocsp.c
index 4c66e966ef..3297b4287a 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -118,13 +118,6 @@ static int print_syslog(const char *str, size_t len, void *levPtr);
static void socket_timeout(int signum);
# endif
-# ifndef OPENSSL_NO_SOCK
-static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
- const char *path,
- const STACK_OF(CONF_VALUE) *headers,
- OCSP_REQUEST *req, int req_timeout);
-# endif
-
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT,
@@ -315,7 +308,8 @@ int ocsp_main(int argc, char **argv)
OPENSSL_free(tport);
OPENSSL_free(tpath);
thost = tport = tpath = NULL;
- if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) {
+ if (!OSSL_HTTP_parse_url(opt_arg(),
+ &host, &port, &path, &use_ssl)) {
BIO_printf(bio_err, "%s Error parsing URL\n", prog);
goto end;
}
@@ -1541,133 +1535,34 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
}
# ifndef OPENSSL_NO_SOCK
-static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
- const char *path,
- const STACK_OF(CONF_VALUE) *headers,
- OCSP_REQUEST *req, int req_timeout)
-{
- int fd;
- int rv;
- int i;
- int add_host = 1;
- OCSP_REQ_CTX *ctx = NULL;
- OCSP_RESPONSE *rsp = NULL;
- fd_set confds;
- struct timeval tv;
-
- if (req_timeout != -1)
- BIO_set_nbio(cbio, 1);
-
- rv = BIO_do_connect(cbio);
-
- if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
- BIO_puts(bio_err, "Error connecting BIO\n");
- return NULL;
- }
-
- if (BIO_get_fd(cbio, &fd) < 0) {
- BIO_puts(bio_err, "Can't get connection fd\n");
- goto err;
- }
-
- if (req_timeout != -1 && rv <= 0) {
- FD_ZERO(&confds);
- openssl_fdset(fd, &confds);
- tv.tv_usec = 0;
- tv.tv_sec = req_timeout;
- rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
- if (rv == 0) {
- BIO_puts(bio_err, "Timeout on connect\n");
- return NULL;
- }
- }
-
- ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
- if (ctx == NULL)
- return NULL;
-
- for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
- CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
- if (add_host == 1 && strcasecmp("host", hdr->name) == 0)
- add_host = 0;
- if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
- goto err;
- }
-
- if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0)
- goto err;
-
- if (!OCSP_REQ_CTX_set1_req(ctx, req))
- goto err;
-
- for (;;) {
- rv = OCSP_sendreq_nbio(&rsp, ctx);
- if (rv != -1)
- break;
- if (req_timeout == -1)
- continue;
- FD_ZERO(&confds);
- openssl_fdset(fd, &confds);
- tv.tv_usec = 0;
- tv.tv_sec = req_timeout;
- if (BIO_should_read(cbio)) {
- rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
- } else if (BIO_should_write(cbio)) {
- rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
- } else {
- BIO_puts(bio_err, "Unexpected retry condition\n");
- goto err;
- }
- if (rv == 0) {
- BIO_puts(bio_err, "Timeout on request\n");
- break;
- }
- if (rv == -1) {
- BIO_puts(bio_err, "Select error\n");
- break;
- }
-
- }
- err:
- OCSP_REQ_CTX_free(ctx);
-
- return rsp;
-}
-
OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
const char *host, const char *path,
const char *port, int use_ssl,
STACK_OF(CONF_VALUE) *headers,
int req_timeout)
{
- BIO *cbio = NULL;
SSL_CTX *ctx = NULL;
OCSP_RESPONSE *resp = NULL;
- cbio = BIO_new_connect(host);
- if (cbio == NULL) {
- BIO_printf(bio_err, "Error creating connect BIO\n");
- goto end;
- }
- if (port != NULL)
- BIO_set_conn_port(cbio, port);
if (use_ssl == 1) {
- BIO *sbio;
ctx = SSL_CTX_new(TLS_client_method());
if (ctx == NULL) {
BIO_printf(bio_err, "Error creating SSL context.\n");
goto end;
}
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
- sbio = BIO_new_ssl(ctx, 1);
- cbio = BIO_push(sbio, cbio);
}
- resp = query_responder(cbio, host, path, headers, req, req_timeout);
+ resp = (OCSP_RESPONSE *)
+ app_http_post_asn1(host, port, path, NULL, NULL /* no proxy used */,
+ ctx, headers, "application/ocsp-request",
+ (ASN1_VALUE *)req, ASN1_ITEM_rptr(OCSP_REQUEST),
+ req_timeout, ASN1_ITEM_rptr(OCSP_RESPONSE));
+
if (resp == NULL)
BIO_printf(bio_err, "Error querying OCSP responder\n");
+
end:
- BIO_free_all(cbio);
SSL_CTX_free(ctx);
return resp;
}
diff --git a/apps/s_client.c b/apps/s_client.c
index 87fb80afb7..cb2af7edde 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -75,7 +75,6 @@ static void print_stuff(BIO *berr, SSL *con, int full);
static int ocsp_resp_cb(SSL *s, void *arg);
#endif
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
-static char *base64encode (const void *buf, size_t len);
static int is_dNS_name(const char *host);
static int saved_errno;
@@ -949,7 +948,7 @@ int s_client_main(int argc, char **argv)
int prexit = 0;
int sdebug = 0;
int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
- int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0;
+ int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0;
int sbuf_len, sbuf_off, cmdletters = 1;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
@@ -2095,16 +2094,16 @@ int s_client_main(int argc, char **argv)
}
re_start:
- if (init_client(&s, host, port, bindhost, bindport, socket_family,
+ if (init_client(&sock, host, port, bindhost, bindport, socket_family,
socket_type, protocol) == 0) {
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
- BIO_closesocket(s);
+ BIO_closesocket(sock);
goto end;
}
- BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
+ BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock);
if (c_nbio) {
- if (!BIO_socket_nbio(s, 1)) {
+ if (!BIO_socket_nbio(sock, 1)) {
ERR_print_errors(bio_err);
goto end;
}
@@ -2116,21 +2115,21 @@ int s_client_main(int argc, char **argv)
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP)
- sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
+ sbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
else
#endif
- sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+ sbio = BIO_new_dgram(sock, BIO_NOCLOSE);
if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "memory allocation failure\n");
- BIO_closesocket(s);
+ BIO_closesocket(sock);
goto end;
}
- if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
+ if (!BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
BIO_printf(bio_err, "getsockname:errno=%d\n",
get_last_socket_error());
BIO_ADDR_free(peer_info.addr);
- BIO_closesocket(s);
+ BIO_closesocket(sock);
goto end;
}
@@ -2167,7 +2166,7 @@ int s_client_main(int argc, char **argv)
}
} else
#endif /* OPENSSL_NO_DTLS */
- sbio = BIO_new_socket(s, BIO_NOCLOSE);
+ sbio = BIO_new_socket(sock, BIO_NOCLOSE);
if (nbio_test) {
BIO *test;
@@ -2398,83 +2397,9 @@ int s_client_main(int argc, char **argv)
}
break;
case PROTO_CONNECT:
- {
- enum {
- error_proto, /* Wrong protocol, not even HTTP */
- error_connect, /* CONNECT failed */
- success
- } foundit = error_connect;
- BIO *fbio = BIO_new(BIO_f_buffer());
-
- BIO_push(fbio, sbio);
- BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n", connectstr);
- /*
- * Workaround for broken proxies which would otherwise close
- * the connection when entering tunnel mode (eg Squid 2.6)
- */
- BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n");
-
- /* Support for basic (base64) proxy authentication */
- if (proxyuser != NULL) {
- size_t l;
- char *proxyauth, *proxyauthenc;
-
- l = strlen(proxyuser);
- if (proxypass != NULL)
- l += strlen(proxypass);
- proxyauth = app_malloc(l + 2, "Proxy auth string");
- BIO_snprintf(proxyauth, l + 2, "%s:%s", proxyuser,
- (proxypass != NULL) ? proxypass : "");
- proxyauthenc = base64encode(proxyauth, strlen(proxyauth));
- BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n",
- proxyauthenc);
- OPENSSL_clear_free(proxyauth, strlen(proxyauth));
- OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
- }
-
- /* Terminate the HTTP CONNECT request */
- BIO_printf(fbio, "\r\n");
- (void)BIO_flush(fbio);
- /*
- * The first line is the HTTP response. According to RFC 7230,
- * it's formatted exactly like this:
- *
- * HTTP/d.d ddd Reason text\r\n
- */
- mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
- if (mbuf_len < (int)strlen("HTTP/1.0 200")) {
- BIO_printf(bio_err,
- "%s: HTTP CONNECT failed, insufficient response "
- "from proxy (got %d octets)\n", prog, mbuf_len);
- (void)BIO_flush(fbio);
- BIO_pop(fbio);
- BIO_free(fbio);
- goto shut;
- }
- if (mbuf[8] != ' ') {
- BIO_printf(bio_err,
- "%s: HTTP CONNECT failed, incorrect response "
- "from proxy\n", prog);
- foundit = error_proto;
- } else if (mbuf[9] != '2') {
- BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog,
- &mbuf[9]);
- } else {
- foundit = success;
- }
- if (foundit != error_proto) {
- /* Read past all following headers */
- do {
- mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
- } while (mbuf_len > 2);
- }
- (void)BIO_flush(fbio);
- BIO_pop(fbio);
- BIO_free(fbio);
- if (foundit != success) {
- goto shut;
- }
- }
+ if (!OSSL_HTTP_proxy_connect(sbio, host, port, proxyuser, proxypass,
+ 0 /* no timeout */, bio_err, prog))
+ goto shut;
break;
case PROTO_IRC:
{
@@ -3192,8 +3117,8 @@ int s_client_main(int argc, char **argv)
timeout.tv_usec = 500000; /* some extreme round-trip */
do {
FD_ZERO(&readfds);
- openssl_fdset(s, &readfds);
- } while (select(s + 1, &readfds, NULL, NULL, &timeout) > 0
+ openssl_fdset(sock, &readfds);
+ } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
BIO_closesocket(SSL_get_fd(con));
@@ -3571,29 +3496,6 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem)
}
/*
- * BASE64 encoder: used only for encoding basic proxy authentication credentials
- */
-static char *base64encode (const void *buf, size_t len)
-{
- int i;
- size_t outl;
- char *out;
-
- /* Calculate size of encoded data */
- outl = (len / 3);
- if (len % 3 > 0)
- outl++;
- outl <<= 2;
- out = app_malloc(outl + 1, "base64 encode buffer");
-
- i = EVP_EncodeBlock((unsigned char *)out, buf, len);
- assert(i <= (int)outl);
- if (i < 0)
- *out = '\0';
- return out;
-}
-
-/*
* Host dNS Name verifier: used for checking that the hostname is in dNS format
* before setting it as SNI
*/
diff --git a/apps/s_server.c b/apps/s_server.c
index c81e572267..69d9e04876 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -526,8 +526,8 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
x = SSL_get_certificate(s);
aia = X509_get1_ocsp(x);
if (aia != NULL) {
- if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
- &host, &port, &path, &use_ssl)) {
+ if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
+ &host, &port, &path, &use_ssl)) {
BIO_puts(bio_err, "cert_status: can't parse AIA URL\n");
goto err;
}
@@ -1387,10 +1387,9 @@ int s_server_main(int argc, char *argv[])
case OPT_STATUS_URL:
#ifndef OPENSSL_NO_OCSP
s_tlsextstatus = 1;
- if (!OCSP_parse_url(opt_arg(),
- &tlscstatp.host,
- &tlscstatp.port,
- &tlscstatp.path, &tlscstatp.use_ssl)) {
+ if (!OSSL_HTTP_parse_url(opt_arg(),
+ &tlscstatp.host, &a