Я предполагаю, что ваше построение данных расширения действительно произошло до вашего звонка на CertCreateSelfSignedCertificate
(и, аналогично, ваше построение myBlobdata
произошло до его использования).
Основноепроблема в том, что вы использовали одну запись SAN (вроде) в качестве полного расширения SAN;что означало, что вы потеряли некоторые обертки для кодирования.Вторичной проблемой является то, что вы использовали szOID_SUBJECT_ALT_NAME
, который является неправильным OID для альтернативного имени субъекта ... вы на самом деле хотите szOID_SUBJECT_ALT_NAME2
.
Я хочу добавить следующее: DNS name = полностьюквалифицированное доменное имя, DNS-имя = имя хоста и DNS-имя = IP
Добавление IP-адреса в качестве DNS-имени является нестандартным и может привести к ошибке сопоставления.Вы действительно хотите добавить IP-адрес в качестве записи SAN IP-адреса.
CERT_ALT_NAME_ENTRY entries[3];
entries[0] = { CERT_ALT_NAME_DNS_NAME };
entries[0].pwszDNSName = L"example.org";
// IPv4 Address 10.12.1.130
BYTE ip4Bytes[] = { 10, 12, 1, 130 };
entries[1] = { CERT_ALT_NAME_IP_ADDRESS };
entries[1].IPAddress = { sizeof(ip4Bytes), ip4Bytes };
// ::1, big-endian
BYTE ip6Bytes[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
entries[2] = { CERT_ALT_NAME_IP_ADDRESS };
entries[2].IPAddress = { sizeof(ip6Bytes), ip6Bytes };
CERT_NAME_BLOB name = { cbEncoded, buf };
BYTE extBuf[1024] = { 0 };
cbEncoded = sizeof(extBuf);
CERT_ALT_NAME_INFO info = { sizeof(entries) / sizeof(CERT_ALT_NAME_ENTRY), entries };
if (!CryptEncodeObjectEx(
X509_ASN_ENCODING,
X509_ALTERNATE_NAME,
&info,
0,
nullptr,
extBuf,
&cbEncoded))
{
// Whatever your error handling story is.
//
// Note I didn't do a 0 buffer or CRYPT_ENCODE_ALLOC; I just knew
// that my buffer would be big enough.
}
CERT_EXTENSION extension = { 0 };
extension.fCritical = 0;
extension.pszObjId = szOID_SUBJECT_ALT_NAME2;
extension.Value = { cbEncoded, extBuf };
CERT_EXTENSIONS extensions = { 1, &extension };
...
PCCERT_CONTEXT cert = CertCreateSelfSignCertificate(
0,
&name,
0,
&keyProvInfo,
&sigAlg,
0,
&certExpirationDate,
&extensions);
В CertUI, который дает мне значение Subject Alternative Name, которое я ожидаю:
DNS Name=example.org
IP Address=10.12.1.130
IP Address=0000:0000:0000:0000:0000:0000:0000:0001