@@ -191,6 +191,7 @@ _mongoc_stream_tls_secure_channel_destroy(mongoc_stream_t *stream)
191
191
192
192
mongoc_stream_destroy (tls -> base_stream );
193
193
194
+ bson_free (secure_channel -> hostname );
194
195
bson_free (secure_channel );
195
196
bson_free (stream );
196
197
@@ -464,6 +465,7 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
464
465
{
465
466
size_t size = 0 ;
466
467
size_t remaining ;
468
+ bool secbuf_extra_received = false;
467
469
SecBuffer inbuf [4 ];
468
470
SecBufferDesc inbuf_desc ;
469
471
SECURITY_STATUS sspi_status = SEC_E_OK ;
@@ -474,6 +476,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
474
476
475
477
/* decrypt loop */
476
478
while (secure_channel -> encdata_offset > 0 && sspi_status == SEC_E_OK ) {
479
+ secbuf_extra_received = false;
480
+
477
481
/* prepare data buffer for DecryptMessage call */
478
482
_mongoc_secure_channel_init_sec_buffer (& inbuf [0 ],
479
483
SECBUFFER_DATA ,
@@ -534,6 +538,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
534
538
secure_channel -> encdata_offset = inbuf [3 ].cbBuffer ;
535
539
}
536
540
541
+ secbuf_extra_received = true;
542
+
537
543
TRACE ("encrypted data cached: offset %d length %d" ,
538
544
(int )secure_channel -> encdata_offset ,
539
545
(int )secure_channel -> encdata_length );
@@ -546,6 +552,28 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
546
552
/* check if server wants to renegotiate the connection context */
547
553
if (sspi_status == SEC_I_RENEGOTIATE ) {
548
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
+ /* mongoc_secure_channel_handshake_step_2 passes the received SECBUFFER_EXTRA to
563
+ * InitializeSecurityContext */
564
+ secure_channel -> connecting_state = ssl_connect_2_writing ;
565
+ ret = mongoc_secure_channel_handshake_step_2 (secure_channel -> tls , secure_channel -> hostname , & error );
566
+ if (!ret ) {
567
+ TRACE ("TLS 1.3 renegotiation failed: %s" , error .message );
568
+ secure_channel -> recv_unrecoverable_err = true;
569
+ return ;
570
+ }
571
+
572
+ /* now continue decrypting data */
573
+ secure_channel -> connecting_state = ssl_connect_done ;
574
+ sspi_status = SEC_E_OK ;
575
+ continue ;
576
+ }
549
577
}
550
578
/* check if the server closed the connection */
551
579
else if (sspi_status == SEC_I_CONTEXT_EXPIRED ) {
@@ -678,6 +706,12 @@ _mongoc_stream_tls_secure_channel_readv(
678
706
ssize_t read_ret = _mongoc_stream_tls_secure_channel_read (
679
707
stream , (char * )iov [i ].iov_base + iov_pos , (int )(iov [i ].iov_len - iov_pos ));
680
708
709
+ /* used up all read bytes for tls renegotiation, try reading again to get next message */
710
+ if (read_ret == 0 && secure_channel -> recv_renegotiate ) {
711
+ secure_channel -> recv_renegotiate = false;
712
+ continue ;
713
+ }
714
+
681
715
if (read_ret < 0 ) {
682
716
RETURN (-1 );
683
717
}
@@ -990,13 +1024,13 @@ mongoc_secure_channel_cred_deleter(void *cred_void)
990
1024
mongoc_stream_t *
991
1025
mongoc_stream_tls_secure_channel_new (mongoc_stream_t * base_stream , const char * host , mongoc_ssl_opt_t * opt , int client )
992
1026
{
993
- BSON_UNUSED (host );
994
1027
BSON_UNUSED (client );
995
- return mongoc_stream_tls_secure_channel_new_with_creds (base_stream , opt , MONGOC_SHARED_PTR_NULL );
1028
+ return mongoc_stream_tls_secure_channel_new_with_creds (base_stream , host , opt , MONGOC_SHARED_PTR_NULL );
996
1029
}
997
1030
998
1031
mongoc_stream_t *
999
1032
mongoc_stream_tls_secure_channel_new_with_creds (mongoc_stream_t * base_stream ,
1033
+ const char * host ,
1000
1034
const mongoc_ssl_opt_t * opt ,
1001
1035
mongoc_shared_ptr cred_ptr )
1002
1036
{
@@ -1011,6 +1045,8 @@ mongoc_stream_tls_secure_channel_new_with_creds(mongoc_stream_t *base_stream,
1011
1045
1012
1046
secure_channel = (mongoc_stream_tls_secure_channel_t * )bson_malloc0 (sizeof * secure_channel );
1013
1047
1048
+ secure_channel -> hostname = bson_strdup (host );
1049
+
1014
1050
secure_channel -> decdata_buffer = bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE );
1015
1051
secure_channel -> decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE ;
1016
1052
secure_channel -> encdata_buffer = bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE );
@@ -1035,6 +1071,8 @@ mongoc_stream_tls_secure_channel_new_with_creds(mongoc_stream_t *base_stream,
1035
1071
tls -> timeout_msec = -1 ;
1036
1072
tls -> base_stream = base_stream ;
1037
1073
1074
+ secure_channel -> tls = tls ;
1075
+
1038
1076
TRACE ("%s" , "SSL/TLS connection with endpoint AcquireCredentialsHandle" );
1039
1077
1040
1078
/* setup Schannel API options */
0 commit comments