Я пытаюсь программно сгенерировать сертификат 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;
}