Я хочу создать сертификат 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:
Есть идеи, что я делаю не так? Спасибо.