A while ago I implemented a client and server using SChannel to encrypt communication. Recently I made the required switch from the SCHANNEL_CRED struct to the SCH_CREDENTIALS one so that TLS 1.3 support is provided in Windows 11. However, I encountered a situation that my code didn't originally account for and that I've resolved but can't explain.
The negotiation flow is as follows:
- I call
InitializeSecurityContexton the client and getSEC_I_CONTINUE_NEEDEDwith some data to send to the server (264 bytes for example). This would be the client hello, cipher suites, and key share. - I call
AcceptSecurityContexton the server and pass in the received data, gettingSEC_I_CONTINUE_NEEDEDwith some data to send to the client (785 bytes for example). This would be the server hello, key agreement protocol, key share, and an indication that the server has finished. - I call
InitializeSecurityContexton the client, pass in the received data, and getSEC_E_OKwith some data to send to the server (80 bytes for example). This would be the client finished indication.
At this point I call AcceptSecurityContext on the server and pass in the received data and I would expect to get SEC_E_OK and no data to pass back to the client. Both sides have indicated that they've finished and, by all accounts that I've read, the negotiation is complete. However what actually happens is:
- I call
AcceptSecurityContexton the server and pass in the received data, gettingSEC_E_OKwith some data to send to the client (103 bytes for example). I don't know what this message could be.
My original implementation would fail at this point because once a given side returned SEC_E_OK I didn't expect the peer to provide it with any more messages for the negotiation. The client already returned that, and yet the server has more data to send it.
- At this point I call
InitializeSecurityContexton the client with the extra data and getSEC_E_OKwith no more data to send to the server. Negotiation is finally actually complete.
Can anyone explain what this additional message is?
I would have put this in as a comment, but my reputation isn't high enough. I can't tell you what the additional token represents, in terms of the TLS protocol, but I can tell you that it's not specific to TLS 1.3 (I haven't done anything with 1.3, and my implementation allows for this final token), and that it is documented.