【发布时间】:2015-09-30 10:25:34
【问题描述】:
我一直在研究涉及密码学的东西。我必须承认,我的密码学知识非常基础。所以我决定看看RSA_generate_key从openssl库生成RSA密钥后RSA结构包含什么。但我遇到了分段错误:
const unsigned long e = 3;
const int num = 3072;
...
RSA *rsa_key = RSA_generate_key(num, e, NULL, NULL);
if (!rsa_key)
{
printf("Failed to generate RSA key!\n");
return RSA_ERROR_CODE;
}
printf("rsa->pad=0x%x\n", rsa_key->pad);
printf("rsa->version=0x%lx\n", rsa_key->version);
if (rsa_key->n)
{
printf("rsa->n->top=0x%x\n", rsa_key->n->top); // HERE I got the seg fault
....
这对我来说看起来很奇怪,所以我编写了一个最小的代码来使用valgrind tool 对其进行测试。这是C中的代码:
#include "openssl/rsa.h"
#include <stdio.h>
int main()
{
const unsigned long e = 3; // the exponent, 3 in QVRSA
const int num = 3072;
RSA *rsa_key = RSA_generate_key(num, e, NULL, NULL);
if (rsa_key == NULL)
{
printf("RSA is invalid!\n");
return 1;
}
printf("rsa->pad=0x%x\n", rsa_key->pad);
printf("rsa->version=0x%lx\n", rsa_key->version);
if (rsa_key->n)
{
printf("rsa->n->top=0x%x\n", rsa_key->n->top);
}
RSA_free(rsa_key);
rsa_key = NULL;
return 0;
}
编译行:gcc rsa.c -lcrypto -g -O0 -o rsa
这次没有分段错误,输出为:
rsa->pad=0x0
rsa->version=0x0
rsa->n->top=0x30
但是 valgrind 触发了大量错误消息:
==6916== Conditional jump or move depends on uninitialised value(s)
==6916== at 0x4DAEB37: BN_bin2bn (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB1B62: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x40072E: main (rsa.c:9)
==6916== Uninitialised value was created by a heap allocation
==6916== at 0x4B23D6D: malloc (vg_replace_malloc.c:270)
==6916== by 0x4D8936A: CRYPTO_malloc (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB1AD1: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x40072E: main (rsa.c:9)
==6916== Conditional jump or move depends on uninitialised value(s)
==6916== at 0x4DB44D0: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x40072E: main (rsa.c:9)
==6916== Uninitialised value was created by a heap allocation
==6916== at 0x4B23D6D: malloc (vg_replace_malloc.c:270)
==6916== by 0x4D8936A: CRYPTO_malloc (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB1AD1: ??? (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DB4471: BN_generate_prime_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DC8763: RSA_generate_key_ex (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x4DCB763: RSA_generate_key (in /usr/lib64/libcrypto.so.0.9.8)
==6916== by 0x40072E: main (rsa.c:9)
还有许多其他的条件跳转或移动取决于未初始化的值标题。
为什么? openSSL 中是否存在已知错误,或者它只是一个误报,而我的原始分段错误与我原始代码中的一些隐藏错误有关?
我用过:
gcc v4.5.2
valgrind v3.8.1
OpenSSL 0.9.8a
【问题讨论】:
-
看看openSSL FAQ:第14节
-
@Missu 谢谢。这可能是问题所在。我想知道为什么我所有的谷歌搜索都没有找到那个链接。但是我只有头文件和opensl的共享对象。我怎么知道它是不是用 -DPURIFY 编译的?
-
如果使用
openssl调试程序中的内存泄漏对您至关重要,则使用-DPURIFY标志从源代码编译openssl。这是众所周知的。只需下载 openssl 的源代码并解压,然后 cd 进入目录并输入./Configure --prefix=/usr --openssldir=/etc/ssl -shared -DPURIFY linux-(your arch)。另外,你为什么用这么旧的版本? -
@iharob 谢谢。相信我,我没有选择这个版本。这是我工作地点的默认 openSSL 版本 :)
-
好吧,他们似乎使用的是旧操作系统。可能是debian,没有其他发行版使用过这样的旧软件。