pkcs#11 - 如果派生密钥 CKA_DERIVE=0,C_DeriveKey 的正确错误代码是什么
问题描述
我是 PKCS#11 库的开发人员。我认为函数 C_DeriveKey 应该失败并显示错误代码
CKR_KEY_FUNCTION_NOT_PERMITTED
如果键有。但是此错误代码未在规范文档CKA_DERIVE=0
中列为可能的返回值。在这种情况下要返回的正确错误代码是什么?C_DeriveKey
C_DeriveKey
解决方案
我同意这个案例的规范不是很清楚。有一个更新版本的规范可用(2020 年 3 月的 v3.0,链接),但它并没有带来更多的清晰度。我会考虑以下几点:
返回值的一般说明
5.1 节中关于返回值的介绍给出了以下免责声明(链接):
由于 Cryptoki 规范的复杂性,建议 Cryptoki 应用程序在解释 Cryptoki 函数的返回值时尝试给一些余地。我们试图尽可能完整地指定 Cryptoki 函数的行为;尽管如此,大概还是有一些差距。 例如,很遗憾,可能适用于特定 Cryptoki 函数的特定错误代码实际上并未作为可能的错误代码列在该函数的描述中。
最后一部分直接承认每个函数的可能返回值列表可能不完整。因此,如果函数应返回此值的原因还有其他原因,则未将其列为可能的返回代码可能不具有权威性C_DeriveKey
。CKR_KEY_FUNCTION_NOT_PERMITTED
返回码的定义
第 5.1.6 节给出了以下定义(链接):
CKR_KEY_FUNCTION_NOT_PERMITTED:已尝试将密钥用于加密目的,但未将密钥的属性设置为允许这样做。例如,要使用密钥执行加密,该密钥必须将其 CKA_ENCRYPT 属性设置为 CK_TRUE(密钥必须具有 CKA_ENCRYPT 属性的事实意味着该密钥不能是私钥)。此返回值的优先级低于 CKR_KEY_TYPE_INCONSISTENT。
CKR_KEY_TYPE_INCONSISTENT:指定的密钥不是与指定机制一起使用的正确密钥类型。此返回值的优先级高于 CKR_KEY_FUNCTION_NOT_PERMITTED。
根据这个定义,我会得出结论,这CKR_KEY_TYPE_INCONSISTENT
不是我们正在讨论的场景的正确返回代码,因为它将机制与密钥的“类型”相关联。如果我们从 的意义上理解“类型” CKA_KEY_TYPE
,它与属性完全无关CKA_DERIVE
。
此外,该属性CKA_ENCRYPT
在 的定义中作为示例给出CKR_KEY_FUNCTION_NOT_PERMITTED
。该属性与 非常相似CKA_DERIVE
,即CKA_ENCRYPT
控制密钥是否可以用于加密和CKA_DERIVE
控制密钥是否可以用于导出。因此,如果CKR_KEY_FUNCTION_NOT_PERMITTED
是未设置时的情况的正确返回码,那么对于CKA_ENCRYPT
未设置时的情况,它也是正确的返回码似乎是合理的CKA_DERIVE
。
参考实现
我查看了一些 PKCS#11 库以检查它们如何处理在设置为C_DeriveKey
的键上调用的情况。我发现的大多数实现根本没有实现该功能(即它们总是 return )。对于实现此功能的库,我观察到以下行为:CKA_DERIVE
CK_FALSE
C_DeriveKey
CKR_FUNCTION_NOT_SUPPORTED
OpenSC返回
CKR_KEY_TYPE_INCONSISTENT
(参考):CK_ATTRIBUTE derive_attribute = { CKA_DERIVE, &can_derive, sizeof(can_derive) }; ... rv = object->ops->get_attribute(session, object, &derive_attribute); if (rv != CKR_OK || !can_derive) { rv = CKR_KEY_TYPE_INCONSISTENT; goto out; }
我还检查了 OpenSC 如何处理与
CKA_DERIVE
. 似乎该C_EncryptInit
功能没有在 OpenSC 中实现(大概是因为这是一个公钥操作?),但是C_DecryptInit
。该函数实现了对CKA_DECRYPT
( reference ) 的检查,但返回CKR_KEY_TYPE_INCONSISTENT
了 ,这与 的规范中给出的示例背道而驰CKR_KEY_FUNCTION_NOT_PERMITTED
。SoftHSMv2返回
CKR_KEY_FUNCTION_NOT_PERMITTED
(参考):// Check if key can be used for derive if (!key->getBooleanValue(CKA_DERIVE, false)) return CKR_KEY_FUNCTION_NOT_PERMITTED;
openCryptoki:我找不到任何检查
CKA_DERIVE
。他们确实检查CKF_DERIVE
机制的功能标志,CKR_MECHANISM_INVALID
如果没有设置标志(参考),即如果机制不支持派生,则返回,但这与检查CKA_DERIVE
密钥的标志不同。illumos-gate(IllumOS 是已停产的 OpenSolaris 的一个分支)也在
CKR_KEY_FUNCTION_NOT_PERMITTED
其软键实现中返回(参考):/* Check to see if key object allows for derivation. */ if (!(basekey_p->bool_attr_mask & DERIVE_BOOL_ON)) { rv = CKR_KEY_FUNCTION_NOT_PERMITTED; goto clean_exit1; }
有趣的是,在他们的旧版本代码中,他们
CKR_KEY_TYPE_INCONSISTENT
改为返回,然后CKR_KEY_FUNCTION_NOT_PERMITTED
在此提交中将其更改为。提交消息的相关部分似乎是6177650 Wrong error code returned when key does not allow requested operation
. 该 ID 指的是 OpenSolaris 错误跟踪器中的票证,该票证已不再在线。这里有一个错误跟踪器的存档,但不幸的是,它不包含有关此票证的任何信息。
在这些参考实现中,就其使用范围而言,我认为 OpenSC 是最权威的。
结论
基于以上考虑,我认为CKR_KEY_FUNCTION_NOT_PERMITTED
是我们正在讨论的场景的合适返回码。以下论点支持这一点:
该规范明确承认每个函数的可能返回代码列表可能不完整。因此,
CKR_KEY_FUNCTION_NOT_PERMITTED
不被列入名单C_DeriveKey
并不是一个强有力的反驳论点。规范明确列出了何时是适当的返回码
CKA_ENCRYPT
的示例。CKR_KEY_FUNCTION_NOT_PERMITTED
该属性CKA_ENCRYPT
类似于CKA_DERIVE
,因此返回码也适用于 似乎是合理的CKA_DERIVE
。规范
CKR_KEY_TYPE_INCONSISTENT
建议它是关于机制和密钥类型之间的关系,而不是关于其他密钥属性。OpenSC用于我们正在讨论的场景,但在未设置的情况下
CKR_KEY_TYPE_INCONSISTENT
也使用此返回码,这与.C_DecryptInit
CKA_DECRYPT
CKR_KEY_FUNCTION_NOT_PERMITTED
OpenSolaris/IllumOS 故意从 切换
CKR_KEY_TYPE_INCONSISTENT
到CKR_KEY_FUNCTION_NOT_PERMITTED
作为我们正在讨论的场景的返回码。这表明他们还认为后者是更合适的返回代码。
推荐阅读
- angular - 如何使用spring boot后端使角度应用程序仅接收来自局域网的请求?
- python - python - 如何在python中为矩阵或二维数组的每个元素设置特定条件?
- android - 尝试访问该方法时出错,因为“没有@Provides-annotated 方法就无法提供”
- reactjs - 子组件放在类组件的静态属性上时返回未定义
- android - 无法在 Mapbox 中显示多边形特征:文档已过时且示例不起作用
- c# - web.config 将文件夹名称重定向到文件名
- symfony - 更新哪个 Doctrine 生命周期事件?
- java - 在 AsynchronousSocketChannel Reas/Connection 处理程序中找不到符号
- javascript - 倒计时之前/之后的Javascript动画
- javascript - 将threejs网格包裹在另一个网格上