15.11.2005 14:59:30проблема с CryptEncodeObject в линухе Ответов: 2
Алексей
Добрый вечер,

При вызове в линухе CryptEncodeObject при кодеровки использования ключа функция вылетает с ошибкой ERROR_FILE_NOT_FOUND, при этом при кодеровки оидов она отрабатывает нормально. Кусок кода:


CRYPT_BIT_BLOB KeyUses;
BYTE byte[1];
byte[0]CERT_DIGITAL_SIGNATURE_KEY_USAGE|
CERT_NON_REPUDIATION_KEY_USAGE| CERT_DATA_ENCIPHERMENT_KEY_USAGE|
CERT_KEY_ENCIPHERMENT_KEY_USAGE;
KeyUses.pbData=byte;
KeyUses.cbData=1;
KeyUses.cUnusedBits=4;
DWORD size=0;
CryptEncodeObject(PKCS_7_ASN_ENCODING, szOID_KEY_USAGE,(void*)&KeyUses, NULL, &size)

т.е. Функция вылетает на опледелении размера блока.

в чем может быть подвох? (в винде это код проходит на ура).
Я подключаю следующие либы:
-L/usr/CPRO/lib -lcapilite -lcapi10 -lcapi20 -lasn1data -lcsp -lssp
Может я не все либы подключаю?
 
Ответы:
18.11.2005 11:31:13Алексей
И еще раз здравствуйте,

С проблемой разобрался, надо было использовать вместо szOID_KEY_USAGE - X509_KEY_USAGE.
Однако появилась новая проблемка - кодировка русских символов в имени.
Понятно, что CERT_RDN_ATTR в качестве dwValueType надо пользовать СERT_RDN_UTF8_STRING, соответственно при кодировки имени надо использовать X509_UNICODE_NAME, однако CryptEncodeObject c слючем X509_UNICODE_NAME вылетает с ошибкой 2 т.е. не может найти алгоритм кодирования.
Если использовать для кодировки X509_NAME
CryptEncodeObject нормально отрабатывает, однако, если посмотреть код запроса на сертификат вместо имени находится не юникодный мусор который должен быть, а ошибка - объект имеет нулевую длину.

Кусок кода кодировки имени

wchar_t wch[]=L"TEST_USER";

rgNameAttr = new CERT_RDN_ATTR [1];

rgNameAttr[0].pszObjId="2.5.4.3" ;
rgNameAttr[0].dwValueType=CERT_RDN_UTF8_STRING;
rgNameAttr[0].Value.cbData=wcslen(wch)*sizeof(wchar_t);
rgNameAttr[0].Value.pbData= (BYTE*)wch;

CERT_RDN* rgRDN;
rgRDN = new CERT_RDN[1];
rgRDN[0].cRDNAttr=1;
rgRDN[0].rgRDNAttr=&rgNameAttr[0];
CERT_NAME_INFO Name = {1,rgRDN};
DWORD cbNameEncoded;
BYTE* pbNameEncoded;

CryptEncodeObject(
MY_ENCODING_TYPE,
X509_NAME,
&Name,
NULL,
&cbNameEncoded);

pbNameEncoded = new BYTE[cbNameEncoded];

CryptEncodeObject(
MY_ENCODING_TYPE,
X509_NAME,
&Name,
pbNameEncoded,
&cbNameEncoded);



Мне кажется, что косяк в том, что нужно использовать X509_UNICODE_NAME в CryptEncodeObject, однако, если это так, то почему ОНО вылетает?
Может вы мне поможите советом?

18.11.2005 18:48:17Григорий Чудов
Боюсь, что в текущей версии X509_UNICODE_NAME не поддерживается, а CERT_RDN_UTF8_STRING поддерживается очень ограничено - она равносильна CERT_RDN_ENCODED_BLOB, т.е. rgNameAttr[0].Value.pbData должно содержать уже закодированую в ASN.1 UTF8-строку, которую придётся кодировать вручную.

Можете воспользоваться для создания X509_NAME более удобной функцией, которая умеет кодировать аттрибуты в UTF8:
CertStrToNameW(
MY_ENCODING_TYPE,
L"CN=TEST_USER",
CERT_X500_NAME_STR | CERT_NAME_STR_NO_QUOTING_FLAG,
0,
pbNameEncoded,
&cbNameEncoded,
0)