C:在cygwin上使用Openssl时声明冲突

时间:2018-09-29 18:30:58

标签: c winapi openssl cygwin rsa

我想创建一个简单的程序,该程序将使用RSA算法对字符串进行加密,然后将其解密(cygwin, windows

这是我的代码

#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <stdio.h>

#include <string.h>

#define KEY_LENGTH  2048
#define PUB_EXP     3
#define PRINT_KEYS
#define WRITE_TO_FILE

int main(void) {
    size_t pri_len;            // Length of private key
    size_t pub_len;            // Length of public key
    char   *pri_key;           // Private key
    char   *pub_key;           // Public key
    char   msg[KEY_LENGTH/8];  // Message to encrypt
    char   *encrypt = NULL;    // Encrypted message
    char   *decrypt = NULL;    // Decrypted message
    char   *err;               // Buffer for any error messages

    // Generate key pair
    printf("Generating RSA (%d bits) keypair...", KEY_LENGTH);
    fflush(stdout);
    RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);

    // To get the C-string PEM form:
    BIO *pri = BIO_new(BIO_s_mem());
    BIO *pub = BIO_new(BIO_s_mem());

    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);

    pri_len = BIO_pending(pri);
    pub_len = BIO_pending(pub);

    pri_key = (char *)malloc(pri_len + 1);
    pub_key = (char *)malloc(pub_len + 1);

    BIO_read(pri, pri_key, pri_len);
    BIO_read(pub, pub_key, pub_len);

    pri_key[pri_len] = '\0';
    pub_key[pub_len] = '\0';

    #ifdef PRINT_KEYS
        printf("\n%s\n%s\n", pri_key, pub_key);
    #endif
    printf("done.\n");

    // Get the message to encrypt
    printf("Message to encrypt: ");
    fgets(msg, KEY_LENGTH-1, stdin);
    msg[strlen(msg)-1] = '\0';

    // Encrypt the message
    encrypt = (char *)malloc(RSA_size(keypair));
    int encrypt_len;
    err = (char *)malloc(130);
    if((encrypt_len = RSA_public_encrypt(strlen(msg)+1, (unsigned char*)msg, (unsigned char*)encrypt,
                                         keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        return -1;
    }

    #ifdef WRITE_TO_FILE
    // Write the encrypted message to a file
        FILE *out = fopen("out.bin", "w");
        fwrite(encrypt, sizeof(*encrypt),  RSA_size(keypair), out);
        fclose(out);
        printf("Encrypted message written to file.\n");
        free(encrypt);
        encrypt = NULL;

        // Read it back
        printf("Reading back encrypted message and attempting decryption...\n");
        encrypt = (char *)malloc(RSA_size(keypair));
        out = fopen("out.bin", "r");
        fread(encrypt, sizeof(*encrypt), RSA_size(keypair), out);
        fclose(out);
    #endif

    // Decrypt it
    decrypt = (char *)malloc(encrypt_len);
    if(RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned char*)decrypt,
                           keypair, RSA_PKCS1_OAEP_PADDING) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error decrypting message: %s\n", err);
            return -1;
    }
    printf("Decrypted message: %s\n", decrypt);


    RSA_free(keypair);
    BIO_free_all(pub);
    BIO_free_all(pri);
    free(pri_key);
    free(pub_key);
    free(encrypt);
    free(decrypt);
    free(err);

    return 0;
}

我遇到的问题是在使用命令编译时

$ gcc -I /usr/include/ -L /usr/lib/ ip.cpp -o ip.exe -lcrypto

这是我的错误:

In file included from /usr/include/errno.h:9:0,
                 from /usr/include/openssl/err.h:140,
                 from ip.cpp:9:
/usr/include/sys/errno.h:14:0: warning: "errno" redefined
 #define errno (*__errno())
 ^
In file included from /usr/lib/gcc/x86_64-w64-mingw32/4.9.2/include/stddef.h:1:0,
                 from /usr/include/sys/cdefs.h:45,
                 from /usr/include/time.h:11,
                 from /usr/include/openssl/asn1.h:62,
                 from /usr/include/openssl/rsa.h:62,
                 from ip.cpp:7:
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stddef.h:19:0: note: this is the location of the previous definition
 #define errno (*_errno())
 ^
In file included from /usr/include/sys/select.h:26:0,
                 from /usr/include/sys/types.h:85,
                 from /usr/include/time.h:28,
                 from /usr/include/openssl/asn1.h:62,
                 from /usr/include/openssl/rsa.h:62,
                 from ip.cpp:7:
/usr/include/sys/_timeval.h:40:18: error: conflicting declaration ‘typedef long int time_t’
 typedef _TIME_T_ time_t;
                  ^
In file included from /usr/x86_64-w64-mingw32/sys-root/mingw/include/stddef.h:7:0,
                 from /usr/lib/gcc/x86_64-w64-mingw32/4.9.2/include/stddef.h:1,
                 from /usr/include/sys/cdefs.h:45,
                 from /usr/include/time.h:11,
                 from /usr/include/openssl/asn1.h:62,
                 from /usr/include/openssl/rsa.h:62,
                 from ip.cpp:7:
/usr/x86_64-w64-mingw32/sys-root/mingw/include/crtdefs.h:138:20: note: previous declaration as ‘typedef __time64_t time_t’
 typedef __time64_t time_t;

如您所见,第一个错误是errno被定义了两次。我检查了一下,在errno.h中有以下代码:

#ifndef _REENT_ONLY
#define errno (*__errno())

定义_REENT_ONLY可以解决此错误,但是在stdio.h中存在以下问题:

#ifndef _REENT_ONLY
FILE *  _EXFUN(fopen, (const char *__restrict _name, const char *__restrict _type));

所以我有fopen undefined error。另外,我认为在不真正了解其含义的情况下定义一些值不是一个好主意。

然后我尝试手动注释掉第二次定义数据的行,以成功构建它并测试程序,但是我得到了:

/tmp/ccC3voSz.o:ip.cpp:(.rdata$.refptr._impure_ptr[.refptr._impure_ptr]+0x0): undefined reference to `_impure_ptr'

所以最后我有两个问题(也许它们甚至以某种方式相关):

如何摆脱声明冲突?

如何修复undefined reference to _impure_ptr

0 个答案:

没有答案