Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline miser  
#1 Оставлено : 7 апреля 2016 г. 12:45:18(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 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)  | Причина: дополнение после серии тестов

Offline Максим Коллегин  
#2 Оставлено : 7 апреля 2016 г. 16:59:32(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,377
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 32 раз
Поблагодарили: 706 раз в 614 постах
Я правильно понимаю, вы переносите между ОС сериализованные хранилища?
Знания в базе знаний, поддержка в техподдержке
Offline miser  
#3 Оставлено : 7 апреля 2016 г. 17:48:29(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 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
Код:
typedef LONG HRESULT;

Переходим на описание LONG, CSP_WinDef.h, строка 157
Код:
typedef int LONG;


Далее, смотрим описание функции 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 бита ошибки.
Идет обрезание кода ошибки.
Offline cross  
#4 Оставлено : 8 апреля 2016 г. 14:35:11(UTC)
Анатолий Беляев

Статус: Сотрудник

Группы: Администраторы, Участники
Зарегистрирован: 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

как видно значение не образалось.
Техническую поддержку оказываем тут.
Наша база знаний.
Наша страничка в Instagram.
Offline miser  
#5 Оставлено : 8 апреля 2016 г. 15:12:05(UTC)
miser

Статус: Активный участник

Группы: Участники
Зарегистрирован: 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) пытаемся что-то проделать с сертификатом - проверить или подписать.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.