Программно создать сертификат CA с openssl в C ++ - PullRequest
1 голос
/ 01 марта 2020

Я хочу создать сертификат CA с openssl и C ++, чтобы затем использовать его для подписи сертификатов. Поэтому я реализовал функцию для генерации сертификатов:

std::shared_ptr<X509> SSL_Utilities::generateCertificate(std::shared_ptr<EVP_PKEY> pkey, std::map<std::string, std::string> subject_fields, std::map<std::string, std::string> issuer_fields)
{
    if(!pkey)return nullptr;

    X509 *x509 = X509_new();
    X509_set_version(x509, 2);

    auto p_serial_number = ASN1_INTEGER_new();
    randSerial(p_serial_number);
    X509_set_serialNumber(x509, p_serial_number);

    X509_gmtime_adj(X509_get_notBefore(x509), 0);
    X509_gmtime_adj(X509_get_notAfter(x509), (long)60*60*24*365);
    X509_set_pubkey(x509, pkey.get());

    X509_NAME *name = X509_get_subject_name(x509);
    for(auto f : subject_fields){
        X509_NAME_add_entry_by_txt(name, f.first.c_str(), MBSTRING_ASC, (const unsigned char*)f.second.c_str(), -1, -1, 0);
    }
    X509_set_subject_name(x509,name);

    name = X509_get_issuer_name(x509);
    for(auto f : issuer_fields){
        X509_NAME_add_entry_by_txt(name, f.first.c_str(), MBSTRING_ASC, (const unsigned char*)f.second.c_str(), -1, -1, 0);
    }
    X509_set_issuer_name(x509,name);

    X509_sign(x509, pkey.get(), EVP_sha512());

    return std::shared_ptr<X509>(x509,X509_free);
}

Этот код затем использовался для генерации сертификата CA. После этого я сгенерировал запросы на подпись для сервера и клиента, подписал их с помощью сгенерированного сертификата и ключа CA и попытался соединить сервер и клиент, который не работал.

Поэтому я попытался сгенерировать CA с помощью команды openssl -line, загрузил его в мою программу, создал подписанные запросы, подписал их и сервер и клиент могли соединиться. Это означает, что проблема заключается в сертификате CA. При сравнении сертификата, сгенерированного в C, с сертификатом, сгенерированным в командной строке, я обнаружил, что сертификат, сгенерированный в C, пропустил следующее:

X509v3 extensions:
            X509v3 Subject Key Identifier: 
                93:72:AB:40:A4:E8:6F:D3:26:F2:F8:54:6F:A0:94:97:79:99:65:E6
            X509v3 Authority Key Identifier: 
                keyid:93:72:AB:40:A4:E8:6F:D3:26:F2:F8:54:6F:A0:94:97:79:99:65:E6

            X509v3 Basic Constraints: critical
                CA:TRUE

Я попытался добавить Basi c Constraints поле со следующим кодом:

    ASN1_STRING * str = ASN1_OCTET_STRING_new();
    const char * ee = "CA:TRUE";
    ASN1_STRING_set(str,(const void*)ee,strlen(ee));

    X509_EXTENSION * ext = nullptr;
    X509_EXTENSION_create_by_NID(&ext,NID_basic_constraints,1,str);

    X509_add_ext(x509,ext,-1);

и сгенерированный сертификат выглядит как поле, добавленное, но при попытке его использовать я получаю следующую ошибку в коде клиента (после SSL_Connect):

140120891770752:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
140120891770752:error:0D068066:asn1 encoding routines:asn1_check_tlen:bad object header:../crypto/asn1/tasn_dec.c:1118:
140120891770752:error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:290:Type=BASIC_CONSTRAINTS
140120891770752:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:../ssl/statem/statem_clnt.c:1919:

Есть идеи, что я делаю не так? Спасибо.

1 Ответ

0 голосов
/ 02 марта 2020

Глядя, что этот пример, похоже, делает то, что вы хотите сделать:

int add_ext(X509 *cert, int nid, char *value)
    {
    X509_EXTENSION *ex;
    X509V3_CTX ctx;
    /* This sets the 'context' of the extensions. */
    /* No configuration database */
    X509V3_set_ctx_nodb(&ctx);
    /* Issuer and subject certs: both the target since it is self signed,
     * no request and no CRL
     */
    X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
    ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
    if (!ex)
        return 0;

    X509_add_ext(cert,ex,-1);
    X509_EXTENSION_free(ex);
    return 1;
    }


    /* Add various extensions: standard extensions */
    add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
    add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

    add_ext(x, NID_subject_key_identifier, "hash");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...