在我们的 Windows C++ 应用程序中,我使用 InitializeSecurityContext() 客户端打开到运行 stunnel SSL 代理的服务器的 schannel 连接。我的代码现在可以工作,但只有我想消除的黑客。
我从这个示例代码开始:http://msdn.microsoft.com/en-us/library/aa380536%28v=VS.85%29.aspx
在示例代码中,查看 SendMsg 和 ReceiveMsg。发送或接收的任何消息的前 4 个字节表示消息长度。这对于示例来说很好,其中示例的服务器部分符合相同的约定。
stunnel 似乎没有使用这个约定。当客户端在握手期间接收数据时,它如何知道何时停止接收并再次调用 InitializeSecurityContext()?
根据我从文档中收集到的信息,这就是我构建代码的方式:
1. call InitializeSecurityContext which returns an output buffer
2. Send output buffer to server
3. Receive response from server
4. call InitializeSecurityContext(server_response) which returns an output buffer
5. if SEC_E_INCOMPLETE_MESSAGE, go back to step 3,
if SEC_I_CONTINUE_NEEDED go back to step 2
如果在第 3 步中没有从服务器读取足够的数据,我希望第 4 步中的 InitializeSecurityContext 返回 SEC_E_INCOMPLETE_MESSAGE。相反,我得到 SEC_I_CONTINUE_NEEDED 但一个空的输出缓冲区。我已经尝试了几种处理这种情况的方法(例如返回第 3 步),但似乎没有一种方法有效,更重要的是,我没有看到这种行为被记录在案。
在第 3 步中,如果我添加一个在超时到期之前接收数据的循环,那么在我的测试环境中一切正常。但必须有更可靠的方法。
知道在第 3 步中接收多少数据的正确方法是什么?