[openssl] master update
dev at ddvo.net
dev at ddvo.net
Tue Feb 2 06:55:33 UTC 2021
The branch master has been updated
via 6aab42c39060c7aa39d96c7a265ddc661cea2ed8 (commit)
via 4d190f99ef1b6fa8c49ca1fd9bda872e5f51ec93 (commit)
via a6d40689ecfb5246c67feee3b8aa5698bb062e90 (commit)
via d337af18919a5c24c6f1d0ceb9fdb7aaf1beaef4 (commit)
via 8e716147971971beb9ce747c74822abd24c6be13 (commit)
via 673474b1640a0265530ad42868d1c8b7d33bef77 (commit)
from f2db0528d8d7015ba39faca78a16e5e820db9df6 (commit)
- Log -----------------------------------------------------------------
commit 6aab42c39060c7aa39d96c7a265ddc661cea2ed8
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Jan 25 20:44:39 2021 +0100
OSSL_HTTP_REQ_CTX.pod and OSSL_HTTP_transfer.pod: various improvements
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
commit 4d190f99ef1b6fa8c49ca1fd9bda872e5f51ec93
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Fri Jan 29 19:08:45 2021 +0100
Constify OSSL_HTTP_REQ_CTX_get0_mem_bio()
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
commit a6d40689ecfb5246c67feee3b8aa5698bb062e90
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Jan 25 22:54:17 2021 +0100
HTTP: add more error detection to low-level API
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
commit d337af18919a5c24c6f1d0ceb9fdb7aaf1beaef4
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Jan 25 19:49:58 2021 +0100
HTTP: Fix mistakes and unclarities on maxline and max_resp_len params
Also rename internal structure fields iobuf(len) to readbuf(len) for clarity
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
commit 8e716147971971beb9ce747c74822abd24c6be13
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Jan 25 19:25:18 2021 +0100
Fix not backwards-compat X509_http_nbio() and X509_CRL_http_nbio()
Provides partial fix of #13127.
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
commit 673474b1640a0265530ad42868d1c8b7d33bef77
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date: Mon Jan 25 16:18:40 2021 +0100
OSSL_HTTP_REQ_CTX_nbio(): Revert to having state var that keeps req len still to send
Otherwise, sending goes wrong in case BIO_write(rctx->wbio, ...) is incomplete at first.
Fixes #13938
Reviewed-by: Paul Dale <pauli at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13960)
-----------------------------------------------------------------------
Summary of changes:
crypto/err/openssl.txt | 1 +
crypto/http/http_client.c | 82 +++++++++++++++++++++++------------------
crypto/http/http_err.c | 2 +
doc/man3/OSSL_HTTP_REQ_CTX.pod | 47 ++++++++++++++---------
doc/man3/OSSL_HTTP_transfer.pod | 13 ++++---
doc/man3/X509_load_http.pod | 4 +-
include/openssl/http.h | 5 ++-
include/openssl/httperr.h | 1 +
include/openssl/x509.h.in | 8 +++-
9 files changed, 100 insertions(+), 63 deletions(-)
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 8418463fc7..9bc59a4bfb 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2641,6 +2641,7 @@ HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length
HTTP_R_ERROR_PARSING_URL:101:error parsing url
HTTP_R_ERROR_RECEIVING:103:error receiving
HTTP_R_ERROR_SENDING:102:error sending
+HTTP_R_FAILED_READING_DATA:128:failed reading data
HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length
HTTP_R_INVALID_PORT_NUMBER:123:invalid port number
HTTP_R_INVALID_URL_PATH:125:invalid url path
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index 6b627e15b0..56fb876ee6 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -42,23 +42,21 @@
struct ossl_http_req_ctx_st {
int state; /* Current I/O state */
- unsigned char *iobuf; /* Line buffer */
- int iobuflen; /* Line buffer length */
+ unsigned char *readbuf; /* Buffer for reading response by line */
+ int readbuflen; /* Buffer length, equals maxline */
BIO *wbio; /* BIO to send request to */
BIO *rbio; /* BIO to read response from */
BIO *mem; /* Memory BIO response is built into */
int method_POST; /* HTTP method is "POST" (else "GET") */
const char *expected_ct; /* expected Content-Type, or NULL */
int expect_asn1; /* response must be ASN.1-encoded */
+ long len_to_send; /* number of bytes in request still to send */
unsigned long resp_len; /* length of response */
unsigned long max_resp_len; /* Maximum length of response */
time_t max_time; /* Maximum end time of the transfer, or 0 */
char *redirection_url; /* Location given with HTTP status 301/302 */
};
-#define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024)
-#define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024)
-
/* HTTP states */
#define OHS_NOREAD 0x1000 /* If set no reading should be performed */
@@ -68,7 +66,7 @@ struct ossl_http_req_ctx_st {
#define OHS_HEADERS 2 /* MIME headers being read */
#define OHS_ASN1_HEADER 3 /* HTTP initial header (tag+length) being read */
#define OHS_CONTENT 4 /* HTTP content octets being read */
-#define OHS_WRITE_INIT (5 | OHS_NOREAD) /* 1st call: ready to start I/O */
+#define OHS_WRITE_INIT (5 | OHS_NOREAD) /* 1st call: ready to start send */
#define OHS_WRITE (6 | OHS_NOREAD) /* Request being sent */
#define OHS_FLUSH (7 | OHS_NOREAD) /* Request being flushed */
#define OHS_DONE (8 | OHS_NOREAD) /* Completed */
@@ -91,13 +89,12 @@ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio,
if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
return NULL;
rctx->state = OHS_ERROR;
- rctx->iobuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
- rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+ rctx->readbuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
+ rctx->readbuf = OPENSSL_malloc(rctx->readbuflen);
rctx->wbio = wbio;
rctx->rbio = rbio;
- rctx->mem = BIO_new(BIO_s_mem());
- if (rctx->iobuf == NULL || rctx->mem == NULL) {
- OSSL_HTTP_REQ_CTX_free(rctx);
+ if (rctx->readbuf == NULL) {
+ OPENSSL_free(rctx);
return NULL;
}
rctx->method_POST = method_POST;
@@ -106,6 +103,7 @@ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio,
rctx->resp_len = 0;
OSSL_HTTP_REQ_CTX_set_max_response_length(rctx, max_resp_len);
rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0;
+ /* everything else is 0, e.g. rctx->len_to_send, or NULL, e.g. rctx->mem */
return rctx;
}
@@ -114,11 +112,11 @@ void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
if (rctx == NULL)
return;
BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */
- OPENSSL_free(rctx->iobuf);
+ OPENSSL_free(rctx->readbuf);
OPENSSL_free(rctx);
}
-BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx)
+BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx)
{
if (rctx == NULL) {
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
@@ -149,6 +147,9 @@ int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx,
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+ BIO_free(rctx->mem);
+ if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL)
+ return 0;
if (BIO_printf(rctx->mem, "%s ", rctx->method_POST ? "POST" : "GET") <= 0)
return 0;
@@ -183,6 +184,10 @@ int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+ if (rctx->mem == NULL) {
+ ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
if (BIO_puts(rctx->mem, name) <= 0)
return 0;
@@ -198,8 +203,8 @@ int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
return 1;
}
-static int OSSL_HTTP_REQ_CTX_content(OSSL_HTTP_REQ_CTX *rctx,
- const char *content_type, BIO *req_mem)
+static int OSSL_HTTP_REQ_CTX_set_content(OSSL_HTTP_REQ_CTX *rctx,
+ const char *content_type, BIO *req_mem)
{
const unsigned char *req;
long req_len;
@@ -208,7 +213,7 @@ static int OSSL_HTTP_REQ_CTX_content(OSSL_HTTP_REQ_CTX *rctx,
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if (!rctx->method_POST) {
+ if (rctx->mem == NULL || !rctx->method_POST) {
ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -255,7 +260,7 @@ int OSSL_HTTP_REQ_CTX_i2d(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
}
res = (mem = HTTP_asn1_item2bio(it, req)) != NULL
- && OSSL_HTTP_REQ_CTX_content(rctx, content_type, mem);
+ && OSSL_HTTP_REQ_CTX_set_content(rctx, content_type, mem);
BIO_free(mem);
return res;
}
@@ -315,7 +320,7 @@ OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy,
path)
&& OSSL_HTTP_REQ_CTX_add1_headers(rctx, headers, server)
&& (req_mem == NULL
- || OSSL_HTTP_REQ_CTX_content(rctx, content_type, req_mem)))
+ || OSSL_HTTP_REQ_CTX_set_content(rctx, content_type, req_mem)))
return rctx;
OSSL_HTTP_REQ_CTX_free(rctx);
@@ -408,7 +413,8 @@ static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, unsigned long len)
"length=%lu, max=%lu", len, rctx->max_resp_len);
if (rctx->resp_len != 0 && rctx->resp_len != len)
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH,
- "length=%lu, before=%lu", len, rctx->resp_len);
+ "ASN.1 length=%lu, Content-Length=%lu",
+ len, rctx->resp_len);
rctx->resp_len = len;
return 1;
}
@@ -420,7 +426,7 @@ static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, unsigned long len)
int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
{
int i;
- long n, n_to_send = 0;
+ long n;
unsigned long resp_len;
const unsigned char *p;
char *key, *value, *line_end = NULL;
@@ -429,19 +435,24 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
+ if (rctx->mem == NULL || rctx->wbio == NULL || rctx->rbio == NULL) {
+ ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
rctx->redirection_url = NULL;
next_io:
if ((rctx->state & OHS_NOREAD) == 0) {
- n = BIO_read(rctx->rbio, rctx->iobuf, rctx->iobuflen);
+ n = BIO_read(rctx->rbio, rctx->readbuf, rctx->readbuflen);
if (n <= 0) {
if (BIO_should_retry(rctx->rbio))
return -1;
+ ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA);
return 0;
}
/* Write data to memory BIO */
- if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+ if (BIO_write(rctx->mem, rctx->readbuf, n) != n)
return 0;
}
@@ -456,14 +467,13 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
/* fall thru */
case OHS_WRITE_INIT:
- n_to_send = BIO_get_mem_data(rctx->mem, NULL);
+ rctx->len_to_send = BIO_get_mem_data(rctx->mem, NULL);
rctx->state = OHS_WRITE;
/* fall thru */
case OHS_WRITE:
- n = BIO_get_mem_data(rctx->mem, &p);
-
- i = BIO_write(rctx->wbio, p + (n - n_to_send), n_to_send);
+ n = BIO_get_mem_data(rctx->mem, &p) - rctx->len_to_send;
+ i = BIO_write(rctx->wbio, p + n, rctx->len_to_send);
if (i <= 0) {
if (BIO_should_retry(rctx->wbio))
@@ -472,9 +482,9 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
return 0;
}
- n_to_send -= i;
+ rctx->len_to_send -= i;
- if (n_to_send > 0)
+ if (rctx->len_to_send > 0)
goto next_io;
rctx->state = OHS_FLUSH;
@@ -513,13 +523,13 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
*/
n = BIO_get_mem_data(rctx->mem, &p);
if (n <= 0 || memchr(p, '\n', n) == 0) {
- if (n >= rctx->iobuflen) {
+ if (n >= rctx->readbuflen) {
rctx->state = OHS_ERROR;
return 0;
}
goto next_io;
}
- n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+ n = BIO_gets(rctx->mem, (char *)rctx->readbuf, rctx->readbuflen);
if (n <= 0) {
if (BIO_should_retry(rctx->mem))
@@ -529,7 +539,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
}
/* Don't allow excessive lines */
- if (n == rctx->iobuflen) {
+ if (n == rctx->readbuflen) {
ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG);
rctx->state = OHS_ERROR;
return 0;
@@ -537,7 +547,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
/* First line */
if (rctx->state == OHS_FIRSTLINE) {
- switch (parse_http_line1((char *)rctx->iobuf)) {
+ switch (parse_http_line1((char *)rctx->readbuf)) {
case HTTP_STATUS_CODE_OK:
rctx->state = OHS_HEADERS;
goto next_line;
@@ -555,7 +565,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
return 0;
}
}
- key = (char *)rctx->iobuf;
+ key = (char *)rctx->readbuf;
value = strchr(key, ':');
if (value != NULL) {
*(value++) = '\0';
@@ -596,8 +606,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
}
}
- /* Look for blank line: end of headers */
- for (p = rctx->iobuf; *p != '\0'; p++) {
+ /* Look for blank line indicating end of headers */
+ for (p = rctx->readbuf; *p != '\0'; p++) {
if (*p != '\r' && *p != '\n')
break;
}
@@ -1177,7 +1187,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc);
OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
}
- proxy_end:
+ proxy_end:
OPENSSL_clear_free(proxyauth, len);
if (proxyauthenc == NULL)
goto end;
diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c
index ec46fb9304..49e56bedbf 100644
--- a/crypto/http/http_err.c
+++ b/crypto/http/http_err.c
@@ -25,6 +25,8 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_URL), "error parsing url"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_RECEIVING), "error receiving"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending"},
+ {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_FAILED_READING_DATA),
+ "failed reading data"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH),
"inconsistent content length"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER),
diff --git a/doc/man3/OSSL_HTTP_REQ_CTX.pod b/doc/man3/OSSL_HTTP_REQ_CTX.pod
index 3955359978..0b730b4e17 100644
--- a/doc/man3/OSSL_HTTP_REQ_CTX.pod
+++ b/doc/man3/OSSL_HTTP_REQ_CTX.pod
@@ -40,7 +40,7 @@ OSSL_HTTP_REQ_CTX_set_max_response_length
ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx,
const ASN1_ITEM *it);
- BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx);
+ BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx);
void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
unsigned long len);
@@ -56,10 +56,13 @@ should be preferred.
OSSL_HTTP_REQ_CTX_new() allocates a new HTTP request context structure,
which gets populated with the B<BIO> to send the request to (I<wbio>),
the B<BIO> to read the response from (I<rbio>, which may be equal to I<wbio>),
+the maximum expected response header line length (I<maxline>, where a value <= 0
+indicates that the B<HTTP_DEFAULT_MAX_LINE_LENGTH> of 4KiB should be used;
+this length is also used as the number of content bytes read at a time),
the request method (I<method_POST>, which may be 1 to indicate that the C<POST>
method is to be used, or 0 to indicate that the C<GET> method is to be used),
-the maximum expected response header length (I<max_resp_len>,
-where any zero or less indicates the default of 4KiB),
+the maximum allowed response content length (I<max_resp_len>, where 0 means
+that the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB),
a response timeout measure in seconds (I<timeout>,
where 0 indicates no timeout, i.e., waiting indefinitely),
the expected MIME content type of the response (I<expected_content_type>,
@@ -87,31 +90,38 @@ For example, to add a C<Host> header for C<example.com> you would call:
OSSL_HTTP_REQ_CTX_add1_header(ctx, "Host", "example.com");
-OSSL_HTTP_REQ_CTX_i2d() finalizes the HTTP request context by adding the DER
-encoding of I<req>, using the ASN.1 template I<it> to do the encoding. The
-HTTP header C<Content-Length> is automatically filled out, and if
+OSSL_HTTP_REQ_CTX_i2d() finalizes the HTTP request context by adding
+the DER encoding of I<req>, using the ASN.1 template I<it> to do the encoding.
+The HTTP header C<Content-Length> is automatically filled out, and if
I<content_type> isn't NULL, the HTTP header C<Content-Type> is also added with
its content as value. All of this ends up in the internal memory B<BIO>.
This requires that I<method_POST> was 1 in the OSSL_HTTP_REQ_CTX_new() call.
-OSSL_HTTP_REQ_CTX_nbio() attempts the exchange of request and response via HTTP,
-using the I<rbio> and I<wbio> that were given in the OSSL_HTTP_REQ_CTX_new()
-call. When successful, the contents of the internal memory B<BIO> is replaced
-with the contents of the HTTP response, without the response headers.
+OSSL_HTTP_REQ_CTX_nbio() attempts to send the request prepared I<rctx>
+and gathering the response via HTTP, using the I<rbio> and I<wbio>
+that were given when calling OSSL_HTTP_REQ_CTX_new().
+When successful, the contents of the internal memory B<BIO> contains
+the contents of the HTTP response, without the response headers.
It may need to be called again if its result is -1, which indicates
L<BIO_should_retry(3)>. In such a case it is advisable to sleep a little in
-between to prevent a busy loop.
+between using L<BIO_wait(3)> on the read BIO to prevent a busy loop.
OSSL_HTTP_REQ_CTX_sendreq_d2i() calls OSSL_HTTP_REQ_CTX_nbio(), possibly
several times until a timeout is reached, and DER decodes the received
response using the ASN.1 template I<it>.
-OSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum response length
-for I<rctx> to I<len>. If the response exceeds this length an error occurs.
-If not set a default value of 100k is used.
-
-OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>. This can
-be used to affect the HTTP request text. I<Use with caution!>
+OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>.
+Before sending the request, this could used to modify the HTTP request text.
+I<Use with caution!>
+After receiving a response via HTTP, the BIO represents
+the current state of reading the response headers and contents.
+
+OSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum allowed
+response content length for I<rctx> to I<len>. If not set or I<len> is 0
+then the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB.
+If the C<Content-Length> header is present and exceeds this value or
+the content is an ASN.1 encoded structure with a length exceeding this value
+or both length indications are present but disagree then an error occurs.
=head1 WARNINGS
@@ -167,6 +177,9 @@ OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>.
=head1 SEE ALSO
+L<BIO_should_retry(3)>,
+L<BIO_wait(3)>,
+L<OSSL_HTTP_get(3)>,
L<OSSL_HTTP_transfer(3)>
=head1 COPYRIGHT
diff --git a/doc/man3/OSSL_HTTP_transfer.pod b/doc/man3/OSSL_HTTP_transfer.pod
index dda59201cf..cb38d0124f 100644
--- a/doc/man3/OSSL_HTTP_transfer.pod
+++ b/doc/man3/OSSL_HTTP_transfer.pod
@@ -123,9 +123,11 @@ while using a proxy for HTTPS connections requires a suitable callback function
such as OSSL_HTTP_proxy_connect(), described below.
The I<maxline> parameter specifies the response header maximum line length,
-where 0 indicates the default value, which currently is 4k.
+where a value <= 0 indicates that the B<HTTP_DEFAULT_MAX_LINE_LENGTH> of 4KiB
+should be used.
+This length is also used as the number of content bytes that are read at a time.
The I<max_resp_len> parameter specifies the maximum response length,
-where 0 indicates the default value, which currently is 100k.
+where 0 indicates B<HTTP_DEFAULT_MAX_RESP_LEN>, which currently is 100 KiB.
An ASN.1-encoded response is expected by OSSL_HTTP_get_asn1() and
OSSL_HTTP_post_asn1(), while for OSSL_HTTP_get() or OSSL_HTTP_transfer()
@@ -217,9 +219,10 @@ other HTTP client implementations such as wget, curl, and git.
=head1 RETURN VALUES
-OSSL_HTTP_get(), OSSL_HTTP_get_asn1(), OSSL_HTTP_post_asn1(), and
-OSSL_HTTP_transfer() return on success the data received via HTTP, else NULL.
-Error conditions include connection/transfer timeout, parse errors, etc.
+On success, OSSL_HTTP_get(), OSSL_HTTP_get_asn1(), OSSL_HTTP_post_asn1(), and
+OSSL_HTTP_transfer() return a memory BIO containing the data received via HTTP.
+This must be freed by the caller. On failure, NULL is returned.
+Failure conditions include connection/transfer timeout, parse errors, etc.
OSSL_HTTP_proxy_connect() and OSSL_HTTP_parse_url()
return 1 on success, 0 on error.
diff --git a/doc/man3/X509_load_http.pod b/doc/man3/X509_load_http.pod
index 483597b5b8..47a0e74760 100644
--- a/doc/man3/X509_load_http.pod
+++ b/doc/man3/X509_load_http.pod
@@ -15,8 +15,8 @@ X509_CRL_http_nbio
X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
- #define X509_http_nbio(url)
- #define X509_CRL_http_nbio(url)
+ #define X509_http_nbio(rctx, pcert)
+ #define X509_CRL_http_nbio(rctx, pcrl)
=head1 DESCRIPTION
diff --git a/include/openssl/http.h b/include/openssl/http.h
index b35302289f..6c3ddd8ce8 100644
--- a/include/openssl/http.h
+++ b/include/openssl/http.h
@@ -35,6 +35,9 @@ typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail)
# define OPENSSL_HTTP_PROXY "HTTP_PROXY"
# define OPENSSL_HTTPS_PROXY "HTTPS_PROXY"
+#define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024)
+#define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024)
+
OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio,
int method_GET, int maxline,
unsigned long max_resp_len,
@@ -52,7 +55,7 @@ int OSSL_HTTP_REQ_CTX_i2d(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx);
ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx,
const ASN1_ITEM *it);
-BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx);
+BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx);
void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
unsigned long len);
diff --git a/include/openssl/httperr.h b/include/openssl/httperr.h
index 4bf52bacb9..716feac39b 100644
--- a/include/openssl/httperr.h
+++ b/include/openssl/httperr.h
@@ -34,6 +34,7 @@
# define HTTP_R_ERROR_PARSING_URL 101
# define HTTP_R_ERROR_RECEIVING 103
# define HTTP_R_ERROR_SENDING 102
+# define HTTP_R_FAILED_READING_DATA 128
# define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120
# define HTTP_R_INVALID_PORT_NUMBER 123
# define HTTP_R_INVALID_URL_PATH 125
diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in
index bb22abef6b..8a3cb2e4d0 100644
--- a/include/openssl/x509.h.in
+++ b/include/openssl/x509.h.in
@@ -403,9 +403,13 @@ int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
unsigned char *md, unsigned int *len);
X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
-# define X509_http_nbio(url) X509_load_http(url, NULL, NULL, 0)
+# define X509_http_nbio(rctx, pcert) \
+ OSSL_HTTP_REQ_CTX_sendreq_d2i(rctx, (ASN1_VALUE **)(pcert), \
+ ASN1_ITEM_rptr(X509))
X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout);
-# define X509_CRL_http_nbio(url) X509_CRL_load_http(url, NULL, NULL, 0)
+# define X509_CRL_http_nbio(rctx, pcrl) \
+ OSSL_HTTP_REQ_CTX_sendreq_d2i(rctx, (ASN1_VALUE **)(pcrl), \
+ ASN1_ITEM_rptr(X509_CRL))
# ifndef OPENSSL_NO_STDIO
X509 *d2i_X509_fp(FILE *fp, X509 **x509);
More information about the openssl-commits
mailing list