|
| 1 | +diff --strip-trailing-cr -Naur curl-8.10.1.old/lib/vtls/mbedtls.c curl-8.10.1.new/lib/vtls/mbedtls.c |
| 2 | +--- curl-8.10.1.old/lib/vtls/mbedtls.c 2024-12-22 20:24:54.944116200 +0100 |
| 3 | ++++ curl-8.10.1.new/lib/vtls/mbedtls.c 2024-12-22 20:22:04.927962100 +0100 |
| 4 | +@@ -113,6 +113,11 @@ |
| 5 | + int *ciphersuites; |
| 6 | + BIT(initialized); /* mbedtls_ssl_context is initialized */ |
| 7 | + BIT(sent_shutdown); |
| 8 | ++ BIT(ww_buffer_valid); |
| 9 | ++ unsigned char *ww_buffer; |
| 10 | ++ size_t ww_buffer_size; |
| 11 | ++ size_t ww_buffer_used; |
| 12 | ++ size_t ww_buffer_from; |
| 13 | + }; |
| 14 | + |
| 15 | + /* apply threading? */ |
| 16 | +@@ -1174,14 +1179,73 @@ |
| 17 | + struct mbed_ssl_backend_data *backend = |
| 18 | + (struct mbed_ssl_backend_data *)connssl->backend; |
| 19 | + int ret = -1; |
| 20 | ++ size_t orig_len = len; |
| 21 | ++ |
| 22 | ++ if(backend->ww_buffer_valid) { |
| 23 | ++ if(backend->ww_buffer_used) { |
| 24 | ++ // if there were bytes in the fragment, match the last byte against what |
| 25 | ++ // libcurl is retrying to get us to send |
| 26 | ++ DEBUGASSERT(len); |
| 27 | ++ DEBUGASSERT(*(unsigned char *)mem == backend->ww_buffer[backend->ww_buffer_used - 1]); |
| 28 | ++ } |
| 29 | ++ // restore the same arguments as were passed to the last call (functionally |
| 30 | ++ // speaking anyway; the pointer will be different but the data it points to |
| 31 | ++ // will be the same) |
| 32 | ++ len = backend->ww_buffer_used - backend->ww_buffer_from; |
| 33 | ++ mem = backend->ww_buffer + backend->ww_buffer_from; |
| 34 | ++ } |
| 35 | + |
| 36 | + (void)data; |
| 37 | + DEBUGASSERT(backend); |
| 38 | + ret = mbedtls_ssl_write(&backend->ssl, (unsigned char *)mem, len); |
| 39 | + |
| 40 | ++ if(ret >= 0 && backend->ww_buffer_valid) { |
| 41 | ++ // some of the data we stashed away is done sending, but we can't fully give |
| 42 | ++ // control back to libcurl until all this data is done sending, and it may |
| 43 | ++ // very well yet result in MBEDTLS_ERR_SSL_WANT_WRITE returns from mbedtls |
| 44 | ++ DEBUGASSERT(backend->ww_buffer_from + ret <= backend->ww_buffer_used); |
| 45 | ++ backend->ww_buffer_from += ret; |
| 46 | ++ if(backend->ww_buffer_from < backend->ww_buffer_used) |
| 47 | ++ // if we're not done sending the data we stashed away, tell libcurl that |
| 48 | ++ // we're still working on it |
| 49 | ++ ret = MBEDTLS_ERR_SSL_WANT_WRITE; |
| 50 | ++ } |
| 51 | ++ if(ret != MBEDTLS_ERR_SSL_WANT_WRITE && backend->ww_buffer_valid && backend->ww_buffer_from == backend->ww_buffer_used) { |
| 52 | ++ // if there were bytes in the fragment, tell libcurl that we have finally |
| 53 | ++ // managed to send that one last byte that we kept for matching against; if |
| 54 | ++ // not, tell it that the lack of bytes has been successfully sent |
| 55 | ++ ret = backend->ww_buffer_used ? 1 : 0; |
| 56 | ++ backend->ww_buffer_from = 0; |
| 57 | ++ backend->ww_buffer_used = 0; |
| 58 | ++ backend->ww_buffer_valid = FALSE; |
| 59 | ++ } |
| 60 | ++ if(ret == MBEDTLS_ERR_SSL_WANT_WRITE && !backend->ww_buffer_valid) { |
| 61 | ++ if(backend->ww_buffer_size < len) { |
| 62 | ++ backend->ww_buffer_size = len; |
| 63 | ++ Curl_safefree(backend->ww_buffer); |
| 64 | ++ backend->ww_buffer = malloc(backend->ww_buffer_size); |
| 65 | ++ if(!backend->ww_buffer) |
| 66 | ++ return CURLE_OUT_OF_MEMORY; |
| 67 | ++ } |
| 68 | ++ memcpy(backend->ww_buffer, mem, len); |
| 69 | ++ backend->ww_buffer_used = len; |
| 70 | ++ backend->ww_buffer_valid = TRUE; |
| 71 | ++ if(len) { |
| 72 | ++ // if there were bytes in the fragment, report that all of them but the |
| 73 | ++ // last one has been sent (any number could be reported that is less than |
| 74 | ++ // len, but the remaining bytes will be attempted to sent again later and |
| 75 | ++ // we have to match them against what is already committed inside mbedtls; |
| 76 | ++ // it's by far the easiest to hold on to just one, which is fast to match) |
| 77 | ++ ret = len - 1; |
| 78 | ++ } |
| 79 | ++ // if there were no bytes in the fragment, let the original logic return |
| 80 | ++ // CURLE_AGAIN, as this is the only way to make libcurl keep trying to send |
| 81 | ++ // the lack of bytes |
| 82 | ++ } |
| 83 | ++ |
| 84 | + if(ret < 0) { |
| 85 | + CURL_TRC_CF(data, cf, "mbedtls_ssl_write(len=%zu) -> -0x%04X", |
| 86 | +- len, -ret); |
| 87 | ++ orig_len, -ret); |
| 88 | + *curlcode = ((ret == MBEDTLS_ERR_SSL_WANT_WRITE) |
| 89 | + #ifdef TLS13_SUPPORT |
| 90 | + || (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET) |
| 91 | +@@ -1304,6 +1368,11 @@ |
| 92 | + mbedtls_x509_crl_free(&backend->crl); |
| 93 | + #endif |
| 94 | + Curl_safefree(backend->ciphersuites); |
| 95 | ++ Curl_safefree(backend->ww_buffer); |
| 96 | ++ backend->ww_buffer_size = 0; |
| 97 | ++ backend->ww_buffer_used = 0; |
| 98 | ++ backend->ww_buffer_from = 0; |
| 99 | ++ backend->ww_buffer_valid = FALSE; |
| 100 | + mbedtls_ssl_config_free(&backend->config); |
| 101 | + mbedtls_ssl_free(&backend->ssl); |
| 102 | + mbedtls_ctr_drbg_free(&backend->ctr_drbg); |
0 commit comments