aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/schannel.c
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2017-04-06 03:27:28 -0400
committerJay Satiro <raysatiro@yahoo.com>2017-04-22 22:39:40 -0400
commit6b39f9c87e48f17533b139b2ddb829aa21227c3d (patch)
tree6d7d22d5412d0b9bdad130f07b1b3e0b5b31fbea /lib/vtls/schannel.c
parentbe299a4dba0362940062f7f07c76862ecf226522 (diff)
schannel: Don't treat encrypted partial record as pending data
- Track when the cached encrypted data contains only a partial record that can't be decrypted without more data (SEC_E_INCOMPLETE_MESSAGE). - Change Curl_schannel_data_pending to return false in such a case. Other SSL libraries have pending data functions that behave similarly. Ref: https://github.com/curl/curl/pull/1387 Closes https://github.com/curl/curl/pull/1392
Diffstat (limited to 'lib/vtls/schannel.c')
-rw-r--r--lib/vtls/schannel.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index c9b513230..d20f30d89 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -432,6 +432,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
connssl->recv_unrecoverable_err = CURLE_OK;
connssl->recv_sspi_close_notify = false;
connssl->recv_connection_closed = false;
+ connssl->encdata_is_incomplete = false;
/* continue to second handshake step */
connssl->connecting_state = ssl_connect_2;
@@ -480,6 +481,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* buffer to store previously received and encrypted data */
if(connssl->encdata_buffer == NULL) {
+ connssl->encdata_is_incomplete = false;
connssl->encdata_offset = 0;
connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
connssl->encdata_buffer = malloc(connssl->encdata_length);
@@ -532,6 +534,8 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* increase encrypted data buffer offset */
connssl->encdata_offset += nread;
+ connssl->encdata_is_incomplete = false;
+ infof(data, "schannel: encrypted data got %zd\n", nread);
}
infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
@@ -576,6 +580,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
/* check if the handshake was incomplete */
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+ connssl->encdata_is_incomplete = true;
connssl->connecting_state = ssl_connect_2_reading;
infof(data, "schannel: received incomplete message, need more data\n");
return CURLE_OK;
@@ -1177,6 +1182,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
}
else if(nread > 0) {
connssl->encdata_offset += (size_t)nread;
+ connssl->encdata_is_incomplete = false;
infof(data, "schannel: encrypted data got %zd\n", nread);
}
}
@@ -1313,6 +1319,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
}
}
else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+ connssl->encdata_is_incomplete = true;
if(!*err)
*err = CURLE_AGAIN;
infof(data, "schannel: failed to decrypt data, need more data\n");
@@ -1414,8 +1421,8 @@ bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex)
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
if(connssl->use) /* SSL/TLS is in use */
- return (connssl->encdata_offset > 0 ||
- connssl->decdata_offset > 0) ? TRUE : FALSE;
+ return (connssl->decdata_offset > 0 ||
+ (connssl->encdata_offset > 0 && !connssl->encdata_is_incomplete));
else
return FALSE;
}
@@ -1518,6 +1525,7 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
Curl_safefree(connssl->encdata_buffer);
connssl->encdata_length = 0;
connssl->encdata_offset = 0;
+ connssl->encdata_is_incomplete = false;
}
/* free internal buffer for received decrypted data */