user45698746
user45698746

Reputation: 315

error: redefinition of ‘struct rsa_meth_st’

I'm trying to develop an RSA engine. My engine was somewhat working until I try to integrate my engine with an apache httpd server. After installing the httpd from the source code, it turns out that, I can't compile my engine code anymore. I get the following error while I try to compile (it was compiling before and I did not make any changes to my engine code).

$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;

My sample source code is like the following,

#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 ()

I notice that, with a fresh version of OS, my code compiles and runs well. I understand that struct rsa_meth_st was defined in ossl_typ.h file, but that did not throw any error previously but why now?

My gcc version is gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

Upvotes: 1

Views: 795

Answers (1)

Reinier Torenbeek
Reinier Torenbeek

Reputation: 17363

This seems like a case where you have been building with two different branches of OpenSSL. Between the 1.0.2 and the 1.1.1 branches, quite a few types were made opaque. This means that certain structure definitions that were publicly visible in 1.0.2 are private in 1.1.1. Your struct rsa_meth_st is one of them. Therefore your code compiles with 1.1.1 but not with 1.0.2.

The solution to your problem depends on which OpenSSL version you want to use. In either case, you have to remove the entire struct rsa_meth_st definition from your code. If you intend to build with 1.0.2 (which is now out of support), then its definition is known already and exposed via the header files so you don't need to repeat it yourself. If you intend to build with 1.1.1, you have to use RSA_meth_new() followed by the appropriate RSA_meth_set_() functions.

In general, when you see constructs like typedef struct rsa_meth_st RSA_METHOD you are typically not supposed to define that same struct yourself because it is already defined somewhere else (visibly or hidden). Instead, you should refer to that type via RSA_METHOD or, more likely, RSA_METHOD *.

Upvotes: 1

Related Questions