@@ -191,6 +191,7 @@ _mongoc_stream_tls_secure_channel_destroy(mongoc_stream_t *stream)
191191
192192 mongoc_stream_destroy (tls -> base_stream );
193193
194+ bson_free (secure_channel -> hostname );
194195 bson_free (secure_channel );
195196 bson_free (stream );
196197
@@ -464,6 +465,7 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
464465{
465466 size_t size = 0 ;
466467 size_t remaining ;
468+ bool secbuf_extra_received = false;
467469 SecBuffer inbuf [4 ];
468470 SecBufferDesc inbuf_desc ;
469471 SECURITY_STATUS sspi_status = SEC_E_OK ;
@@ -474,6 +476,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
474476
475477 /* decrypt loop */
476478 while (secure_channel -> encdata_offset > 0 && sspi_status == SEC_E_OK ) {
479+ secbuf_extra_received = false;
480+
477481 /* prepare data buffer for DecryptMessage call */
478482 _mongoc_secure_channel_init_sec_buffer (& inbuf [0 ],
479483 SECBUFFER_DATA ,
@@ -534,6 +538,8 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
534538 secure_channel -> encdata_offset = inbuf [3 ].cbBuffer ;
535539 }
536540
541+ secbuf_extra_received = true;
542+
537543 TRACE ("encrypted data cached: offset %d length %d" ,
538544 (int )secure_channel -> encdata_offset ,
539545 (int )secure_channel -> encdata_length );
@@ -546,6 +552,28 @@ _mongoc_stream_tls_secure_channel_decrypt(mongoc_stream_tls_secure_channel_t *se
546552 /* check if server wants to renegotiate the connection context */
547553 if (sspi_status == SEC_I_RENEGOTIATE ) {
548554 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+ }
549577 }
550578 /* check if the server closed the connection */
551579 else if (sspi_status == SEC_I_CONTEXT_EXPIRED ) {
@@ -678,6 +706,12 @@ _mongoc_stream_tls_secure_channel_readv(
678706 ssize_t read_ret = _mongoc_stream_tls_secure_channel_read (
679707 stream , (char * )iov [i ].iov_base + iov_pos , (int )(iov [i ].iov_len - iov_pos ));
680708
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+
681715 if (read_ret < 0 ) {
682716 RETURN (-1 );
683717 }
@@ -990,13 +1024,13 @@ mongoc_secure_channel_cred_deleter(void *cred_void)
9901024mongoc_stream_t *
9911025mongoc_stream_tls_secure_channel_new (mongoc_stream_t * base_stream , const char * host , mongoc_ssl_opt_t * opt , int client )
9921026{
993- BSON_UNUSED (host );
9941027 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 );
9961029}
9971030
9981031mongoc_stream_t *
9991032mongoc_stream_tls_secure_channel_new_with_creds (mongoc_stream_t * base_stream ,
1033+ const char * host ,
10001034 const mongoc_ssl_opt_t * opt ,
10011035 mongoc_shared_ptr cred_ptr )
10021036{
@@ -1011,6 +1045,8 @@ mongoc_stream_tls_secure_channel_new_with_creds(mongoc_stream_t *base_stream,
10111045
10121046 secure_channel = (mongoc_stream_tls_secure_channel_t * )bson_malloc0 (sizeof * secure_channel );
10131047
1048+ secure_channel -> hostname = bson_strdup (host );
1049+
10141050 secure_channel -> decdata_buffer = bson_malloc (MONGOC_SCHANNEL_BUFFER_INIT_SIZE );
10151051 secure_channel -> decdata_length = MONGOC_SCHANNEL_BUFFER_INIT_SIZE ;
10161052 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,
10351071 tls -> timeout_msec = -1 ;
10361072 tls -> base_stream = base_stream ;
10371073
1074+ secure_channel -> tls = tls ;
1075+
10381076 TRACE ("%s" , "SSL/TLS connection with endpoint AcquireCredentialsHandle" );
10391077
10401078 /* setup Schannel API options */
0 commit comments