[openssl] master update

2021-12-22 Thread Dr . Paul Dale
The branch master has been updated
   via  2080da84a49b0c52fc8c6e6caef5d373235bd3e4 (commit)
  from  7c78bd4be810ddceb8f13585a921946cc98f5fbd (commit)


- Log -
commit 2080da84a49b0c52fc8c6e6caef5d373235bd3e4
Author: Michael Baentsch 
Date:   Mon Dec 20 11:01:00 2021 +0100

improving tests for adding sigalg with empty digest

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17315)

---

Summary of changes:
 test/upcallstest.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/test/upcallstest.c b/test/upcallstest.c
index 76899fee3d..c4ef714713 100644
--- a/test/upcallstest.c
+++ b/test/upcallstest.c
@@ -71,11 +71,12 @@ static int obj_provider_init(const OSSL_CORE_HANDLE *handle,
 /* additional tests checking empty digest algs are accepted, too */
 if (!c_obj_add_sigid(handle, SIGALG_OID, "", SIG_LN))
 return 0;
-if (!c_obj_add_sigid(handle, SIGALG_OID, NULL, SIG_LN))
-return 0;
 /* checking wrong digest alg name is rejected: */
 if (c_obj_add_sigid(handle, SIGALG_OID, "NonsenseAlg", SIG_LN))
 return 0;
+/* Testing actual triplet addition under separate sig alg */
+if (!c_obj_add_sigid(handle, SIG_OID, NULL, SIG_LN))
+return 0;
 
 return 1;
 }
@@ -105,6 +106,14 @@ static int obj_create_test(void)
 || !TEST_int_eq(signid, OBJ_ln2nid(SIG_LN)))
 goto err;
 
+/* Check empty digest alg storage capability */
+sigalgnid = OBJ_txt2nid(SIG_OID);
+if (!TEST_int_ne(sigalgnid, NID_undef)
+|| !TEST_true(OBJ_find_sigid_algs(sigalgnid, , ))
+|| !TEST_int_eq(digestnid, NID_undef)
+|| !TEST_int_ne(signid, NID_undef))
+goto err;
+
 testresult = 1;
  err:
 OSSL_PROVIDER_unload(objprov);


[openssl] openssl-3.0 update

2021-12-22 Thread Dr . Paul Dale
The branch openssl-3.0 has been updated
   via  a9c02a552153eabfb5a1a01ecdeb03e7b2920f4b (commit)
  from  317bedd656e76b1162a6b29ed19a78303f362a78 (commit)


- Log -
commit a9c02a552153eabfb5a1a01ecdeb03e7b2920f4b
Author: Kan 
Date:   Fri Dec 17 00:35:32 2021 +0800

Add static check in BN_hex2bn

Fixes #17298

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17299)

(cherry picked from commit 7c78bd4be810ddceb8f13585a921946cc98f5fbd)

---

Summary of changes:
 crypto/bn/bn_conv.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/crypto/bn/bn_conv.c b/crypto/bn/bn_conv.c
index 6757f3d0aa..75054f5d6a 100644
--- a/crypto/bn/bn_conv.c
+++ b/crypto/bn/bn_conv.c
@@ -154,6 +154,10 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
 return 0;
 } else {
 ret = *bn;
+if (BN_get_flags(ret, BN_FLG_STATIC_DATA)) {
+ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+return 0;
+}
 BN_zero(ret);
 }
 


[openssl] master update

2021-12-22 Thread Dr . Paul Dale
The branch master has been updated
   via  7c78bd4be810ddceb8f13585a921946cc98f5fbd (commit)
  from  a595e3286ae9f033c56452967b3add2145f9085f (commit)


- Log -
commit 7c78bd4be810ddceb8f13585a921946cc98f5fbd
Author: Kan 
Date:   Fri Dec 17 00:35:32 2021 +0800

Add static check in BN_hex2bn

Fixes #17298

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17299)

---

Summary of changes:
 crypto/bn/bn_conv.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/crypto/bn/bn_conv.c b/crypto/bn/bn_conv.c
