【问题标题】:How to handle SEC_I_MESSAGE_FRAGMENT when performing a DTLS handshake via the SChannel SSPI?通过 SChannel SSPI 执行 DTLS 握手时如何处理 SEC_I_MESSAGE_FRAGMENT?
【发布时间】:2021-07-31 10:45:29
【问题描述】:

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

我明白我的意思是将收到的片段发送给对方并再次调用 ASC/ISC 以获得下一个片段,但是当我再次调用 ASC 时,这次输入为空的 SECBUFFER_TOKEN,我在输出令牌缓冲区,并返回 SEC_I_MESSAGE_FRAGMENT - 表明它正在等待输入数据。

大概我没有成功地向 ASC 表明我希望它给我下一个片段,那么我该怎么做呢?

我创建了一个独立的示例,在此 GitHub gist 中重现了我的问题: https://gist.github.com/haddoncd/381c5e9542e977ca238ff16229bd9a0e/c881132ced94995402b617f38a5c8b6f8669b637

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

【问题讨论】:

  • 我建议您像收到 SEC_E_INCOMPLETE_MESSAGE 一样处理它,它们看起来非常相似。
  • @SoroneHaetir - 据我了解,SEC_E_INCOMPLETE_MESSAGE 用于表示输入消息不完整,必须从对方读取更多数据才能继续。 SEC_I_MESSAGE_FRAGMENT 的含义几乎相反——从 ASC/ISC 获得更多数据而无需从套接字读取,因为它产生的输出不适合单个数据报,因此将其分段,只返回第一个片段。
  • 正如 Hsu Pu 在下面的回答中所示,我正确处理了 SEC_I_MESSAGE_FRAGMENT。我的代码的问题是我在第一次之后在 ISC/ASC 调用中将 nullptr 作为 phNewContext 参数传递。我曾假设第一次调用会分配一个上下文句柄,然后在后续调用中(通过 phContext 参数)重复使用该句柄。然而,这显然不是 API 的实现方式。我已经用工作代码更新了我的要点,以帮助其他发现这个问题的人:gist.github.com/haddoncd/381c5e9542e977ca238ff16229bd9a0e

标签: winapi desktop-application sspi dtls schannel


【解决方案1】:

根据我的测试,你做的唯一错误的事情是在握手过程中忘记重置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,因为调用后它已无效。

【讨论】:

  • 您好,Hsu Pu,谢谢您的回复,看起来就是这样。似乎我被 InitializeSecurityContextW 文档中的这一行误导了:“使用 Schannel SSP 时,在第一次调用后的调用中,将此处返回的句柄作为 phContext 参数传递,并为 phNewContext 指定 NULL。” (docs.microsoft.com/en-us/windows/win32/api/sspi/…)
猜你喜欢
  • 2012-04-15
  • 1970-01-01
  • 2018-05-20
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
相关资源
最近更新 更多