是啥导致来自 WinHttpSendRequest 的间歇性 SEC_E_BUFFER_TOO_SMALL 错误?

Posted

技术标签:

【中文标题】是啥导致来自 WinHttpSendRequest 的间歇性 SEC_E_BUFFER_TOO_SMALL 错误?【英文标题】:What is causing intermittent SEC_E_BUFFER_TOO_SMALL error coming from WinHttpSendRequest?是什么导致来自 WinHttpSendRequest 的间歇性 SEC_E_BUFFER_TOO_SMALL 错误? 【发布时间】:2016-12-09 17:22:17 【问题描述】:

我有一个工具,它可以针对具有相同标题、相同帖子正文等的相同 URL 执行 HTTPS POST 命令多次迭代。

我遇到的是,对于某些测试人员来说,WinHttpSendRequest() 函数经常失败,随后对 GetLastError() 的调用返回 SEC_E_BUFFER_TOO_SMALL (0x80090321),记录在此处:COM Error Codes (Security and Setup)。

这不是 WinHttpSendRequest() 的记录错误代码,并且相当广泛的谷歌搜索根本没有发现任何东西。

我已经四次检查了我提供的 WinHttpSendRequest() 输入是否正确且有效,并且这些输入连续工作了数万次......直到它没有。

我无法提供 MVCE,但根据此处提供的假设,我正在寻找错误代码返回的任何可能原因。

【问题讨论】:

“我无法提供 MVCE”(最小可验证代码示例)。 由于您正在发出 secure HTTP 请求,并且遇到 security 错误,很可能WinHttpSendRequest() 本身在内部提供用于加密 HTTP 流量的安全 API 的数据缓冲区不足。这可能不是你的错。虽然很难确定,因为您没有显示任何代码.. 谢谢@RemyLebeau,这也是我的怀疑。我见过的最相关的解释在这里:github.com/dblock/waffle/pull/128(请参阅“wbond”用户在 2015 年 12 月 9 日发表的评论)。我怀疑 WinHttpSendRequest() 在内部调用 InitializeSecurityContext() 并接收 SEC_E_BUFFER_TOO_SMALL 但未处理它。我最好的选择可能是检测到该错误,然后再次尝试调用 WinHttpSendRequest(),因为后续尝试很可能会起作用。 【参考方案1】:

有人离线提供了一个答案,觉得很有趣。

在使用 RSA+ECDHE 的 TLS 1.2 中发生的密钥交换期间,ECDHE 的 256 字节(2048 位)公共模数整数是随机生成的,因此它偶尔会有一个高位字节为零。在这种情况下,正在使用的服务器(一些带有 OpenSSL 的 Linux 机器,不知道任何发行版或版本)使用 255 字节而不是 256 字节发送整数。

以略短的形式接收公共模数整数的 WinHTTP 代码显然无法正确处理它。值得注意的是,我还没有看到在所有软件更新的 Windows 7 上重现此问题,但在 Windows 8 上经常看到它(Windows 10 尚未测试)。

Microsoft Edge 中的此错误报告确认了相同的行为,只是使用了 1024 位模数而不是 2048,但可能是相同的问题:

TLS ServerKeyExchange with 1024 DHE may encode dh_Y as 127 bytes, breaking Internet Explorer 11

但是,这确实让我想知道 OpenSSL 是否应该填充整数。我没有寻找实际规范来查看在这种情况下允许的行为是什么。

【讨论】:

以上是关于是啥导致来自 WinHttpSendRequest 的间歇性 SEC_E_BUFFER_TOO_SMALL 错误?的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows Server 2008 rc2 上使用 https 的 winhttpsendrequest POST

是啥导致 PHP 出现这种延迟?

是啥导致我的堆栈中出现神秘的重复条目?

是啥导致此 Spring MVC 应用程序中的映射失败?

是啥导致soap响应在新服务器上没有返回数据?

CORBA:它是啥,为啥会产生“GIOP 魔法错误”?