我有旧的代码,用于链接旧版本的openssl。此代码的一部分从PEM文件加载密钥,并尝试通过使用以下代码来了解此密钥是私钥还是公钥:
if( (prv->p==0 || prv->q==0) ) {
// This is not a private key!
throw error("No private key for decryption");
}
使用最新版本的openssl,这(理所当然)无法编译:
crypto.cpp: In function ‘key* decrypt_header(file_t, RSA*)’:
crypto.cpp:158:13: error: invalid use of incomplete type ‘RSA {aka struct rsa_st}’
if( (prv->p==0 || prv->q==0) ) {
^~
我理解直接访问struct的私有成员已被一个函数替换,但我很难搞清楚哪个函数。
答案 0 :(得分:8)
crypto.cpp:158:13: error: invalid use of incomplete type ‘RSA {aka struct rsa_st}’
if( (prv->p==0 || prv->q==0) ) {
^~
如您所知,OpenSSL 1.1.0改变了许多struct成员的可见性。您无法再直接访问成员。相反,你必须使用getter和setter函数。
试试RSA_get0_factors
。 get0
表示引用计数 不 递增。 不 BN_free
他们。
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
如果代码支持多个版本的OpenSSL,那么您将需要一个防护,因为RSA_get0_factors
适用于OpenSSL 1.1.0及更高版本。也许类似以下内容。另请参阅OPENSSL_VERSION_NUMBER
man page。
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* OpenSSL 1.0.2 and below (old code) */
#else
/* OpenSSL 1.1.0 and above (new code) */
#endif
答案 1 :(得分:2)
在1.1.1之后,OpenSSL支持getter这样返回每个参数。
const BIGNUM *RSA_get0_n(const RSA *d);
const BIGNUM *RSA_get0_e(const RSA *d);
const BIGNUM *RSA_get0_d(const RSA *d);
const BIGNUM *RSA_get0_p(const RSA *d);
const BIGNUM *RSA_get0_q(const RSA *d);
const BIGNUM *RSA_get0_dmp1(const RSA *r);
const BIGNUM *RSA_get0_dmq1(const RSA *r);
const BIGNUM *RSA_get0_iqmp(const RSA *r);
因此,如果您不需要考虑低于1.1.1的OpenSSL版本,这些代码将成为简单的代码。 AND其他结构也支持这种吸气剂。您可以找到有关此功能的更多信息。 https://www.openssl.org/docs/man1.1.1/man3/
答案 2 :(得分:0)
#if OPENSSL_VERSION_NUMBER < 0x10100005L
static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d, const BIGNUM **p, const BIGNUM **q)
{
if(n != NULL)
*n = r->n;
if(e != NULL)
*e = r->e;
if(d != NULL)
*d = r->d;
if(p != NULL)
*p = r->p;
if(q != NULL)
*q = r->q;
}
#endif
const BIGNUM *bn_p;
const BIGNUM *bn_q;
RSA_get0_key(key, NULL, NULL, NULL, &bn_p, &bn_q);
/* if( (prv->p==0 || prv->q==0) ) { */
if( (prv_p==0 || prv_q==0) ) {