Статус: Активный участник
Группы: Участники
Зарегистрирован: 14.03.2011(UTC) Сообщений: 152 Откуда: Санкт-Петербург Сказал «Спасибо»: 1 раз Поблагодарили: 7 раз в 5 постах
|
Добрый день. Стоит сборки 4.0.9708 Nechaev. 64 разрядная. Уперся в ошибку получения сведений о наличии сведений о контейнере закрытого ключа в хранилище. Читаю файл хранилища сертификатов. "CertOpenStore(CERT_STORE_PROV_FILENAME ...". Код:// находим сертификат
PCCERT_CONTEXT pCert = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_HASH, &idBlob, NULL);
if(pCert == NULL) {
printf("не нашли сертификат. error:%X\n", GetLastError());
} else {
PCRYPT_KEY_PROV_INFO pCryptKeyProvInfo;
DWORD cbData = 0;
if(!CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbData)) {
printf("ошибка при расчете. error:%X\n", GetLastError());
} else {
printf("выделяем память %d\n", (int) cbData);
PCRYPT_KEY_PROV_INFO pCryptKeyProvInfo = (PCRYPT_KEY_PROV_INFO) malloc(cbData);
if(!pCryptKeyProvInfo) {
printf("ошибка при выделении памяти\n");
} else if(!CertGetCertificateContextProperty(pCert, CERT_KEY_PROV_INFO_PROP_ID, pCryptKeyProvInfo, &cbData)) {
printf("ошибка при извлечении. error:%X\n", GetLastError());
free(pCryptKeyProvInfo);
}
}
CertFreeCertificateContext(pCert);
}
Выдаются сообщения: Код:
выделяем память 244
ошибка при извлечении. error:D
Что означает код ошибки "0xD" ? Решил дополнить после серии тестов. Кстати, интересная особенность. Файл хранилища сертификатов был подготовлен на машине, с Windows 7 и установленной КриптоПро CSP 3.9. Имеется два хранилища. 1) в виде файла, со списком сертификатов 2) системное MY Программа в цикле перебирает оба хранилища и пытается найти сведения о закрытом ключе. Поменял механику поиска. Если мне нужно искать сертификат с закрытым ключем, список хранилищ читаю в обратном порядке. Получение сведений из системного хранилища MY не вызывает данной ошибки. Этот же код, прямого перебора хранилищ, в Windows c КриптоПро CSP 3.6 и 3.9 не вызывает таких проблем. Отредактировано пользователем 7 апреля 2016 г. 16:45:42(UTC)
| Причина: дополнение после серии тестов
|
|
|
|
Статус: Сотрудник
Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC) Сообщений: 6,377 Откуда: КРИПТО-ПРО Сказал «Спасибо»: 32 раз Поблагодарили: 706 раз в 614 постах
|
Я правильно понимаю, вы переносите между ОС сериализованные хранилища? |
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 14.03.2011(UTC) Сообщений: 152 Откуда: Санкт-Петербург Сказал «Спасибо»: 1 раз Поблагодарили: 7 раз в 5 постах
|
Да, правильно. И еще заметил очень некрасивую ошибку. У меня Linux amd 64. Проект собираю под Qt Creator. Смотрим описание ошибки CSP_WinError.h, строка 18943 Код:#define CRYPT_E_NOT_FOUND _HRESULT_TYPEDEF_(0x80092004L)
Переходим на описание _HRESULT_TYPEDEF_, CSP_WinError.h, строка 14116 Код:#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
Переходим на описание HRESULT, CSP_WinDef.h, строка 162 Переходим на описание LONG, CSP_WinDef.h, строка 157 Далее, смотрим описание функции GetLastError в CSP_WinDef.h, строка 446 Код:WINBASEAPI DWORD WINAPI GetLastError(void);
Переходим на описание DWORD, CSP_WinDef.h, строка 159 Код:typedef unsigned int DWORD; /* XXXX icc говорит, что с этим типом есть проблемы ???? */
Всё это к чему? 0x80092004L - это long - 64 бита. Читаем Re: amd64: why is sizeof(int) =4? why not =8?Вот и получается, что мы видим всего лишь 32 бита, а не все 64 бита ошибки. Идет обрезание кода ошибки.
|
|
|
|
Статус: Сотрудник
Группы: Администраторы, Участники Зарегистрирован: 24.11.2009(UTC) Сообщений: 965 Откуда: Crypto-Pro
Сказал(а) «Спасибо»: 3 раз Поблагодарили: 174 раз в 152 постах
|
Выглядит крайне странно. Т.е. у вас преобразование unsigned int test = (int)(0x80092004L) обрезает число даже если оно не вылазит за 32 бита? Впервые кто то имеет проблемы с этим кодом. У меня например на i7 Цитата:cross@cross7:/tmp$ uname -a Linux cross7 3.19.0-22-generic #22-Ubuntu SMP Tue Jun 16 17:15:15 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux cross@cross7:/tmp$ cat test.c #include <stdio.h> int main(void) { unsigned int test = (int)(0x80092004L); printf("test=0x%08x\n", test); } cross@cross7:/tmp$ gcc test.c cross@cross7:/tmp$ ./a.out test=0x80092004
как видно значение не образалось. |
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 14.03.2011(UTC) Сообщений: 152 Откуда: Санкт-Петербург Сказал «Спасибо»: 1 раз Поблагодарили: 7 раз в 5 постах
|
Когда возникают очень странные коды ошибок, не описанные в документации, сразу думаешь о том, что сделал не так. Вот предупреждения транслятора. Код:предупреждение: comparison between signed and unsigned integer expressions [-Wsign-compare]
if(GetLastError() != CRYPT_E_NOT_FOUND)
^
Результат функции GetLastError() - unsigned int Значение константы - int. Понятно, что преобразование типа. Но как правильно? а) if((HRESULT) GetLastError() != CRYPT_E_NOT_FOUND) б) if(GetLastError() != (DWORD) CRYPT_E_NOT_FOUND) Цифра 8 в старшем разряде, это минус для типа int. Приведение длинного положительного целого числа 0x80092003L, к целому числу (int). Это отрицательное число или всё таки положительное? Я понимаю, что система как-то работает и с этим можно жить. Есть еще один казус с возвратом не документированной ошибки 0x57. Как его получить? 1) находим сертификат в хранилище; 2) закрываем хранилище с флагом CERT_CLOSE_STORE_FORCE_FLAG; 3) пытаемся что-то проделать с сертификатом - проверить или подписать.
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close