Как извлечь IP-адрес из поля subject_alt_name из сертификатов OpenSSL, используя API(не команды openssl) в C
Мое требование - извлечь IP-адрес из сертификатов openSSL, используя функции API OpenSSL (не примитивные команды openSSL). Я могу использовать ASN1_STRING_data() для извлечения сведений о поле san, но как мне распечатать IP-адрес из него. Каков тип данных поля IP-адреса
Я получаю общее имя и поле san из сертификатов, следующих за потоком кода ниже. Я могу получить общее имя, но у меня возникают проблемы с полем SAN
Используя openssl api для C, смог получить поле общего имени, но не поле SAN ip
common_name(X509* server_cert)
{
X509_NAME *subject_name = X509_get_subject_name((X509 *)server_cert);
int common_name_loc = X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);
X509_NAME_ENTRY *common_name_entry =
X509_NAME_get_entry(X509_get_subject_name((X509 *) server_cert), common_name_loc);
ASN1_STRING *common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
char *common_name_str = (char *) ASN1_STRING_data(common_name_asn1);
}
san_field(X509 *cert)
{
STACK_OF(GENERAL_NAME) *san_names = NULL;
// Try to extract the names within the SAN extension from the certificate
san_names = static_cast<STACK_OF(GENERAL_NAME)*>(X509_get_ext_d2i((X509 *)cert, NID_subject_alt_name, NULL, NULL));
san_names_nb = sk_GENERAL_NAME_num(san_names);
// Check each name within the extension
for (i=0; i<san_names_nb; i++)
{
const GENERAL_NAME *current_name = sk_GENERAL_NAME_value(san_names, i);
if (current_name->type == GEN_IPADD)
{
const char* ip_addrezz = reinterpret_cast<char*>
(ASN1_STRING_data(current_name->d.iPAddress));
print ---------->ip_addrezz //issue here
}
}
}
How to extract SAN ip field from certificate
How to print the ip address extracted from SAN field of certificate/what is the data type of the ip field
Am i going in correct direction
1 ответ
Поскольку я недавно также наткнулся на это, я хотел бы задокументировать ответ, который лучше всего подходит для меня (надеюсь, я правильно понял суть этого вопроса):RFC5280 - Альтернативное имя субъекта утверждает, что iPAddress является
хранится в строке октетов в "сетевом порядке байтов"
When the subjectAltName extension contains an iPAddress, the address
MUST be stored in the octet string in "network byte order", as
specified in [RFC791]. The least significant bit (LSB) of each octet
is the LSB of the corresponding byte in the network address. For IP
version 4, as specified in [RFC791], the octet string MUST contain
exactly four octets. For IP version 6, as specified in
[RFC2460], the octet string MUST contain exactly sixteen octets.
Что, в свою очередь, означает, что для IPv4-адреса вы можете использовать что-то вроде
std::stringstream ip{};
ip << (int)ip_addrezz[0] << '.' << (int)ip_addrezz[1] << '.' << (int)ip_addrezz[2] << '.' << (int)ip_addrezz[3]
return ip.str();
напечатать это.
Я также нашел этот пост действительно полезным (приведенный выше код скопирован оттуда).