index 6757f3d0aa..75054f5d6a 100644
--- a/crypto/bn/bn_conv.c
+++ b/crypto/bn/bn_conv.c
@@ -154,6 +154,10 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
 return 0;
 } else {
 ret = *bn;
+if (BN_get_flags(ret, BN_FLG_STATIC_DATA)) {
+ERR_raise(ERR_LIB_BN, ERR_R_PASSED_INVALID_ARGUMENT);
+return 0;
+}
 BN_zero(ret);
 }
 


[openssl] OpenSSL_1_1_1-stable update

2021-12-22 Thread Dr . Paul Dale
The branch OpenSSL_1_1_1-stable has been updated
   via  8a5dbc182d85eeb5778dcfd17cab945f7061c5ef (commit)
  from  f2f7cff20377f7402b132a19d953a9d998be26aa (commit)


- Log -
commit 8a5dbc182d85eeb5778dcfd17cab945f7061c5ef
Author: Alexandros Roussos 
Date:   Mon Dec 20 19:14:57 2021 +0100

Fix Configure variable spill

* Evaluating code-refs in Configure can sometimes set the default
variable `$_`
* Prevent spillage influencing the target property by using named
variable in loop

CLA: trivial

Fixes gh-17321

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17322)

(cherry picked from commit a595e3286ae9f033c56452967b3add2145f9085f)

---

Summary of changes:
 Configure | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/Configure b/Configure
index faf57b155a..4bea49d7da 100755
--- a/Configure
+++ b/Configure
@@ -3161,25 +3161,25 @@ sub resolve_config {
 }
 }
 
