RSA Знак: OpenSSL - PullRequest
       2

RSA Знак: OpenSSL

5 голосов
/ 15 марта 2011

Я пытаюсь кодировать с интерфейсом EVP Openssl для подписи RSA с SHA1.Позже я хотел бы расширить подписание с помощью различных алгоритмов дайджеста и других алгоритмов подписи (в общем, общего характера и, следовательно, с использованием EVP).

Кажется, что я получаю ошибку сегментации, когда пытаюсь получить размер моегозакрытый ключ

Может кто-нибудь сказать мне, как это исправить?

int rsaSign(char *in_file, char * sig_file){

        char *data = NULL;
        int data_len;
        unsigned int sig_len;
        unsigned char *sig;
        int err = -1;

        OpenSSL_add_all_digests();
        FILE *fd;
        EVP_PKEY *priv_key = EVP_PKEY_new();
        RSA *privkey = NULL;
           printf( "we are here..\n");

        if ((fd = fopen(PRIVKEY_FILE, "r")) == NULL){
            printf("error reading file\n");
            exit(0);
        }

        privkey = RSA_new();
        if (!PEM_read_PrivateKey(fd, &privkey, NULL, NULL))
        {
            fprintf(stderr, "Error loading RSA Private Key File.\n");
            return 2;
        }

        fclose(fd);

        if (!EVP_PKEY_assign_RSA (priv_key, privkey))
        {
            fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
            return 3;
        }

        if (!priv_key) {
            printf("no private key\n");
        }
        EVP_PKEY_set1_RSA(privkey, priv_key);


        EVP_MD_CTX *ctx = EVP_MD_CTX_create();

        const EVP_MD *md = EVP_get_digestbyname("SHA1");

        if (!md) {
            fprintf(stderr, "Error creating message digest");
            fprintf(stderr, " object, unknown name?\n");
            ERR_print_errors_fp(stderr);
            exit(1);
        }



        if (!EVP_SignInit(ctx, md))
            {
                fprintf(stderr, "EVP_SignInit: failed.\n");
                EVP_PKEY_free(priv_key);
                return 3;
            }
        printf( "now to sign update..\n");
        data = readFile(in_file);
        data_len = strlen(data);
        printf("data len = %d\n", data_len);

        if (!EVP_SignUpdate(ctx, data, data_len))
        {
            fprintf(stderr, "EVP_SignUpdate: failed.\n");
            EVP_PKEY_free(priv_key);
            return 3;
        }
        printf( "now to sign final..\n");

sig = malloc(EVP_PKEY_size(privkey)); //!!!!! SEGMENTATION FAULT HERE !!!!!


        if (!EVP_SignFinal(ctx, &sig, &sig_len, priv_key))
        {
            fprintf(stderr, "EVP_SignFinal: failed.\n");
            free(sig);
            EVP_PKEY_free(priv_key);
            return 3;
        }

        free(data);
        free(sig);
        EVP_PKEY_free(priv_key);
        return EXIT_SUCCESS;

}

Ответы [ 2 ]

7 голосов
/ 21 марта 2011

У вас есть несколько проблем:

  • PEM_read_PrivateKey() ожидает EVP_PKEY **, а не RSA ** - на самом деле вам вообще не нужен объект RSA *;
  • Вам не следует звонить EVP_PKEY_assign_RSA();
  • Вам не следует звонить EVP_PKEY_set1_RSA().

Чтобы загрузить закрытый ключ, вы можете просто сделать:

EVP_PKEY *priv_key = NULL;

if (!PEM_read_PrivateKey(rsa_pkey_file, &priv_key, NULL, NULL))
{
    fprintf(stderr, "Error loading Private Key File.\n");
    return 2;
}

Теперь вы можете позвонить EVP_PKEY_size(priv_key), чтобы определить размер ключа.

Кроме того, ваш EVP_SignFinal() вызов неверен - вы должны передавать sig, а не &sig.

7 голосов
/ 15 марта 2011

Я не эксперт в этой конкретной библиотеке, но, просмотрев документы API, я думаю, что это:

EVP_PKEY_set1_RSA(privkey, priv_key);

должно быть:

EVP_PKEY_set1_RSA(priv_key, privkey);

и аналогично, если строка, которую вы выделили как SEGFAULTing, не относится к priv_key, а не privkey также:

sig = malloc(EVP_PKEY_size(priv_key));

Обе эти ошибки будет легче увидеть, если вы измените имена переменных на что-то более простое для различения (вместо privkey и priv_key, используйте priv_key_RSA и priv_key_EVP

Наличие переменных, которые отличаются только подчеркиванием, - действительно плохая идея:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...