Я предполагаю, что ваше построение расширенных данных действительно произошло до вашего звонка в CertCreateSelfSignedCertificate
(и, аналогично, ваше построение myBlobdata
произошло до его использования).
Основная проблема заключается в том, что вы использовали одну запись SAN (своего рода) в качестве полного расширения SAN; что означало, что вы потеряли некоторые обертки для кодирования. Еще одна проблема заключается в том, что вы использовали szOID_SUBJECT_ALT_NAME
, который является неправильным OID для альтернативного имени субъекта ... вы на самом деле хотите szOID_SUBJECT_ALT_NAME2
.
Я хочу добавить следующее: DNS-имя = полное доменное имя, DNS-имя = имя хоста и DNS-имя = IP
blockquote>Добавление 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, который дает мне значение альтернативного имени субъекта, я ожидаю:
DNS Name=example.org IP Address=10.12.1.130 IP Address=0000:0000:0000:0000:0000:0000:0000:0001
Вы смотрите на теоретическую проблему с точки зрения реализации. Первый вопрос, который возникает, должен быть именно то, какой контроль вы инвертируете ?
Тогда вы поймете, что не имеет значения, какой объект, метод, функция или еще что-то передается, но что на самом деле код делает это.
Короче говоря, когда вы делаете Dependency Injection, вы инвертируете контроль создания и использования зависимостей (ресурсов).
Когда вы передаете функции Windows API указатель на функцию обратного вызова, вы предоставляете им контроль над вызовом вашей функции с их собственными параметрами.
Итак, вы видите, IoC - это просто теоретическая концепция, и, конечно, могут быть разные практические реализации.
Что ж, концепция «инверсии управления» кажется применимой везде, где есть какой-то способ передачи указателей функций. По сути, концепции плагинов и библиотеки DLL с совместимыми сигнатурами (например, драйверы) являются не чем иным, как формой IoC.
Однако, при использовании IoC с расширенным типом и моделью контейнера, вы в основном будете в OO Мир автоматически. И концепции ООП очень хорошо соответствуют концепциям IoC, особенно в языках, которые поддерживают множественное наследование с чисто виртуальными классами (или, как их еще называют, «интерфейсами»).
Инверсия управления, скорее всего, не является концепцией ОО.
IoC существует и довольно часто используется в неOO-языках. Например, это очень часто встречается в Си. Ярким примером этого является Windows API - каждый раз, когда вы вызываете какие-либо функции Windows API, которые работают через обратные вызовы, вы в основном используете IoC в его наиболее примитивной форме.
Например, взгляните на EnumWindows функция. Используя это, вы передаете указатель функции (EnumWindowsProc) в библиотеку, и ваш код запускается из кода библиотеки.
Сравните это с определением инверсии управления из Википедии: «Инверсия управления происходит, когда процедура библиотеки вызывает пользовательские процедуры. "
Это точно так же.
Однако IoC действительно становится очень мощным, гибким, и прост в использовании, когда вы добавляете систему расширенного типа и многие другие инструменты, которые поставляются с ООП. Это делает его более распространенным, поскольку с ним «приятнее» работать, но он существовал до ООП.
Фактически, объектно-ориентированная реализация IoC довольно сложна, потому что функции часто не являются первоклассными гражданами.
Как упомянул Аздер: IoC используется по множеству причин. Я обобщу некоторые здесь, чтобы убедить:)
Итерация
#ruby
{1,2,3}.each{ |i| puts i }
#haskell
map [1,2,3] ( \i -> write i )
//the stl algorithms
int printint( int i ){ return printf( "%d", i ); }
std::foreach( onetwothree.begin(), onetwothree.end(), &printi );
Создание потока
CreateThread( NULL, 0, &myFunction, NULL, 0, NULL );
Общая диспетчеризация событий
//javascript
document.getElementById( "mybutton" )
.addEventListener(
function(e){ alert("buttonPressed") } );
Ни один из этих примеров не является объектно-ориентированным, qed.