PEM_read_RSAPublicKey() дает сбой в основном коде приложения, но отлично работает в примере кода. Как я могу решить эту проблему?

Я пишу код c/c++ для библиотеки Win32 Dynamic_link в Visual Studio 6. На самом деле я использую libcryptoMD.lib для реализации шифрования RSA с использованием файла pem и файла ppk. Я могу сделать это шифрование в примере кода, но PEM_read_RSAPublicKey() дает сбой в реальном коде приложения.

Я уже пытался установить все настройки проекта фактического кода приложения для примера проекта, так как могут быть некоторые конфликты в библиотеках зависимостей фактического кода приложения. Но, к моему удивлению, пример проекта работал успешно, а фактическое приложение не удалось. Я также искал, почему эта функция могла дать сбой в реальном коде приложения, но не смог найти никакого полезного ответа. Эта функция нуждается в указателе файла pem-файла с открытым ключом и указателе RSA, которые абсолютно прекрасны.

RSA * create_RSA(RSA * keypair, int pem_type, char *file_name) {

    RSA   *rsa = NULL;
    FILE  *fp  = NULL;

    if(pem_type == PUBLIC_KEY_PEM) 
    {
        fp = fopen(file_name, "rb");

        PEM_read_RSAPublicKey(fp, &rsa, NULL, NULL);

        fclose(fp);

    }
    else if(pem_type == PRIVATE_KEY_PEM) 
    {
        fp = fopen(file_name, "rb");
        PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL);
        fclose(fp);
    }

    return rsa;
}

PEM_read_RSAPublicKey(fp, &rsa, NULL, NULL); вылетает, показывая

OPENSSL_Uplink(6F8D1880,08): нет OPENSSL_Applink в фактическом коде приложения.


person user12154135    schedule 02.10.2019    source источник
comment
Вы никогда не утруждаете себя проверкой того, действительно ли работают ваши fopen() вызовы.   -  person Andrew Henle    schedule 02.10.2019


Ответы (1)


Неясно, пытаетесь ли вы использовать здесь два уровня DLL, т. е. есть ли у вас EXE-файл, который вызывает DLL, содержащую ваш код, который, в свою очередь, вызывает библиотеки DLL OpenSSL? Если это так, это не работает; кладж, который OpenSSL использует для «восходящей связи» для выполнения файлового ввода-вывода, может обрабатывать только EXE, который (напрямую) вызывает библиотеки DLL OpenSSL. Ваши альтернативы: статическая ссылка OpenSSL (в вашу DLL); или вместо этого используйте интерфейс BIO, чтобы файловый ввод-вывод (полностью) обрабатывался на уровне OpenSSL, или выполняйте ввод-вывод (здесь ввод) самостоятельно и используйте память BIO для OpenSSL; см. мои ответы на этот аналогичный вопрос.

Если вы вызываете из EXE-файла DLL-библиотеки OpenSSL, это должно работать, если вы скомпилируете и свяжете applink.c с вашим EXE-файлом, как описано (кратко) на справочную страницу, или вы можете выбрать варианты выше, если хотите.

Кроме того: как прокомментировал Эндрю, вы должны проверять наличие ошибок в fopen или другом вводе-выводе, а также в подпрограммах PEM_read - они могут дать сбой. Кроме того, файлы PEM являются текстовыми и не нуждаются в флаге b даже в Windows. А использование низкоуровневого формата RSAPublicKey вместо формата [RSA_]PUBKEY очень необычно; ты уверен, что ты этого хочешь?"

person dave_thompson_085    schedule 02.10.2019
comment
Спасибо, dave_thompson_085. Мне помогло связывание dll openssl напрямую с основным исполняемым файлом и добавление PEM_read_RSAPublicKey() в основной исполняемый файл. - person user12154135; 25.10.2019