]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
HTTP client: Work around the 'gets' method not being supported by SSL BIOs
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Thu, 18 Nov 2021 19:43:06 +0000 (20:43 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Tue, 21 Dec 2021 12:04:14 +0000 (13:04 +0100)
It turned out that loading non-ASN.1 contents using the HTTP client
fails over TLS because SSL BIOs do not support the gets method.

This PR provides a workaround by using the less efficient BIO_get_line() function
in case BIO_gets() returns -2, which means that it is not supported by the BIO.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17317)

crypto/http/http_client.c

index b4d42f2eb0b9e4e7d5869dca3112ba1fb95040f6..ef0114240b4677026b951b2b334e99a412a50d7e 100644 (file)
@@ -488,7 +488,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
     long n;
     size_t resp_len;
     const unsigned char *p;
-    char *key, *value, *line_end = NULL;
+    char *buf, *key, *value, *line_end = NULL;
 
     if (rctx == NULL) {
         ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
@@ -501,11 +501,20 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
 
     rctx->redirection_url = NULL;
  next_io:
+    buf = (char *)rctx->buf;
     if ((rctx->state & OHS_NOREAD) == 0) {
-        if (rctx->expect_asn1)
+        if (rctx->expect_asn1) {
             n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size);
-        else
-            n = BIO_gets(rctx->rbio, (char *)rctx->buf, rctx->buf_size);
+        } else {
+            (void)ERR_set_mark();
+            n = BIO_gets(rctx->rbio, buf, rctx->buf_size);
+            if (n == -2) { /* some BIOs, such as SSL, do not support "gets" */
+                (void)ERR_pop_to_mark();
+                n = BIO_get_line(rctx->rbio, buf, rctx->buf_size);
+            } else {
+                (void)ERR_clear_last_mark();
+            }
+        }
         if (n <= 0) {
             if (BIO_should_retry(rctx->rbio))
                 return -1;
@@ -606,7 +615,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
             }
             goto next_io;
         }
-        n = BIO_gets(rctx->mem, (char *)rctx->buf, rctx->buf_size);
+        n = BIO_gets(rctx->mem, buf, rctx->buf_size);
 
         if (n <= 0) {
             if (BIO_should_retry(rctx->mem))
@@ -624,7 +633,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->buf, &found_keep_alive)) {
+            switch (parse_http_line1(buf, &found_keep_alive)) {
             case HTTP_STATUS_CODE_OK:
                 rctx->state = OHS_HEADERS;
                 goto next_line;
@@ -642,7 +651,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
                 goto next_line;
             }
         }
-        key = (char *)rctx->buf;
+        key = buf;
         value = strchr(key, ':');
         if (value != NULL) {
             *(value++) = '\0';