Как я могу загрузить сертификаты с Unicode CN, используя CryptoAPI? - PullRequest
1 голос
/ 14 сентября 2011

Я пытаюсь загрузить сертификат из системного хранилища.Я использую функцию CertFindCertificateInStore из CryptoAPI:

std::string certName;
CERT_RDN_ATTR subjCN;
subjCN.pszObjId = szOID_COMMON_NAME;
subjCN.dwValueType = CERT_RDN_PRINTABLE_STRING;
subjCN.Value.cbData = 2*(certName.size()); 
subjCN.Value.pbData = (BYTE*)certName.c_str();
CERT_RDN rdn;
rdn.cRDNAttr = 1;
rdn.rgRDNAttr = &subjCN;

cert = CertFindCertificateInStore ( certStore,    
                                    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                    CERT_UNICODE_IS_RDN_ATTRS_FLAG ,
                                    CERT_FIND_SUBJECT_ATTR,
                                    &rdn,
                                    NULL);
  1. Почему мне нужно установить dwValueType для CERT_RDN_ATTR в CERT_RDN_PRINTABLE_STRING вместо CERT_RDN_UNICODE_STRING?(Я использую Unicode.) С CERT_RDN_UNICODE_STRING этот код не работает.

  2. Тем не менее, я не могу загрузить сертификат с темой CN, содержащей пробелы и русские символы.Для простых имен CN, таких как "foo", этот код отлично работает.

Что я могу сделать, чтобы загрузить сертификаты с именем Unicode таким образом?

Ответы [ 2 ]

1 голос
/ 15 сентября 2011

Я более внимательно посмотрел на документацию. Как я понимаю сейчас, блоб имени сертификата содержит закодированный массив атрибутов rdn http://msdn.microsoft.com/en-us/library/aa382005(v=vs.85).aspx Каждый атрибут rdn имеет тип - такой как UTF8, UNICODE, T.61 и т. Д.

При использовании CERT_UNICODE_IS_RDN_ATTRS_FLAG для CertFindCertificateInStore эта функция преобразует поддерживаемую строку в атрибуте RDN из Unicode в тип атрибута RDN, а затем сопоставляет это значение с сертификатами RDN.

Итак, я расшифровал свой сертификат с помощью CryptDecodedObject, посмотрел на RDN Common Name и выяснил, что этот тип был CERT_RDN_T61_STRING. Затем я установил для subjCN.dwValueType значение CERT_RDN_T61_STRING. Код работал. Для русских символов мне нужно было CERT_RDN_UNICODE_STRING. Так что CertFindCertificateInStore с CERT_FIND_SUBJECT_ATTR или с CERT_FIND_ISSUER_ATTR не очень полезен для вас, если вы не знаете точную кодировку этого атрибута в сертификате.

1 голос
/ 15 сентября 2011

Если вы можете понять что-нибудь из бреда, который является документацией MSDN, тогда вы удивительны. Возможно, следующий драгоценный камень может быть разобран для некоторого освещения:

Значение CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags используется только с значения CERT_FIND_SUBJECT_ATTR и CERT_FIND_ISSUER_ATTR для dwFindType. CERT_UNICODE_IS_RDN_ATTRS_FLAG должен быть установлен, если Структура CERT_RDN_ATTR, на которую указывает pvFindPara, была инициализирована с Строки Unicode. Перед выполнением любого сравнения строка должна быть совпавший конвертируется с помощью X509_UNICODE_NAME, чтобы обеспечить Unicode сравнения.

Я предполагаю, что "строка для сопоставления" находится в вашем поле subjCN.Value.pbData. Вы конвертировали это, используя X509_UNICODE_NAME? Похоже, это то, что вы делаете в функции CryptEncodeObject. Переход на эту страницу заставил мою голову болеть. Извините, вам придется пережить следующие шаги.

...