0

我的要求是使用 OpenSSL API 函数(不是 openSSL 原始命令)从 openSSL 证书中提取 IP 地址。我可以使用 ASN1_STRING_data() 来提取 san 字段详细信息,但是如何从中打印 ip 地址。ip 地址字段的数据类型是什么

我正在按照以下代码流从证书中获取公用名和 san 字段。我能够获取公用名,但是 SAN 字段有问题

对 C 使用 openssl api,能够获取公用名字段,但不能获取 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
4

1 回答 1

0

正如我最近也偶然发现的那样,我想记录最适合我的答案(我希望我能正确理解这个问题): RFC5280 - Subject Alternative Name states, that iPAddress is

以“网络字节顺序”存储在八位字节字符串中

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();

打印它。

我还发现这篇文章真的很有帮助(上面的代码是从那里复制的)。

于 2021-06-25T12:13:13.063 回答