Проблема при создании сертификата X509 с дополнительными расширениями - PullRequest
1 голос
/ 30 сентября 2019

Я пытаюсь программно сгенерировать сертификат X.509 для использования при соединении HTTPS с C ++ и библиотекой OpenSSL. Исходный код ниже - это мой код, который генерирует сертификат X.509, но X509V3_EXT_conf_nid в функции addExt всегда возвращает ноль, поэтому я не могу создать сертификат с дополнительными расширениями. Без добавления расширения я проверил, что сертификат X.509 сгенерирован хорошо. Корневой сертификат (эмитент) и сгенерированный сертификат (субъект) без дополнительных расширений в порядке, как я могу это исправить?

using X509_ptr = std::unique_ptr<X509, decltype(&X509_free)>;
using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)>;

class Certificate {
public:
    Certificate() :
        certificate(X509_ptr(nullptr, nullptr)), 
        key(EVP_PKEY_ptr(nullptr, nullptr))
    {
    }

    X509_ptr certificate;
    EVP_PKEY_ptr key;
};

int TlsManager::generateCrt(Certificate &certificate, int serial, string hostname, const Certificate &root_certificate)
{
    if (root_certificate.certificate == nullptr)
        Error::CRT_INVALIDROOT;


    // Create X.509 certificate
    X509* x509 = X509_new();
    if (x509 == nullptr) {
        X509_free(x509);
        return Error::CRT_CREATE;
    }

    // Set version
    X509_set_version(x509, 3);

    // Set serial
    ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);

    // Set validation dates
    X509_gmtime_adj(X509_get_notBefore(x509), 0);
    X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);

    // Set public key
    X509_set_pubkey(x509, certificate.key.get());

    // Set subject name
    X509_NAME *subject_name = X509_NAME_new();
    X509_NAME_add_entry_by_txt(subject_name, "CN", MBSTRING_ASC, toConstUint8Ptr(hostname.c_str()), -1, -1, 0);
    X509_set_subject_name(x509, subject_name);
    X509_NAME_free(subject_name);

    // Add extensions
    if (addExt(root_certificate.certificate.get(), x509, NID_subject_alt_name, const_cast<char*>(hostname.c_str())) != Error::NONE)
        return Error::CRT_ADDEXT;

    // Set issuer name
    X509_NAME* root_name = X509_get_issuer_name(root_certificate.certificate.get());
    X509_set_issuer_name(x509, root_name);
    X509_NAME_free(root_name);

    if (X509_sign(x509, root_certificate.key.get(), EVP_sha256()) == 0) {
        X509_free(x509);
        return Error::CRT_SIGN;
    }

    certificate.certificate = X509_ptr(x509, X509_free);

    return Error::NONE;
}

int TlsManager::addExt(X509 *subject, X509* issuer, int nid, char* value)
{
    X509V3_CTX ctx;
    X509V3_set_ctx_nodb(&ctx);
    X509V3_set_ctx(&ctx, issuer, subject, nullptr, nullptr, 0);

    /* This line always return null */
    X509_EXTENSION* ex = X509V3_EXT_conf_nid(nullptr, &ctx, nid, value);
    if (!ex)
        return Error::CRT_ADDEXT;

    X509_add_ext(subject, ex, -1);
    X509_EXTENSION_free(ex);

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