【问题标题】:error: redefinition of ‘struct rsa_meth_st’错误:重新定义“struct rsa_meth_st”
【发布时间】:2021-07-07 00:13:22
【问题描述】:

我正在尝试开发一个 RSA 引擎。在我尝试将我的引擎与 apache httpd 服务器集成之前,我的引擎一直在工作。从源代码安装httpd后,事实证明,我无法编译我的引擎代码了。尝试编译时出现以下错误(之前正在编译,我没有对引擎代码进行任何更改)。

$gcc -fPIC -c r_engine.c
r_engine.c:29:8: error: redefinition of ‘struct rsa_meth_st’
struct rsa_meth_st {
    ^ 
In file included from /usr/include/openssl/crypto.h:131:0,
             from r_engine.c:7:
/usr/include/openssl/ossl_typ.h:147:16: note: originally defined here
typedef struct rsa_meth_st RSA_METHOD;

我的示例源代码如下,

#include <openssl/opensslconf.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/engine.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/ossl_typ.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>


/* Declared in ossl_typ.h */
/* typedef struct rsa_meth_st RSA_METHOD; */

//#ifndef INCLUDE_OSSL_TYP_H
//#define INCLUDE_OSSL_TYP_H

struct rsa_meth_st {

const char *name;
int (*rsa_pub_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_pub_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding);
int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int (*init) (RSA *rsa);
int (*finish) (RSA *rsa);
int flags;
char *app_data;
int (*rsa_sign) (int type, const unsigned char *m, unsigned int m_length, unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
int (*rsa_verify) (int dtype, const unsigned char *m, unsigned int m_length, const unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
};
//#endif


static int eng_rsa_pub_enc (int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding){
    printf ("Engine is encrypting using pub key \n");
}

static int eng_rsa_pub_dec (int flen, const unsigned char *from,  unsigned char *to, RSA * rsa, int padding){
    printf ("Engine is decrypting using pub key \n");
}

static int eng_rsa_priv_enc (int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding __attribute__ ((unused))){
    printf ("Engine is encrypting using priv key \n");
}

static int eng_rsa_priv_dec (int flen, unsigned char *from, unsigned char *to, RSA * rsa, int padding __attribute__ ((unused))){
    printf ("Engine is decrypting using priv key \n");
}

/* Constants used when creating the ENGINE */
static const char *engine_rsa_id = "r_engine";
static const char *engine_rsa_name = "Demo engine";

struct rsa_meth_st new_rsa =
    {
            "demo RSA Engine",
            eng_rsa_pub_enc,
            eng_rsa_pub_dec,
            eng_rsa_priv_enc,
            eng_rsa_priv_dec,
            NULL,
            NULL,
            NULL,
            NULL,
            RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
            NULL,
            NULL,
            NULL,
            NULL
    };

static int bind (ENGINE * e, const char *id){
printf ("%s\n", id);

if (!ENGINE_set_id (e, engine_rsa_id) ||

    !ENGINE_set_name (e, engine_rsa_name) ||

    !ENGINE_set_RSA (e, &new_rsa))

    return 0;

return 1;

}

IMPLEMENT_DYNAMIC_BIND_FN (bind)
IMPLEMENT_DYNAMIC_CHECK_FN ()

我注意到,使用新版本的操作系统,我的代码编译和运行良好。 我知道struct rsa_meth_st 是在ossl_typ.h 文件中定义的,但之前没有抛出任何错误,但为什么现在?

我的gcc versiongcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

【问题讨论】:

  • 你为什么注释掉包含守卫?这可能就是问题所在。
  • @tofro,我试过了。使用include guard,那不起作用。同样的问题仍然存在。
  • @tofro,同样,在我的另一台机器上,同样的代码正在工作。没有任何守卫。

标签: c struct openssl openssl-engine


【解决方案1】:

这似乎是您一直在使用 OpenSSL 的两个不同分支进行构建的情况。在1.0.21.1.1 分支之间,有不少类型是不透明的。这意味着在1.0.2 中公开可见的某些结构定义在1.1.1 中是私有的。您的struct rsa_meth_st 就是其中之一。因此,您的代码可以使用 1.1.1 编译,但不能使用 1.0.2

您的问题的解决方案取决于您要使用的 OpenSSL 版本。无论哪种情况,您都必须从代码中删除整个 struct rsa_meth_st 定义。如果您打算使用1.0.2(现在不支持)进行构建,那么它的定义已经知道并通过头文件公开,因此您无需自己重复。如果您打算使用 1.1.1 构建,则必须使用 RSA_meth_new() 后跟相应的 RSA_meth_set_() 函数。

一般来说,当您看到像 typedef struct rsa_meth_st RSA_METHOD 这样的结构时,您通常不应该自己定义相同的结构,因为它已经在其他地方定义(可见或隐藏)。相反,您应该通过RSA_METHOD 或更可能的是RSA_METHOD * 来引用该类型。

【讨论】:

  • 感谢您的澄清。我正在使用 OpenSSL 1.1.1c。我发现 OpenSSL 文档有点难以理解。目前,我正在使用来自 (openssl/engines/e_dasync.c)[github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/engines/… 的示例代码,这与您的建议非常相似。我的完整示例源代码可在此处获得 (rsa-engine.c)[pastebin.com/EQfpF7cm]
  • 但是,即使在使用 OpenSSL 存储库中的示例代码之后,我也会收到以下警告,rsa-engine.c: In function ‘bind_dasync’: rsa-engine.c:64:30: warning: implicit declaration of function ‘RSA_meth_new’ [-Wimplicit-function-declaration]
  • 发生此问题时,您确定要针对 OpenSSL 1.1.1 进行编译吗?你可以看到这个函数被声明为here。您可以添加检查以在编译时验证版本,如文档中的here
  • 是的。我正在针对 OpenSSL 1.1.1c 进行编译。我的 openSSL 版本检查显示了这一点,xxx@xxx:~/Downloads/test_engine$ openssl version OpenSSL 1.1.1c 28 May 2019。奇怪的是,我有两台具有相同内核/GCC/OpenSSL 版本的机器。在一台机器上它在另一台机器上工作,我收到上述错误。
  • 您显示的是运行时检查,而不是编译时间。在您的代码中添加一些内容,例如 #if OPENSSL_VERSION_NUMBER &lt; 0x10100000 #error "Require OpenSSL 1.1" #endif 并编译它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多