错误:"无效使用不完整类型'RSA {aka struct rsa_st}"在OpenSSL 1.1.0中

时间:2016-11-11 13:45:04

标签: c openssl

我有旧的代码,用于链接旧版本的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的私有成员已被一个函数替换,但我很难搞清楚哪个函数。

3 个答案:

答案 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_factorsget0表示引用计数 递增。 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) ) {