通过SChannel SSPI执行DTLS握手时,如何处理SEC_I_MESSAGE_FRANSION?

人气:1,033 发布:2022-10-16 标签: winapi desktop-application sspi dtls schannel

问题描述

在Windows 10中使用SChannel SSPI执行DTLS握手时(没有相关文档),应用程序应如何处理AcceptSecurityContext(ASC)或InitializeSecurityContext(ISC)产生的SEC_I_MESSAGE_FRANSION结果?

我知道我应该将收到的片段发送给另一方,并再次调用ASC/ISC以获取下一个片段,但当我再次调用ASC时,这次使用空的输入SECBUFFER_TOKEN,我在输出令牌缓冲区中没有收到任何内容,并且它返回SEC_I_MESSAGE_FRANSION-表明它正在等待输入数据。

我可能没有成功地向ASC指示我希望它给我下一个片段,那么我该如何做?

我已经创建了一个独立的示例,它重现了以下GitHub要点中的问题: https://gist.github.com/haddoncd/381c5e9542e977ca238ff16229bd9a0e/c881132ced94995402b617f38a5c8b6f8669b637

我还在程序的主要示例输出中包含了详细显示导致问题的输入的输出: https://gist.github.com/haddoncd/381c5e9542e977ca238ff16229bd9a0e/c881132ced94995402b617f38a5c8b6f8669b637#file-example_output-txt

推荐答案

根据我的测试,您唯一做错的事情是在握手过程中初始化后忘记重置context.handle

isc_status = InitializeSecurityContextW(
    &creds,
    context.initialized ? &context.handle : nullptr,
    nullptr,
    context_reqs,
    0,
    SECURITY_NATIVE_DREP,
    isc_input_buffers,
    0,
    &context.handle, // HERE
    &out_buffer_desc,
    &context.attrs,
    &context.expiry
);

asc_status = AcceptSecurityContext(
    &creds,
    context.initialized ? &context.handle : nullptr,
    &in_buffer_desc,
    context_reqs,
    SECURITY_NATIVE_DREP,
    &context.handle, // HERE
    &out_buffer_desc,
    &context.attrs,
    &context.expiry
);

顺便说一句,您不需要在旧的CtxtHandle上调用DeleteSecurityContext,因为它在调用后已经无效。

358