从命令行测试自定义 openSSL 引擎
Testing a custom openSSL engine from the command line
小问题:如何验证我从命令行编写的自定义 openSSL 引擎的功能?
现在我正在跟随 this great tutorial, and am successfully able to exercise the engine (which returns a digest value of all 2's) using my test program (source code here,测试程序位于 test/wssha256engine_test.c)。
brett@wintermute:~/openssl_ws/wssha256engine$ make test
make[1]: Entering directory
/home/brett/openssl_ws/wssha256engine/test
make[1]: '../bin/test' is up to date.
make[1]: Leaving directory
/home/brett/openssl_ws/wssha256engine/test
brett@wintermute:~/openssl_ws/wssha256engine$ bin/test
Engine Loaded...
Initializing wssha256 engine...
*TEST: Successfuly initialized engine [A test engine for the ws sha256 hardware encryption module, on the Xilinx ZYNQ7000]
init result = 1
Digest NID=672 requested
SHA256 algorithm context initialized
*TEST: Digest INIT 1
SHA256 update
*TEST: Digest Update 1
SHA256 final: sizeof(EVP_MD)= 120
SHA256 cleanup
*TEST: Digest Final 1 Digest size:32
22222222222222222222222222222222
但是,由于某些原因,我还想使用 openssl 命令行界面来练习我刚刚编写的引擎,并让它像 this other tutorial 中那样计算随机字符串的摘要,仅使用 sha256而不是 md5。
但是当我尝试这样做时,引擎没有加载并导致错误告诉我我的摘要的 NID 不存在,而是用标准算法对字符串进行哈希处理:
brett@wintermute:~/openssl_ws/wssha256engine$ echo "Hello" | openssl dgst -engine /home/brett/Thesis/openssl_ws/wssha256engine/bin/libwssha256engine.so -sha256
ERROR: Digest is empty! (NID = 0)
engine "wssha256" set.
(stdin)= 66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18
为什么我不能在命令行上使用我的引擎,但我可以创建一个 C 程序来加载它?我如何使用我的引擎从命令行计算摘要?
注意:我可以从命令行加载引擎,只是不使用它。
经过一些挖掘,我能够弄清楚为什么我的引擎的 CLI 调用不起作用,并解决了这个问题。
问题出在我的摘要选择器函数中(原始损坏的代码在下面被注释掉了)。最初,我 return 从摘要选择器函数中输入了失败状态,而不是 return 引擎支持的摘要 ID 的数量。
static int wssha256engine_digest_selector(ENGINE *e, const EVP_MD **digest, const int **nids, int nid)
{
if (!digest)
{
*nids = wssha256_digest_ids;
// THIS ORIGINAL CODE CAUSES THE ENGINE TO NEVER INITIALIZE FROM A CLI INVOCATION
//printf("ERROR: Digest is empty! (NID = %d)\n",nid);
//return FAIL;
// THIS FIXES IT
int retnids = sizeof(wssha256_digest_ids - 1) / sizeof(wssha256_digest_ids[0]);
printf("wssha256engine: digest nids requested...returning [%d]\n",retnids);
return retnids;
}
仔细阅读,我们可以发现OpenSSL通过以下(单独)方式调用摘要选择器函数:
- 摘要为 NULL。在这种情况下,*nids 应该被分配一个
NID 的零终止数组和带有可用 NID 数量的调用 returns。 OpenSSL 使用它来确定此引擎支持哪些摘要。
- 摘要为非 NULL。在这种情况下,*digest 应该被分配指向与 nid 给出的 NID 相对应的 EVP_MD 结构的指针。如果请求 NID 是该引擎支持的,则调用 returns 为 1,否则为 0。
所以即使我的引擎支持 sha256,CLI 调用也不起作用,因为在调用摘要选择器函数之前它一定没有用摘要初始化(不知道使用 CLI 时的操作顺序).然而,当我在我的测试程序中手动初始化它时,一切正常。更改为非失败 return 值以支持调用 1. 以上解决了问题。
小问题:如何验证我从命令行编写的自定义 openSSL 引擎的功能?
现在我正在跟随 this great tutorial, and am successfully able to exercise the engine (which returns a digest value of all 2's) using my test program (source code here,测试程序位于 test/wssha256engine_test.c)。
brett@wintermute:~/openssl_ws/wssha256engine$ make test
make[1]: Entering directory
/home/brett/openssl_ws/wssha256engine/test
make[1]: '../bin/test' is up to date.
make[1]: Leaving directory
/home/brett/openssl_ws/wssha256engine/test
brett@wintermute:~/openssl_ws/wssha256engine$ bin/test
Engine Loaded...
Initializing wssha256 engine...
*TEST: Successfuly initialized engine [A test engine for the ws sha256 hardware encryption module, on the Xilinx ZYNQ7000]
init result = 1
Digest NID=672 requested
SHA256 algorithm context initialized
*TEST: Digest INIT 1
SHA256 update
*TEST: Digest Update 1
SHA256 final: sizeof(EVP_MD)= 120
SHA256 cleanup
*TEST: Digest Final 1 Digest size:32
22222222222222222222222222222222
但是,由于某些原因,我还想使用 openssl 命令行界面来练习我刚刚编写的引擎,并让它像 this other tutorial 中那样计算随机字符串的摘要,仅使用 sha256而不是 md5。
但是当我尝试这样做时,引擎没有加载并导致错误告诉我我的摘要的 NID 不存在,而是用标准算法对字符串进行哈希处理:
brett@wintermute:~/openssl_ws/wssha256engine$ echo "Hello" | openssl dgst -engine /home/brett/Thesis/openssl_ws/wssha256engine/bin/libwssha256engine.so -sha256
ERROR: Digest is empty! (NID = 0)
engine "wssha256" set.
(stdin)= 66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18
为什么我不能在命令行上使用我的引擎,但我可以创建一个 C 程序来加载它?我如何使用我的引擎从命令行计算摘要?
注意:我可以从命令行加载引擎,只是不使用它。
经过一些挖掘,我能够弄清楚为什么我的引擎的 CLI 调用不起作用,并解决了这个问题。
问题出在我的摘要选择器函数中(原始损坏的代码在下面被注释掉了)。最初,我 return 从摘要选择器函数中输入了失败状态,而不是 return 引擎支持的摘要 ID 的数量。
static int wssha256engine_digest_selector(ENGINE *e, const EVP_MD **digest, const int **nids, int nid)
{
if (!digest)
{
*nids = wssha256_digest_ids;
// THIS ORIGINAL CODE CAUSES THE ENGINE TO NEVER INITIALIZE FROM A CLI INVOCATION
//printf("ERROR: Digest is empty! (NID = %d)\n",nid);
//return FAIL;
// THIS FIXES IT
int retnids = sizeof(wssha256_digest_ids - 1) / sizeof(wssha256_digest_ids[0]);
printf("wssha256engine: digest nids requested...returning [%d]\n",retnids);
return retnids;
}
仔细阅读,我们可以发现OpenSSL通过以下(单独)方式调用摘要选择器函数:
- 摘要为 NULL。在这种情况下,*nids 应该被分配一个 NID 的零终止数组和带有可用 NID 数量的调用 returns。 OpenSSL 使用它来确定此引擎支持哪些摘要。
- 摘要为非 NULL。在这种情况下,*digest 应该被分配指向与 nid 给出的 NID 相对应的 EVP_MD 结构的指针。如果请求 NID 是该引擎支持的,则调用 returns 为 1,否则为 0。
所以即使我的引擎支持 sha256,CLI 调用也不起作用,因为在调用摘要选择器函数之前它一定没有用摘要初始化(不知道使用 CLI 时的操作顺序).然而,当我在我的测试程序中手动初始化它时,一切正常。更改为非失败 return 值以支持调用 1. 以上解决了问题。