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