我们在Windows7 SP1 VM上有一个客户端应用程序,具有适当的修补程序和注册表设置,以启用TLS1.2通信。我们在Windows 2019数据中心VM上有一个服务器应用程序。客户机和服务器建立一个TLS1.2会话(根据QueryContextAttributes),协商的流拖车大小为48字节(同样,根据QueryContextAttributes)。
当客户机或服务器使用四个缓冲区(一个DecryptMessage和三个SECBUFFER_EMPTY)调用SECBUFFER_EMPTY时,输出缓冲区类型为SECBUFFER_STREAM_HEADER、SECBUFFER_DATA、SECBUFFER_STREAM_TRAILER和SECBUFFER_EXTRA。
尽管谈判流拖车的大小是一些协商的字节数(例如。48 )如上所示,SECBUFFER_STREAM_TRAILER似乎总是小一些,SECBUFFER_EXTRA指向流尾的真正末尾之后的第一个字节。
例如,如果协商后的流拖尾大小为48字节,并且我们用SECBUFFER_STREAM_TRAILER缓冲区解密了一个cbBuffer为45字节的消息包,那么SECBUFFER_EXTRA缓冲区就会出现,并指向流拖车的缓冲器+ 45,并且有一个3的cbBuffer。
这在我看来是非常奇怪的。在极其技术性的意义上,它是有效的(额外的缓冲区仅用于指向以前调用DecryptMessage时没有使用的数据,而上面示例中的这3个字节则不是)。我们已经通过计算额外缓冲区是否在协商的流拖车块中来解决这个问题,如果是的话,将额外的缓冲区指针移到这些字节上,但是安全提供者甚至会将这些字节报告为“额外的数据”,或者消息包将使用更少的字节来处理其流头和/或流拖车,这似乎很奇怪。
值得注意的是,当客户端和服务器都使用比Windows 7更现代的操作系统(在Windows 2012 R2标准、Windows 2019数据中心和Windows 10上进行测试)时,似乎不存在这种行为。
发布于 2022-12-01 01:19:25
协商后的流大小表示报头和拖车的最大可能值。实际值可能较少。当客户端发送TLS应用程序数据消息时,Schannel有时会构造一个比协商大小更小的拖车,但我们的应用程序总是发送最大报头大小+应用程序数据大小+最大拖车大小字节,这将导致服务器接收额外的空字节。Schannel的DecryptMessage会将这些额外的字节报告为额外的数据,但从我们的角度来看,数据“在”预告片中。
如前所述,我们通过计算额外的缓冲区是否在我们认为是预告片的内部来解决这个问题,并将额外的数据指针移到那些空字节之后(如果在这些空字节之后有任何数据),从而使其他一切正常工作。
但是,正确实现的客户端将无法通过TLS 1.0和TLS 1.1会话与服务器通信。这导致我修复了加密逻辑中的错误,这将导致我们的应用程序发送额外的空字节,而我们的解密逻辑中的错误将导致应用程序无效地跳过那些(坏的)空字节。
https://stackoverflow.com/questions/73720038
复制相似问题