-foreach (sort keys %all_keys) {
-my $previous = $combined_inheritance{$_};
+foreach my $key (sort keys %all_keys) {
+my $previous = $combined_inheritance{$key};
 
 # Current target doesn't have a value for the current key?
 # Assign it the default combiner, the rest of this loop body
 # will handle it just like any other coderef.
-if (!exists $table{$target}->{$_}) {
-$table{$target}->{$_} = $default_combiner;
+if (!exists $table{$target}->{$key}) {
+$table{$target}->{$key} = $default_combiner;
 }
 
-$table{$target}->{$_} = process_values($table{$target}->{$_},
-   $combined_inheritance{$_},
-   $target, $_);
-unless(defined($table{$target}->{$_})) {
-delete $table{$target}->{$_};
+$table{$target}->{$key} = process_values($table{$target}->{$key},
+   $combined_inheritance{$key},
+   $target, $key);
+unless(defined($table{$target}->{$key})) {
+delete $table{$target}->{$key};
 }
 #if ($extra_checks &&
-#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$_})) {
-#warn "$_ got replaced in $target\n";
+#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$key})) {
+#warn "$key got replaced in $target\n";
 #}
 }
 


[openssl] openssl-3.0 update

2021-12-22 Thread Dr . Paul Dale
The branch openssl-3.0 has been updated
   via  317bedd656e76b1162a6b29ed19a78303f362a78 (commit)
  from  ceeb92f7b52fbbb349cca8d9560a0708d948936a (commit)


- Log -
commit 317bedd656e76b1162a6b29ed19a78303f362a78
Author: Alexandros Roussos 
Date:   Mon Dec 20 19:14:57 2021 +0100

Fix Configure variable spill

* Evaluating code-refs in Configure can sometimes set the default
variable `$_`
* Prevent spillage influencing the target property by using named
variable in loop

CLA: trivial

Fixes gh-17321

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17322)

(cherry picked from commit a595e3286ae9f033c56452967b3add2145f9085f)

---

Summary of changes:
 Configure | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/Configure b/Configure
index b00b91ac63..df7232d551 100755
--- a/Configure
+++ b/Configure
@@ -3169,25 +3169,25 @@ sub resolve_config {
 }
 }
 
-foreach (sort keys %all_keys) {
-my $previous = $combined_inheritance{$_};
+foreach my $key (sort keys %all_keys) {
+my $previous = $combined_inheritance{$key};
 
 # Current target doesn't have a value for the current key?
 # Assign it the default combiner, the rest of this loop body
 # will handle it just like any other coderef.
-if (!exists $table{$target}->{$_}) {
-$table{$target}->{$_} = $default_combiner;
+if (!exists $table{$target}->{$key}) {
+$table{$target}->{$key} = $default_combiner;
 }
 
-$table{$target}->{$_} = process_values($table{$target}->{$_},
-   $combined_inheritance{$_},
-   $target, $_);
-unless(defined($table{$target}->{$_})) {
-delete $table{$target}->{$_};
+$table{$target}->{$key} = process_values($table{$target}->{$key},
+   $combined_inheritance{$key},
+   $target, $key);
+unless(defined($table{$target}->{$key})) {
+delete $table{$target}->{$key};
 }
 #if ($extra_checks &&
-#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$_})) {
-#warn "$_ got replaced in $target\n";
+#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$key})) {
+#warn "$key got replaced in $target\n";
 #}
 }
 


[openssl] master update

2021-12-22 Thread Dr . Paul Dale
The branch master has been updated
   via  a595e3286ae9f033c56452967b3add2145f9085f (commit)
  from  7a85dd46e0b2f67b341c777509f0126e3252938d (commit)


- Log -
commit a595e3286ae9f033c56452967b3add2145f9085f
Author: Alexandros Roussos 
Date:   Mon Dec 20 19:14:57 2021 +0100

Fix Configure variable spill

* Evaluating code-refs in Configure can sometimes set the default
variable `$_`
* Prevent spillage influencing the target property by using named
variable in loop

CLA: trivial

Fixes gh-17321

Reviewed-by: Tomas Mraz 
Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17322)

---

Summary of changes:
 Configure | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/Configure b/Configure
index f48b7ab075..bf6c568a4c 100755
--- a/Configure
+++ b/Configure
@@ -3169,25 +3169,25 @@ sub resolve_config {
 }
 }
 
-foreach (sort keys %all_keys) {
-my $previous = $combined_inheritance{$_};
+foreach my $key (sort keys %all_keys) {
+my $previous = $combined_inheritance{$key};
 
 # Current target doesn't have a value for the current key?
 # Assign it the default combiner, the rest of this loop body
 # will handle it just like any other coderef.
-if (!exists $table{$target}->{$_}) {
-$table{$target}->{$_} = $default_combiner;
+if (!exists $table{$target}->{$key}) {
+$table{$target}->{$key} = $default_combiner;
 }
 
-$table{$target}->{$_} = process_values($table{$target}->{$_},
-   $combined_inheritance{$_},
-   $target, $_);
-unless(defined($table{$target}->{$_})) {
-delete $table{$target}->{$_};
+$table{$target}->{$key} = process_values($table{$target}->{$key},
+   $combined_inheritance{$key},
+   $target, $key);
+unless(defined($table{$target}->{$key})) {
+delete $table{$target}->{$key};
 }
 #if ($extra_checks &&
-#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$_})) {
-#warn "$_ got replaced in $target\n";
+#$previous && !($add_called ||  $previous ~~ 
$table{$target}->{$key})) {
+#warn "$key got replaced in $target\n";
 #}
 }
 


Coverity Scan: Analysis completed for openssl/openssl

2021-12-22 Thread scan-admin


Your request for analysis of openssl/openssl has been completed 
successfully.
The results are available at 
https://u15810271.ct.sendgrid.net/ls/click?upn=HRESupC-2F2Czv4BOaCWWCy7my0P0qcxCbhZ31OYv50yoN-2BQSVjTtaSz8wS4wOr7HlekBtV1P4YRtWclMVkCdvAA-3D-3D4qYN_MulOTlHne1IxTRELXXnGni8d68xSVF-2BUCe3a7Ux-2BjeE7JdX8mOCoTlBmOzfOsrNUGn0i-2BubSXQ8yIEsMxFcs9-2BrAcd5p2ALLDj-2FdY3CTdDonwXvKaLxKQrt-2B2gQkEzRxSK1hCKjnp7bcqEgqI6TLeJAzoL-2BT8Anp0dE-2FVjsIwCSSx8LZITVhkI590j9ACzLFpPTzF-2BxtY1hdhncwu2UiLKWcyNFKDgf2fJdAegSrFZQ-3D

Build ID: 425131

Analysis Summary:
   New defects found: 0
   Defects eliminated: 0



[openssl] openssl-3.0 update

2021-12-22 Thread Dr . Paul Dale
The branch openssl-3.0 has been updated
   via  ceeb92f7b52fbbb349cca8d9560a0708d948936a (commit)
  from  e0314df5f21dd537602d4ea8d9272a21aac66356 (commit)


- Log -
commit ceeb92f7b52fbbb349cca8d9560a0708d948936a
Author: Pauli 
Date:   Tue Dec 21 10:17:04 2021 +1100

namemap: handle a NULL return when looking for a non-legacy cipher/MD

Fixes #17313

Reviewed-by: Tomas Mraz 
(Merged from https://github.com/openssl/openssl/pull/17324)

(cherry picked from commit 7a85dd46e0b2f67b341c777509f0126e3252938d)

---

Summary of changes:
 crypto/core_namemap.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index e1da724bd2..2bee5ef194 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -409,14 +409,16 @@ static void get_legacy_cipher_names(const OBJ_NAME *on, 
void *arg)
 {
 const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type);
 
-get_legacy_evp_names(NID_undef, EVP_CIPHER_get_type(cipher), NULL, arg);
+if (cipher != NULL)
+get_legacy_evp_names(NID_undef, EVP_CIPHER_get_type(cipher), NULL, 
arg);
 }
 
 static void get_legacy_md_names(const OBJ_NAME *on, void *arg)
 {
 const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type);
 
-get_legacy_evp_names(0, EVP_MD_get_type(md), NULL, arg);
+if (md != NULL)
+get_legacy_evp_names(0, EVP_MD_get_type(md), NULL, arg);
 }
 
 static void get_legacy_pkey_meth_names(const EVP_PKEY_ASN1_METHOD *ameth,


[openssl] master update

2021-12-22 Thread Dr . Paul Dale
The branch master has been updated
   via  7a85dd46e0b2f67b341c777509f0126e3252938d (commit)
  from  cdaf072f90399efb9e8e19ee4f387d1425f12274 (commit)


- Log -
commit 7a85dd46e0b2f67b341c777509f0126e3252938d
Author: Pauli 
Date:   Tue Dec 21 10:17:04 2021 +1100

namemap: handle a NULL return when looking for a non-legacy cipher/MD

Fixes #17313

Reviewed-by: Tomas Mraz 
(Merged from https://github.com/openssl/openssl/pull/17324)

---

Summary of changes:
 crypto/core_namemap.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index e1da724bd2..2bee5ef194 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -409,14 +409,16 @@ static void get_legacy_cipher_names(const OBJ_NAME *on, 
void *arg)
 {
 const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type);
 
-get_legacy_evp_names(NID_undef, EVP_CIPHER_get_type(cipher), NULL, arg);
+if (cipher != NULL)
+get_legacy_evp_names(NID_undef, EVP_CIPHER_get_type(cipher), NULL, 
arg);
 }
 
 static void get_legacy_md_names(const OBJ_NAME *on, void *arg)
 {
 const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type);
 
-get_legacy_evp_names(0, EVP_MD_get_type(md), NULL, arg);
+if (md != NULL)
+get_legacy_evp_names(0, EVP_MD_get_type(md), NULL, arg);
 }
 
 static void get_legacy_pkey_meth_names(const EVP_PKEY_ASN1_METHOD *ameth,


[openssl] openssl-3.0 update

2021-12-22 Thread dev
The branch openssl-3.0 has been updated
   via  e0314df5f21dd537602d4ea8d9272a21aac66356 (commit)
  from  fbadef597c906711d82d8bfd9c4d5276ea981db7 (commit)


- Log -
commit e0314df5f21dd537602d4ea8d9272a21aac66356
Author: Dr. David von Oheimb 
Date:   Sun Nov 21 20:55:35 2021 +0100

HTTP client: Fix cleanup of TLS BIO via 'bio_update_fn' callback function

Make app_http_tls_cb() tidy up on disconnect the SSL BIO it pushes on 
connect.
Make OSSL_HTTP_close() respect this.

Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17318)

(cherry picked from commit cdaf072f90399efb9e8e19ee4f387d1425f12274)

---

Summary of changes:
 apps/lib/apps.c | 33 -
 crypto/http/http_client.c   | 12 +---
 doc/man3/OSSL_HTTP_transfer.pod | 18 +-
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index e01633c5b5..6a762b7668 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -2442,7 +2442,7 @@ static const char *tls_error_hint(void)
 }
 
 /* HTTP callback function that supports TLS connection also via HTTPS proxy */
-BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
+BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail)
 {
 if (connect && detail) { /* connecting with TLS */
 APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
@@ -2451,7 +2451,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, 
int detail)
 BIO *sbio = NULL;
 
 if ((info->use_proxy
- && !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
+ && !OSSL_HTTP_proxy_connect(bio, info->server, info->port,
  NULL, NULL, /* no proxy credentials */
  info->timeout, bio_err, 
opt_getprog()))
 || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
@@ -2467,18 +2467,25 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, 
int detail)
 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(2, " : ", 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
- */
+bio = BIO_push(sbio, bio);
 }
-return hbio;
+if (!connect) {
+const char *hint;
+BIO *cbio;
+
+if (!detail) { /* disconnecting after error */
+hint = tls_error_hint();
+if (hint != NULL)
+ERR_add_error_data(2, " : ", hint);
+}
+(void)ERR_set_mark();
+BIO_ssl_shutdown(bio);
+cbio = BIO_pop(bio); /* connect+HTTP BIO */
+BIO_free(bio); /* SSL BIO */
+(void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */
+bio = cbio;
+}
+return bio;
 }
 
 void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info)
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index 7f8d8fc8d7..c80d4fe519 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -1197,11 +1197,17 @@ BIO *OSSL_HTTP_transfer(OSSL_HTTP_REQ_CTX **prctx,
 
 int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok)
 {
+BIO *wbio;
 int ret = 1;
 
-/* callback can be used to clean up TLS session on disconnect */
-if (rctx != NULL && rctx->upd_fn != NULL)
-ret = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg, 0, ok) != NULL;
+/* callback can be used to finish TLS session and free its BIO */
+if (rctx != NULL && rctx->upd_fn != NULL) {
+wbio = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg,
+   0 /* disconnect */, ok);
+ret = wbio != NULL;
+if (ret)
+rctx->wbio = wbio;
+}
 OSSL_HTTP_REQ_CTX_free(rctx);
 return ret;
 }
