Создание самоподписанного сертификата с полями отличительного имени

Я пытаюсь написать приложение, которое создаст самозаверяющий сертификат с предоставленными различающимися именами.

У меня есть следующее приложение, которое создает файлы .key и .csr.

#include <stdio.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>

#define _RAND_FILENAME  "/dev/random"
#define _RAND_LOADSIZE  128
#define _RSA_KEYSIZE    1024


int build_and_save_csr(int dn_entries, char *dn_fields[], char *dn_values[], FILE *req_f, FILE *priv_f)
{
    X509_REQ    *req_p;
    EVP_PKEY    *key_p;
    RSA     *rsa_p;
    X509_NAME   *name_p = NULL;
    int     priv_len;
    unsigned char   *priv_p;
    int     i;

    if (!(req_p = X509_REQ_new())) {
        fprintf(stderr, "X509_REQ_new() failed\n");
        return -1;
    }

    if (!(key_p = EVP_PKEY_new())) {
        X509_REQ_free(req_p);
        fprintf(stderr, "EVP_PKEY_new() failed\n");
        return -1;
    }

#if 0
    if (RAND_load_file(_RAND_FILENAME, _RAND_LOADSIZE) != _RAND_LOADSIZE) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "RAND_load_file() failed\n");
        return -1;
    }
#endif

    if (!(rsa_p = RSA_generate_key(_RSA_KEYSIZE, RSA_F4, NULL, NULL))) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "RSA key generatione failed\n");
        return -1;
    }

    if (!EVP_PKEY_assign_RSA(key_p, rsa_p)) {
        X509_REQ_free(req_p);
        RSA_free(rsa_p);
        EVP_PKEY_free(key_p);
        return -1;
    }
    /*!!! the memory for rsa_p is now managed by key_p - don't free! */


    if (!X509_REQ_set_version(req_p, 0L)        /* Version 1 */
     || !X509_REQ_set_pubkey(req_p, key_p)) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "Failed to set stuff on X509_REQ\n");
        return -1;
    }

    if (!(name_p  = X509_REQ_get_subject_name(req_p))) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "Failed to make get X509_REQ_get_subject_name\n");
        return -1;
    }

    /* Build the DN */
    for (i = 0; i < dn_entries; i++) {
        if (!X509_NAME_add_entry_by_txt(name_p, dn_fields[i], MBSTRING_ASC,
                dn_values[i], -1, -1, 0)) {
            X509_REQ_free(req_p);
            EVP_PKEY_free(key_p);
            fprintf(stderr, "Failed to make the X509_NAME\n");
            return -1;
        }
    }

    if (!X509_REQ_sign(req_p, key_p, EVP_sha1())) {
        X509_REQ_free(req_p);
        EVP_PKEY_free(key_p);
        fprintf(stderr, "X509_REQ_sign() failed\n");
        return -1;
    }

    /* save the private key to file (PKCS#1) */
    priv_p = NULL;
    priv_len = i2d_RSAPrivateKey(rsa_p, &priv_p);
    fwrite(priv_p, priv_len, 1, priv_f);
    OPENSSL_free(priv_p);

    EVP_PKEY_free(key_p);   /* nolonger need the EVP structure */

    /* save the CSR to file (PKCS#10) */
    i2d_X509_REQ_fp(req_f, req_p);
    X509_REQ_free(req_p);

    return 0;
}

int main(int argc, char *argv[])
{
    char    *dn_fields[] = { "O", "CN" };
    char    *dn_values[] = { "My Application", "[email protected]" };
    FILE    *req_f, *priv_f;

    req_f = fopen("selleck.csr", "w");
    priv_f = fopen("selleck.key", "w");

    if (build_and_save_csr(2, dn_fields, dn_values, req_f, priv_f) != 0) {
        fprintf(stderr, "Oh bother...\n");
        fclose(req_f);
        fclose(priv_f);
        exit(1);
    }

    fclose(req_f);
    fclose(priv_f);
    return 0;
}

Я предполагаю, что эту строку можно заменить на ту, которая создает самозаверяющий сертификат вместо запроса на подпись??

/* save the CSR to file (PKCS#10) */
i2d_X509_REQ_fp(req_f, req_p);

Для меня это все в новинку, поэтому буду признателен за любой совет!


person TomSelleck    schedule 20.09.2013    source источник


Ответы (1)


Я предполагаю, что эту строку можно заменить на ту, которая создает самозаверяющий сертификат вместо запроса на подпись??

Нет, мне жаль, что это не так просто.

X509_REQ не является правильной структурой для создания самозаверяющего сертификата. Это только для управления CSR (запрос на подпись сертификата), поэтому основная структура и функции (с суффиксом _REQ) недействительны для вашей цели.

Но процесс создания самоподписанного сертификата очень близок к этому (CSR является самоподписанным, как вы можете заметить в вызове X509_REQ_sign).

Здесь вы можете найти очень полный и исчерпывающий ответ на весь процесс, и здесь пример самоподписанное творение.

В качестве пояснения i2d_X509_REQ_fp он используется для сохранения CSR X509 в формате PKCS#10, Информация .

person Jon Ander Ortiz Durántez    schedule 20.09.2013
comment
Я попробую использовать этот пример и посмотрю, что у меня получится, большое спасибо! - person TomSelleck; 20.09.2013