mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
schannel: improve handshake procedure
- During handshake, do not require reading more data if unprocessed encrypted data that may be a complete TLS record is already available. - During handshake, check that the socket is writeable before processing encrypted data that may require an immediate reply to the server. These two fixes are for issues that were found during renegotiation testing but could affect any handshake. Prior to this change it was possible in some abnormal network conditions for the Schannel TLS handshake procedure to erroneously wait or error. Ref: https://github.com/curl/curl/pull/18125 Closes https://github.com/curl/curl/pull/18323
This commit is contained in:
parent
7d5f535ca7
commit
b6a5f67259
@ -1190,21 +1190,28 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
backend->encdata_offset,
|
||||
&nread);
|
||||
if(result == CURLE_AGAIN) {
|
||||
connssl->io_need = CURL_SSL_IO_NEED_RECV;
|
||||
DEBUGF(infof(data, "schannel: failed to receive handshake, "
|
||||
"need more data"));
|
||||
return CURLE_OK;
|
||||
if(!backend->encdata_offset || backend->encdata_is_incomplete) {
|
||||
connssl->io_need = CURL_SSL_IO_NEED_RECV;
|
||||
DEBUGF(infof(data, "schannel: failed to receive handshake, "
|
||||
"need more data"));
|
||||
return CURLE_OK;
|
||||
}
|
||||
else {
|
||||
DEBUGF(infof(data, "schannel: no new handshake data received, "
|
||||
"continuing to process existing handshake data"));
|
||||
}
|
||||
}
|
||||
else if(result || (nread == 0)) {
|
||||
failf(data, "schannel: failed to receive handshake, "
|
||||
"SSL/TLS connection failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* increase encrypted data buffer offset */
|
||||
backend->encdata_offset += nread;
|
||||
backend->encdata_is_incomplete = FALSE;
|
||||
SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread));
|
||||
else {
|
||||
/* increase encrypted data buffer offset */
|
||||
backend->encdata_offset += nread;
|
||||
backend->encdata_is_incomplete = FALSE;
|
||||
SCH_DEV(infof(data, "schannel: encrypted data got %zu", nread));
|
||||
}
|
||||
}
|
||||
|
||||
SCH_DEV(infof(data,
|
||||
@ -1232,6 +1239,16 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
|
||||
backend->encdata_offset);
|
||||
|
||||
/* The socket must be writeable (or a poll error occurred) before we call
|
||||
InitializeSecurityContext to continue processing the received TLS
|
||||
records. This is because that function is not idempotent and we don't
|
||||
support partial save/resume sending replies of handshake tokens. */
|
||||
if(!SOCKET_WRITABLE(Curl_conn_cf_get_socket(cf, data), 0)) {
|
||||
SCH_DEV(infof(data, "schannel: handshake waiting for writeable socket"));
|
||||
connssl->io_need = CURL_SSL_IO_NEED_SEND;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
sspi_status = Curl_pSecFn->InitializeSecurityContext(
|
||||
&backend->cred->cred_handle, &backend->ctxt->ctxt_handle,
|
||||
backend->cred->sni_hostname, backend->req_flags,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user