diff --git a/doc/man3/OSSL_HTTP_transfer.pod b/doc/man3/OSSL_HTTP_transfer.pod
index 7fcd71dbe0..7e823db3ea 100644
--- a/doc/man3/OSSL_HTTP_transfer.pod
+++ b/doc/man3/OSSL_HTTP_transfer.pod
@@ -113,17 +113,25 @@ or NULL to indicate failure, in which case it should not 
modify the BIO.
 
 Here is a simple example that supports TLS connections (but not via a proxy):
 
- BIO *http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
+ BIO *http_tls_cb(BIO *bio, void *arg, int connect, int detail)
  {
  if (connect && detail) { /* connecting with TLS */
  SSL_CTX *ctx = (SSL_CTX *)arg;
  BIO *sbio = BIO_new_ssl(ctx, 1);
 
- hbio = sbio != NULL ? BIO_push(sbio, hbio) : NULL;
- } else if 

[openssl] master update

2021-12-22 Thread dev
The branch master has been updated
   via  cdaf072f90399efb9e8e19ee4f387d1425f12274 (commit)
  from  c2d1ad0e048dd3bfa60e6aa0b5ee343cc6d97a15 (commit)


- Log -
commit cdaf072f90399efb9e8e19ee4f387d1425f12274
Author: Dr. David von Oheimb 
Date:   Sun Nov 21 20:55:35 2021 +0100

HTTP client: Fix cleanup of TLS BIO via 'bio_update_fn' callback function

Make app_http_tls_cb() tidy up on disconnect the SSL BIO it pushes on 
connect.
Make OSSL_HTTP_close() respect this.

Reviewed-by: Paul Dale 
(Merged from https://github.com/openssl/openssl/pull/17318)

---

Summary of changes:
 apps/lib/apps.c | 33 -
 crypto/http/http_client.c   | 12 +---
 doc/man3/OSSL_HTTP_transfer.pod | 18 +-
 3 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 88c4f7b97a..034fd45c4b 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -2462,7 +2462,7 @@ static const char *tls_error_hint(void)
 }
 
 /* HTTP callback function that supports TLS connection also via HTTPS proxy */
-BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
+BIO *app_http_tls_cb(BIO *bio, void *arg, int connect, int detail)
 {
 if (connect && detail) { /* connecting with TLS */
 APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg;
@@ -2471,7 +2471,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, 
int detail)
 BIO *sbio = NULL;
 
 if ((info->use_proxy
- && !OSSL_HTTP_proxy_connect(hbio, info->server, info->port,
+ && !OSSL_HTTP_proxy_connect(bio, info->server, info->port,
  NULL, NULL, /* no proxy credentials */
  info->timeout, bio_err, 
opt_getprog()))
 || (sbio = BIO_new(BIO_f_ssl())) == NULL) {
@@ -2487,18 +2487,25 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, 
int detail)
 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(2, " : ", 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
- */
+bio = BIO_push(sbio, bio);
 }
-return hbio;
+if (!connect) {
+const char *hint;
+BIO *cbio;
+
+if (!detail) { /* disconnecting after error */
+hint = tls_error_hint();
+if (hint != NULL)
+ERR_add_error_data(2, " : ", hint);
+}
+(void)ERR_set_mark();
+BIO_ssl_shutdown(bio);
+cbio = BIO_pop(bio); /* connect+HTTP BIO */
+BIO_free(bio); /* SSL BIO */
+(void)ERR_pop_to_mark(); /* hide SSL_R_READ_BIO_NOT_SET etc. */
+bio = cbio;
+}
+return bio;
 }
 
 void APP_HTTP_TLS_INFO_free(APP_HTTP_TLS_INFO *info)
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index ef0114240b..f786f831bf 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -1196,11 +1196,17 @@ BIO *OSSL_HTTP_transfer(OSSL_HTTP_REQ_CTX **prctx,
 
 int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok)
 {
+BIO *wbio;
 int ret = 1;
 
-/* callback can be used to clean up TLS session on disconnect */
-if (rctx != NULL && rctx->upd_fn != NULL)
-ret = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg, 0, ok) != NULL;
+/* callback can be used to finish TLS session and free its BIO */
+if (rctx != NULL && rctx->upd_fn != NULL) {
+wbio = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg,
+   0 /* disconnect */, ok);
+ret = wbio != NULL;
+if (ret)
+rctx->wbio = wbio;
+}
 OSSL_HTTP_REQ_CTX_free(rctx);
 return ret;
 }
diff --git a/doc/man3/OSSL_HTTP_transfer.pod b/doc/man3/OSSL_HTTP_transfer.pod
index 7fcd71dbe0..7e823db3ea 100644
--- a/doc/man3/OSSL_HTTP_transfer.pod
+++ b/doc/man3/OSSL_HTTP_transfer.pod
@@ -113,17 +113,25 @@ or NULL to indicate failure, in which case it should not 
modify the BIO.
 
 Here is a simple example that supports TLS connections (but not via a proxy):
 
- BIO *http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
+ BIO *http_tls_cb(BIO *bio, void *arg, int connect, int detail)
  {
  if (connect && detail) { /* connecting with TLS */
  SSL_CTX *ctx = (SSL_CTX *)arg;
  BIO *sbio = BIO_new_ssl(ctx, 1);
 
- hbio = sbio != NULL ? BIO_push(sbio, hbio) : NULL;
- } else if (!connect && !detail) { /* disconnecting after error */
- /* optionally add