У меня есть метод, который использует PEM_write_RSAPrivateKey
с именем GenerateKeys
extern "C" {
__declspec(dllexport) void GenerateKeys(const char* pcszPassphrase)
{
const EVP_CIPHER* pCipher = NULL;
EVP_PKEY* pPrivKey = NULL;
FILE* pFile = NULL;
RSA *rsa = NULL;
pPrivKey = create_rsa_key();
if (pPrivKey)
{
char buff[MAX_PATH];
sprintf(buff, "%s%s", currentDirectory, "\\Keys\\prikey.pem");
if ((pFile = fopen(buff, "wt")) && (pCipher = EVP_aes_256_cbc()))
{
rsa = EVP_PKEY_get1_RSA(pPrivKey);
if (!PEM_write_RSAPrivateKey(pFile, rsa, pCipher,
(unsigned char*)pcszPassphrase,
(int)strlen(pcszPassphrase), NULL, NULL))
{
// Not important code
}
}
}
}
}
PEM_write_RSAPrivateKey
метод требует applink.c кодовый блок для правильной работы, поэтому я добавил еготоже и все работает нормально.
#define APPLINK_STDIN 1
#define APPLINK_STDOUT 2
#define APPLINK_STDERR 3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS 5
#define APPLINK_FREAD 6
#define APPLINK_FWRITE 7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF 9
#define APPLINK_FCLOSE 10 /* should not be used */
#define APPLINK_FOPEN 11 /* solely for completeness */
#define APPLINK_FSEEK 12
#define APPLINK_FTELL 13
#define APPLINK_FFLUSH 14
#define APPLINK_FERROR 15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO 17 /* to be used with below */
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
#define APPLINK_READ 19
#define APPLINK_WRITE 20
#define APPLINK_LSEEK 21
#define APPLINK_CLOSE 22
#define APPLINK_MAX 22 /* always same as last macro */
static void *app_stdin(void) { return stdin; }
static void *app_stdout(void) { return stdout; }
static void *app_stderr(void) { return stderr; }
static int app_feof(FILE *fp) { return feof(fp); }
static int app_ferror(FILE *fp) { return ferror(fp); }
static void app_clearerr(FILE *fp) { clearerr(fp); }
static int app_fileno(FILE *fp) { return _fileno(fp); }
static int app_fsetmod(FILE *fp, char mod)
{
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
extern "C" {
__declspec(dllexport)
void **
OPENSSL_Applink()
{
static int once = 1;
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] = { (void *)APPLINK_MAX };
if (once)
{
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
once = 0;
}
return OPENSSL_ApplinkTable;
}
}
Проблема в том, что я хочу использовать этот код в C # . После сортировки и вызова метода GenerateKeys
, C # приложение закрывается в PEM_write_RSAPrivateKey
строке с этим сообщением об ошибке:
OPENSSL_Uplink (0F3C26E0,08): нет OPENSSL_Applink
И это та же ошибка, которая произошла, если я неНе включайте applink.c в мой C код. Кажется, проблема в том, что OPENSSL_Applink
функция - это extern
сам метод, но я не знаю, как решить эту проблему.