如何在 C 中使用 API(不是 openssl 命令)从 OpenSSL 证书的 subject_alt_name 字段中提取 IP 地址
How to extract ip address from subject_alt_name field from OpenSSL certificates using API(not openssl commands) in C
我的要求是使用 OpenSSL API 函数(不是 openSSL 原始命令)从 openSSL 证书中提取 IP 地址。
我可以使用 ASN1_STRING_data() 来提取 san 字段详细信息,但是我如何从 it.What 打印 ip 地址是 ip 地址字段的数据类型
我正在按照以下代码从证书中获取公用名和 san 字段flow.I我能够获取公用名,但是 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
因为我最近也偶然发现了这个问题,所以我想记录下最适合我的答案(我希望我能正确理解这个问题的要点):
RFC5280 - Subject Alternative Name 指出,iPAddress 是
stored in the octet string in "network byte order"
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();
打印它。
我还发现这个 post 非常有用(上面的代码是从那里复制的)。
我的要求是使用 OpenSSL API 函数(不是 openSSL 原始命令)从 openSSL 证书中提取 IP 地址。 我可以使用 ASN1_STRING_data() 来提取 san 字段详细信息,但是我如何从 it.What 打印 ip 地址是 ip 地址字段的数据类型
我正在按照以下代码从证书中获取公用名和 san 字段flow.I我能够获取公用名,但是 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
因为我最近也偶然发现了这个问题,所以我想记录下最适合我的答案(我希望我能正确理解这个问题的要点): RFC5280 - Subject Alternative Name 指出,iPAddress 是
stored in the octet string in "network byte order"
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();
打印它。
我还发现这个 post 非常有用(上面的代码是从那里复制的)。