@@ -465,6 +465,7 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
465
465
{
466
466
size_t size = 0 ;
467
467
size_t remaining ;
468
+ bool secbuf_extra_received = false;
468
469
SecBuffer inbuf [4 ];
469
470
SecBufferDesc inbuf_desc ;
470
471
SECURITY_STATUS sspi_status = SEC_E_OK ;
@@ -475,6 +476,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
475
476
476
477
/* decrypt loop */
477
478
while (secure_channel -> encdata_offset > 0 && sspi_status == SEC_E_OK ) {
479
+ secbuf_extra_received = false;
480
+
478
481
/* prepare data buffer for DecryptMessage call */
479
482
_mongoc_secure_channel_init_sec_buffer (& inbuf [0 ],
480
483
SECBUFFER_DATA ,
@@ -535,6 +538,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
535
538
secure_channel -> encdata_offset = inbuf [3 ].cbBuffer ;
536
539
}
537
540
541
+ secbuf_extra_received = true;
542
+
538
543
TRACE ("encrypted data cached: offset %d length %d" ,
539
544
(int )secure_channel -> encdata_offset ,
540
545
(int )secure_channel -> encdata_length );
@@ -547,6 +552,27 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
547
552
/* check if server wants to renegotiate the connection context */
548
553
if (sspi_status == SEC_I_RENEGOTIATE ) {
549
554
TRACE ("%s" , "remote party requests renegotiation" );
555
+
556
+ if (secbuf_extra_received ) {
557
+ bool ret ;
558
+ bson_error_t error ;
559
+
560
+ secure_channel -> recv_renegotiate = true;
561
+
562
+ /* the tls handshake will pass the contents of SECBUFFER_EXTRA to the server */
563
+ secure_channel -> connecting_state = ssl_connect_2_writing ;
564
+ ret = mongoc_secure_channel_handshake_step_2 (secure_channel -> tls , secure_channel -> hostname , & error );
565
+ if (!ret ) {
566
+ TRACE ("TLS 1.3 renegotiation failed: %s" , error .message );
567
+ secure_channel -> recv_unrecoverable_err = true;
568
+ return ;
569
+ }
570
+
571
+ /* now continue decrypting data */
572
+ secure_channel -> connecting_state = ssl_connect_done ;
573
+ sspi_status = SEC_E_OK ;
574
+ continue ;
575
+ }
550
576
}
551
577
/* check if the server closed the connection */
552
578
else if (sspi_status == SEC_I_CONTEXT_EXPIRED ) {
@@ -679,6 +705,12 @@ _mongoc_stream_tls_secure_channel_readv(
679
705
ssize_t read_ret = _mongoc_stream_tls_secure_channel_read (
680
706
stream , (char * )iov [i ].iov_base + iov_pos , (int )(iov [i ].iov_len - iov_pos ));
681
707
708
+ /* used up all read bytes for tls renegotiation, try reading again to get next message */
709
+ if (read_ret == 0 && secure_channel -> recv_renegotiate ) {
710
+ secure_channel -> recv_renegotiate = false;
711
+ continue ;
712
+ }
713
+
682
714
if (read_ret < 0 ) {
683
715
RETURN (-1 );
684
716
}
@@ -1011,13 +1043,13 @@ mongoc_secure_channel_cred_deleter(void *cred_void)
1011
1043
mongoc_stream_t *
1012
1044
mongoc_stream_tls_secure_channel_new (mongoc_stream_t * base_stream , const char * host , mongoc_ssl_opt_t * opt , int client )
1013
1045
{
1014
- BSON_UNUSED (host );
1015
1046
BSON_UNUSED (client );
1016
- return mongoc_stream_tls_secure_channel_new_with_creds (base_stream , opt , MONGOC_SHARED_PTR_NULL );
1047
+ return mongoc_stream_tls_secure_channel_new_with_creds (base_stream , host , opt , MONGOC_SHARED_PTR_NULL );
1017
1048
}
1018
1049
1019
1050
mongoc_stream_t *
1020
1051
mongoc_stream_tls_secure_channel_new_with_creds (mongoc_stream_t * base_stream ,
1052
+ const char * host ,
1021
1053
const mongoc_ssl_opt_t * opt ,
1022
1054
mongoc_shared_ptr cred_ptr )
1023
1055
{
@@ -1032,6 +1064,8 @@ mongoc_stream_tls_secure_channel_new_with_creds(mongoc_stream_t *base_stream,
1032
1064
1033
1065
secure_channel = (mongoc_stream_tls_secure_channel_t * )bson_malloc0 (sizeof * secure_channel );
1034
1066
1067
+ secure_channel -> hostname = bson_strdup (host );
1068
+
1035
1069
secure_channel -> decdata_buffer = bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE );
1036
1070
secure_channel -> decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE ;
1037
1071
secure_channel -> encdata_buffer = bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE );
@@ -1056,6 +1090,8 @@ mongoc_stream_tls_secure_channel_new_with_creds(mongoc_stream_t *base_stream,
1056
1090
tls -> timeout_msec = -1 ;
1057
1091
tls -> base_stream = base_stream ;
1058
1092
1093
+ secure_channel -> tls = tls ;
1094
+
1059
1095
TRACE ("%s" , "SSL/TLS connection with endpoint AcquireCredentialsHandle" );
1060
1096
1061
1097
/* setup Schannel API options */
0 commit comments