From: Dr. David von Oheimb Date: Mon, 25 Jan 2021 21:54:17 +0000 (+0100) Subject: HTTP: add more error detection to low-level API X-Git-Tag: openssl-3.0.0-alpha12~168 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6d40689ecfb5246c67feee3b8aa5698bb062e90;p=thirdparty%2Fopenssl.git HTTP: add more error detection to low-level API Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/13960) --- diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 8418463fc70..9bc59a4bfb7 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 6e75725f072..f1db8fea425 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -93,9 +93,8 @@ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, rctx->readbuf = OPENSSL_malloc(rctx->readbuflen); rctx->wbio = wbio; rctx->rbio = rbio; - rctx->mem = BIO_new(BIO_s_mem()); - if (rctx->readbuf == NULL || rctx->mem == NULL) { - OSSL_HTTP_REQ_CTX_free(rctx); + if (rctx->readbuf == NULL) { + OPENSSL_free(rctx); return NULL; } rctx->method_POST = method_POST; @@ -104,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; } @@ -147,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; @@ -181,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; @@ -196,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; @@ -206,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; } @@ -253,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; } @@ -313,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); @@ -428,6 +435,10 @@ 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: @@ -436,6 +447,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) if (n <= 0) { if (BIO_should_retry(rctx->rbio)) return -1; + ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA); return 0; } @@ -1175,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 ec46fb93047..49e56bedbfc 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/include/openssl/httperr.h b/include/openssl/httperr.h index 4bf52bacb9a..716feac39b5 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