C 错误:重新定义‘;结构rsa_meth st’;

C 错误:重新定义‘;结构rsa_meth st’;,c,struct,openssl,openssl-engine,C,Struct,Openssl,Openssl Engine,我正在尝试开发一个RSA引擎。在我尝试将我的引擎与apachehttpd服务器集成之前,我的引擎一直在工作。在从源代码安装httpd之后,我无法再编译引擎代码了。我在尝试编译时遇到了以下错误(它以前是编译的,我没有对引擎代码进行任何更改) 我的示例源代码如下所示 #include <openssl/opensslconf.h> #include <stdio.h> #include <string.h> #include <unistd.h> #i

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

我的示例源代码如下所示

#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 ()
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*以ossl_标准h声明*/
/*typedef结构rsa_方法st rsa_方法*/
//#ifndef包括_OSSL _TYP
//#定义包含类型
结构rsa\u方法{
常量字符*名称;
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*mctx);
int(*init)(RSA*RSA);
内部(*饰面)(RSA*RSA);
国际旗帜;
字符*应用程序数据;
int(*rsa_-sign)(int类型,常量无符号字符*m,无符号整数m_长度,无符号字符*sigret,无符号整数*siglen,常量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位,BIGNUM*e,BN_GENCB*cb);
};
//#恩迪夫
静态int eng_rsa_pub_enc(int flen,const unsigned char*from,unsigned char*to,rsa*rsa,int padding){
printf(“引擎正在使用发布密钥进行加密\n”);
}
静态int eng_rsa_pub_dec(int flen,const unsigned char*from,unsigned char*to,rsa*rsa,int padding){
printf(“引擎正在使用发布密钥进行解密\n”);
}
静态int eng_rsa_priv_enc(int flen,const unsigned char*from,unsigned char*to,rsa*rsa,int padding uu属性(未使用))){
printf(“引擎正在使用私钥加密”);
}
静态int eng_rsa_priv_dec(int-flen,无符号字符*from,无符号字符*to,rsa*rsa,int-padding u属性(未使用))){
printf(“引擎正在使用priv-key进行解密”);
}
/*创建引擎时使用的常量*/
静态常量char*engine\u rsa\u id=“r\u engine”;
静态常量char*engine\u rsa\u name=“演示引擎”;
结构rsa\u方法st new\u rsa=
{
“演示RSA引擎”,
英国皇家音乐学院,
12月1日,
私人工程,
12月1日,
无效的
无效的
无效的
无效的
RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE,
无效的
无效的
无效的
无效的
};
静态int绑定(引擎*e,常量字符*id){
printf(“%s\n”,id);
如果(!引擎设置id(e,引擎rsa\U id)||
!引擎集名称(e,引擎集名称)||
!ENGINE_set_RSA(e和new_RSA))
返回0;
返回1;
}
实现动态绑定(绑定)
实施动态检查
我注意到,使用新版本的操作系统,我的代码编译和运行良好。 我知道
ossl\u typ.h
文件中定义了
struct rsa\u meth\st
,但之前没有引发任何错误,但为什么现在


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

这似乎是一个使用OpenSSL的两个不同分支构建的案例。在
1.0.2
1.1.1
分支之间,有相当多的类型是不透明的。这意味着在
1.0.2
中公开可见的某些结构定义在
1.1.1
中是私有的。您的
struct rsa\u meth\st
就是其中之一。因此,您的代码是使用
1.1.1
编译的,而不是使用
1.0.2
编译的

问题的解决方案取决于要使用哪个OpenSSL版本。在任何一种情况下,都必须从代码中删除整个
struct rsa\u meth\st
定义。如果您打算使用
1.0.2
(现在不受支持)进行构建,那么它的定义已经为人所知,并通过头文件公开,因此您无需自己重复。如果要使用
1.1.1
进行构建,则必须使用相应的
RSA\u meth\u set\u()函数


通常,当您看到像
typedef struct rsa\u meth\u st rsa\u METHOD
这样的构造时,通常不应该自己定义同一个结构,因为它已经在其他地方定义(可见或隐藏)。相反,您应该通过
RSA\u方法
或者更可能的是,
RSA\u方法*

引用该类型,为什么要注释掉include-guard?“这可能就是问题所在。”托夫罗,我试过了。使用
包含保护
,该功能不起作用。同样的问题依然存在。@tofro,同样,在我的另一台机器上,同样的代码也在工作。没有任何警卫。谢谢你的澄清。我使用的是OpenSSL 1.1.1c。我发现OpenSSL文档有点难以理解。目前,我正在使用(openssl/engines/e_dasync.c)[中的示例代码,与您建议的完全相同。我的完整示例源代码可在此处获得(rsa engine.c)[然而,即使在使用了OpenSSL存储库中的示例代码之后,我仍收到以下警告,
rsa engine.c:在函数“bind_dasync”:rsa engine.c:64:30:警告:函数“rsa_meth_new”的隐式声明[-Wimplicit函数声明]
发生此问题时,您确定是针对OpenSSL 1.1.1进行编译吗?您可以看到该函数已声明。您可以添加检查以验证版本
#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 ()