我有一个嵌入式设备,使用 mBedTLS,尝试打开到https://www.cloudflare.com并失败:
#define MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE -0x3A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */
由于硬件限制,设备仅支持以下曲线:
MBEDTLS_ECP_DP_SECP192R1
MBEDTLS_ECP_DP_SECP224R1
MBEDTLS_ECP_DP_SECP256R1
并启用了以下 TLS 扩展:
Supported Elliptic Curves
Supported Point Formats
查看 cloudflare.com 证书:https://www.ssllabs.com/ssltest/analyze.html?d=www.cloudflare.com&s=104.17.210.9
我看到 cloudflare.com 同时支持 RSA 和 ECDSA 证书。
ECDSA 服务器证书使用 256 位 EC 密钥,但该证书的颁发者使用 384 位 EC 密钥。
这就是导致设备故障的原因。设备无法验证链中的 384 位证书。
那么,这是 cloudflare.com 的问题吗?服务器是否应该看到客户端不支持其证书链中的所有曲线并改为恢复为 RSA 证书?
即设备提供了它支持的曲线列表,但服务器返回的证书链中包含不受支持的 EC。服务器是否应该审查客户端提供的“支持的椭圆曲线”TLS 扩展,或者仅在支持所有曲线时才返回证书链?
任何见解都值得赞赏。
答案1
如果您不确定协议应如何运行,请参考其定义。对于在 Internet 上广泛使用的协议,这通常是一个或多个 RFC。
在这种情况下,RFC 8422对于这种情况下必须发生什么非常明确:如果客户端不支持该证书中使用的椭圆曲线,则服务器不得尝试使用 ECC 证书。
第 5.1 节解释说,如果协商失败,服务器不得尝试协商 ECC:
收到包含一个或两个扩展的 ClientHello 的服务器必须使用客户端枚举的功能来指导其选择适当的密码套件。仅当服务器能够在使用客户端支持的曲线和点格式时成功完成握手时,才必须协商其中一个建议的 ECC 密码套件(参见第 5.3 和 5.4 节)。
注意:参与 ECDHE_ECDSA 密钥交换的服务器可以对其证书中的 ECDSA 或 EdDSA 密钥以及 ServerKeyExchange 消息中的临时 ECDH 密钥使用不同的曲线。服务器必须在这两种情况下都考虑扩展。
如果服务器不理解支持的椭圆曲线扩展、不理解支持的点格式扩展,或者在将自身限制为枚举曲线和点格式时无法完成 ECC 握手,则它不得协商使用 ECC 密码套件。根据客户端提议的和服务器支持的其他密码套件,这可能会导致致命的握手失败警报,因为缺少通用密码套件。
第 5.3 节还说:
服务器构建适当的证书链,并在证书消息中将其传达给客户端。如果客户端使用了受支持的椭圆曲线扩展,则服务器证书中的公钥必须尊重客户端对椭圆曲线的选择。无法满足此要求的服务器不得在其 ServerHello 消息中选择 ECC 密码套件。
看起来你正在向 CloudFlare 提交错误报告。
答案2
很可能是一个错误移动TLS这使得它宣传的功能/算法在实际配置中并不支持。这会让服务器感到困惑。
做一个小型独立示例程序演示此行为并将其报告给移动TLS开发人员。他们要么会告诉你这是 CloudFlare 的一个错误,要么会在他们的库中修复该错误。
因为云Flare每天为数百万用户提供服务,配置出现问题很快就会显现出来。另一方面移动TLS是一个非常特定用途的库,但远没有受到同等程度的审查。如果可以的话,我敢打赌,这里错的是 mBedTLS,而不是 CloudFlare。