Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Файл из дельфи в си


Автор: alexsk 1.2.2007, 12:56
Нужно  библиотеке на си (libeay32.dll) параметром функции (PEM_read_PrivateKey( fp,nil,nil,nil)) передать указатель типа FILE, только сишный файл и дельфевый - это разные вещи и передать тупо укзателем не получается. Как можно обмануть сишную dll?

Автор: _hunter 1.2.2007, 13:00
можно написать на сях небольшую библиотеку, принимающую имя файла, вызывающую libeay32.dll

Автор: CatATonik 1.2.2007, 13:00
Не знаю что этой функции надо, но думаю не указатель а Handle файла. Превратить FILE в Handle проблематично, может лучше просто окрыть файл APIшными функциями (CreateFile).

Автор: alexsk 1.2.2007, 13:06
тут проблема в том, что передать нужно указатель на переменную тип FILE сишного, т.е. надо смонтировать в делфи указатель на переменную сишного типа FILE и уже его передать функции

Автор: VectorMan 1.2.2007, 16:17
Если libeay32.dll слинкована не со статической сишной либой, а какой нибудь dll (типа msvcrt.dll), то можно в дельфийском исходнике экспортировать функцию fopen и вызывать её для открытия файла, а потом передавать полученный указатель нужной функции

Автор: Alexeis 1.2.2007, 16:26
Цитата(alexsk @  1.2.2007,  13:06 Найти цитируемый пост)
тут проблема в том, что передать нужно указатель на переменную тип FILE сишного, т.е. надо смонтировать в делфи указатель на переменную сишного типа FILE и уже его передать функции

  Лучше передать хэндл открытого файла, тогда вообще проблем не будет.

Автор: Romikgy 1.2.2007, 16:38
alexsk, 
Цитата(alexsk @  1.2.2007,  11:56 Найти цитируемый пост)
Нужно  библиотеке на си (libeay32.dll) 


Цитата(alexsk @  1.2.2007,  11:56 Найти цитируемый пост)
передать указатель типа FILE,

начем написана библа?
ибо
это из gcc
Код

typedef struct _iobuf
{
    char*    _ptr;
    int    _cnt;
    char*    _base;
    int    _flag;
    int    _file;
    int    _charbuf;
    int    _bufsiz;
    char*    _tmpfname;
} FILE;

а это из билдера
Код

typedef struct
{
        unsigned char  *curp;       /* Current active pointer     */
        unsigned char  *buffer;     /* Data transfer buffer       */
        int             level;      /* fill/empty level of buffer */
        int             bsize;      /* Buffer size                */
        unsigned short  istemp;     /* Temporary file indicator   */
        unsigned short  flags;      /* File status flags          */
        wchar_t         hold;       /* Ungetc char if no buffer   */
        char            fd;         /* File descriptor            */
        unsigned char   token;      /* Used for validity checking */
}       FILE;                       /* This is the FILE object    */

какой переводить?

Автор: alexsk 2.2.2007, 07:36
Romikgy, да хбз, эта дллка идет с openssl у них файл открывается через fopen(), но эта функция имхо стандартная для всех си и может использоваться в любом... или я не прав? А как узнать? Я че-то у поставщиков нигде не нашел.... smile 

Alexeis, как? smile 

Автор: Romikgy 2.2.2007, 09:54
Цитата(alexsk @  2.2.2007,  06:36 Найти цитируемый пост)
или я не прав?

а ты хоть чуть чуть в Си разбираешься? посмотри то что я привел, увидишь разницу?

ЗЫ приведи пример работы с этой библиотекой на си, всех ф_ций которые тебе понадобяться

Автор: Alexeis 2.2.2007, 11:00
alexsk, Сишная структура совместима только с C++, в делфи для доступа к файлу используются другие структуры. 
Файл открывается при помощи CreateFileEx(); - результат хендл открытого файла. Этот хендл можно спокойно передавать куда угодно. Делфи с ним прекрасно работает. Открой MSDN - раздел работа с файлами. Там описаны все апишные функции. Все они работают с дескриптором открытого файла. 

Автор: alexsk 5.2.2007, 11:21
Вот пример чего надо написан на Си

Код

#include 
#include 
#include 


const char HEX[16] = "0123456789abcdef";

int main(int argc, char ** argv){
    // путь к файлу приватного ключа 
    char *keyFile  ="priv.key";
    // подписываемые данные
    char *data  = "test";
    int dlen = 4;
    // подпись - результат вычислений
    unsigned char *sign;
    int slen;
    // подпись в шестнадцатеричном представлении
    char *hex;
    
    int i, j;
    FILE * f;
    EVP_MD *md;
    EVP_PKEY  *key;
    EVP_MD_CTX *mdctx;
    
    
    // читаем файл закрытого ключа
    f = fopen(keyFile, "r");
    if(f == NULL){
        printf("невозможно открыть файл ключа\n");
        return -1;
    }
    key = PEM_read_PrivateKey(f,NULL,NULL,NULL);
    fclose(f);
    if(key == NULL) goto ERROR;
        
    // определяем размер ключа
    slen = EVP_PKEY_size(key);
    
    // размер подписи будет таким же 
    sign = (unsigned char*) malloc(slen);
    if(sign == NULL)  goto ERROR;
        
    // получаем доступ к хэш-функции MD5
    OpenSSL_add_all_digests();
    md  = (EVP_MD*)EVP_get_digestbyname("MD5");
    if(md == NULL) goto ERROR;

    // формируем контекст подписи
    mdctx = EVP_MD_CTX_create();
    if(mdctx == NULL) goto ERROR;
    
    // устанавливаем хэш-функцию, которая буддет использована
    if(! EVP_SignInit(mdctx, md)) goto ERROR;

    // подписываем данные
    if(! EVP_SignUpdate(mdctx, data, dlen)) goto ERROR;

    // завершаем формирование подписи
    if(! EVP_SignFinal (mdctx, sign, &slen, key)) goto ERROR;
        
    // преобразуем результат вычислений в 
    // шестнадцатеричное представление
    hex = (char*) malloc(slen * 2 + 1);
    if(hex == NULL)  goto ERROR;    
    j = 0;
    for (i = 0; i < slen; i++) {
        hex[j++] = HEX[sign[i] >> 4];
        hex[j++] = HEX[sign[i] & 0xF];
    }
    hex[j] = 0;

    // отображаем результат в 16-ричном формате
    printf("Signature  is %s\n", hex);
    
    // освобождаем ресурсы
    free(hex);
    free(sign);
    EVP_PKEY_free(key);
    EVP_MD_CTX_destroy(mdctx);
    
    return 0;
    
    // отладочная информация при сбое
    ERROR:
    ERR_load_crypto_strings();
    printf("ERROR: %s\n", ERR_error_string(ERR_get_error(),NULL));
    return -1;
}


Мне по сути надо тоже самое только на делфи
А вся запарка в этом PEM_read_PrivateKey(f,NULL,NULL,NULL); и встала.
Как ему передать файл?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)