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

Уведомление

Icon
Error

3 Страницы<123>
Опции
К последнему сообщению К первому непрочитанному
Offline EgorovAlexandr  
#11 Оставлено : 25 августа 2009 г. 19:04:08(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Обнулять пробовал, эффекта не дало, выдает ту же ошибку

Подпись передаю в таком виде:
f0f3e0ee5054f0f79092e0e907b0b9202c2029b0b4b0bb10175052f0f57074c0c4101d07d0d68
08e4043404d505cb0b5c0cbc0c3b0ba404ba0a03035202b202d9096a0a104c0c9e0e780869091808
42025d0d1e0e1c0ca7077303e50591014d0d2f0f2202f707cf0fe03b0bc01404fb0bc9097e0e6303
3707c8081 (естественно без переноса строк)

Цитата:
Quote:
не могу корректно записать msgPara.pvGetArg

Там может быть любой указатель на что угодно. Что именно Вы хотите передать в CryptGetSignerCertificateCallback в этом параметре?


Я так понимаю, что сюда надо передать указатель на сертификат
Код:

msgPara.pvGetArg = (void *)pCert;


Это тоже не помогает: GetLastError возвращает прежнюю ошибку
Offline EgorovAlexandr  
#12 Оставлено : 25 августа 2009 г. 19:15:22(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

наткнулся на форуме на топик: http://www.cryptopro.ru/....aspx?g=posts&t=1630
Уважаемый Flame_xXx, не могли бы Вы поподробнее остановиться на том, как написать свою callback-функцию?
Offline EgorovAlexandr  
#13 Оставлено : 25 августа 2009 г. 19:18:02(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

По настоянию руководства выкладываю исходник проги. Может так будет проще...

Код:
PCCERT_CONTEXT my_CryptGetSignerCertificateCallback_function(void *pvGetArg,DWORD dwCertEncodingType,PCERT_INFO pSignerId,HCERTSTORE hMsgCertStore)
{
	return (PCCERT_CONTEXT)pvGetArg;
}

int main(int argc, char* argv[])
{
 
	HCERTSTORE hCMSCertStore = NULL;
	PCCERT_CONTEXT pCert = NULL;

	DWORD i = 1,c,j=0,k;
	DWORD cbContent = 0;
	BYTE signature[128];
	BYTE hexSig[64];
	BYTE * pbContent1;
	const BYTE * pbContent;

	FILE * inFile, * f = fopen("signed-data.txt","r");


	if( f == NULL )
	{
		puts("file not found");
		exit( EXIT_FAILURE );
	}

	while ( fgetc(f) != EOF )
		++cbContent;

	if( fseek(f,0,SEEK_SET) != 0 )
	{
		puts("fseek failed");
		fclose(f);
		f = fopen("signed-data.txt","r");
		if( f == NULL )
		{
			puts("file not found");
			return -1;
		}
	}
	pbContent1 = (BYTE *)malloc(cbContent+1);
	for( i = 0; i < cbContent; ++i )
		pbContent1[i] = (BYTE)fgetc(f);
	pbContent = pbContent1;
	
	hCMSCertStore = CertOpenStore(CERT_STORE_PROV_FILENAME_A,CODE_TYPE,0,0,"CMS.p7b");
	if(hCMSCertStore == NULL)
	{
		puts("store not open");
		exit( EXIT_FAILURE );
	}

	doPure = TRUE;
	output = fopen("out","w+");
	if( !readGlobalConfig( "" ) )
	{
		puts("error readGlobalConfig");
		exit( EXIT_FAILURE );
	}
	if( ( inFile = fopen( "CMS.p7b", "rb" ) ) == NULL )
	{
		puts("error fopen");
		exit( EXIT_FAILURE );
	}
	
	fseek( inFile, 0, SEEK_SET );
	printAsn1( inFile, 0, LENGTH_MAGIC, 0 );
	fclose( inFile );
	fclose(output);

	output = fopen("out","r");
	fseek(output,-1*(33+64*4),SEEK_END);
	
	while( ( c = fgetc(output) ) != EOF )
	{
		if( c == ' ' || c == '\n' || c == '}' )
			continue;
		signature[j] = (BYTE)c;
		++j;
	}

	for ( i = 0, k = 0 ; i < 64; ++i )
	{
		for ( j = 0 ; j < 2; ++j, ++k )
		{
			if( signature[k] >= 'A' && signature[k] <= 'F' )
				c = (int)signature[k] - 'A'+10;
			else if ( signature[k] >= '0' && signature[k] <= '9' )
				c = (int)signature[k] - '0';

			if( j == 0 )
				hexSig[i] = (BYTE)c*0x10;
			else
				hexSig[i] += (BYTE)c;
		}
	}

	DWORD cSig=64;

	CRYPT_VERIFY_MESSAGE_PARA msgPara;

	while( ( pCert = CertFindCertificateInStore(hCMSCertStore,CODE_TYPE,1,CERT_FIND_ANY,NULL,pCert) ) != NULL )
	{
		ZeroMemory(&msgPara, sizeof(msgPara)); 
		msgPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
		msgPara.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
		msgPara.hCryptProv = NULL;//hCryptProv;
		msgPara.pfnGetSignerCertificate = NULL;//&my_CryptGetSignerCertificateCallback_function;
		msgPara.pvGetArg = (void *)pCert;

		if( !CryptVerifyDetachedMessageSignature(&msgPara,1,hexSig,cSig,1,&pbContent,&cbContent,NULL) )
		{
			printf("%x\n",GetLastError());
		}
		
	}
    

	if( !CertFreeCertificateContext(pCert) )
		puts("Certificate not cleaned");

	if( !CertCloseStore(hCMSCertStore,CERT_CLOSE_STORE_CHECK_FLAG) )
		puts("Store not closed");


	printf("\nHello World!\n");
	fclose(f);
	return 0;
}
Offline ivan.novikov  
#14 Оставлено : 25 августа 2009 г. 19:18:35(UTC)
ivan.novikov

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

Группы: Участники
Зарегистрирован: 23.05.2008(UTC)
Сообщений: 74
Откуда: Moscow

Цитата:

f0f3e0ee5054f0f79092e0e907b0b9202c2029b0b4b0bb10175052f0f5707
4c0c4101d07d0d6808e4043404d505cb0b5c0cbc0c3b0ba404ba0a03035
202b202d9096a0a104c0c9e0e78086909180842025d0d1e0e1c0ca70773
03e50591014d0d2f0f2202f707cf0fe03b0bc01404fb0bc9097e0e6303370
7c8081


Здесь 123 байта после hexToBin, многовато...

Отредактировано пользователем 25 августа 2009 г. 19:23:07(UTC)  | Причина: Не указана

Offline Kirill Sobolev  
#15 Оставлено : 25 августа 2009 г. 19:19:00(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
Цитата:
Подпись передаю в таком виде:

В таком виде не поймет, нужно преобразовать к бинарному виду.
Для преобразования можно использовать функцию CryptStringToBinary.
Цитата:
Я так понимаю, что сюда надо передать указатель на сертификат

Вообще говоря, туда можно ничего не передавать.
А что Вам надо передавать - зависит от логики работы Вашей CryptGetSignerCertificateCallback и того, как там этот параметр будет использоваться.
Если Вы нашли каким-то особенным способом сертификат для проверки подписи - то да, его конечно можно передать как
Код:
msgPara.pvGetArg = (void *)pCert;

и затем просто вернуть из CryptGetSignerCertificateCallback.

Отредактировано пользователем 25 августа 2009 г. 19:23:43(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Flame_xXx  
#16 Оставлено : 25 августа 2009 г. 19:25:32(UTC)
Flame_xXx

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

Группы: Участники
Зарегистрирован: 27.10.2008(UTC)
Сообщений: 63

pvGetArg
Argument to pass to the callback function. Typically, this gets and verifies the message signer's certificate.

Код:

param.pfnGetSignerCertificate = global_my_get_cert;    /* этот callback должен возвернуть сертификат на котором проверяем сообщение*/
param.pvGetArg = (void*) certfile;		    /* передадим имя файла сертификата в функцию*/

PCCERT_CONTEXT WINAPI global_my_get_cert (void *pvGetArg, DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore)
{

    PCCERT_CONTEXT ret = NULL;

    ret = read_cert_from_my((char*) pvGetArg);
    return ret;
    UNREFERENCED_PARAMETER(dwCertEncodingType);
    UNREFERENCED_PARAMETER(pSignerId);
    UNREFERENCED_PARAMETER(hMsgCertStore);
}

PCCERT_CONTEXT read_cert_from_my (char *subject_name)
{
    PCCERT_CONTEXT  ret = NULL;
    HANDLE	    hCertStore = 0;        
    USES_CONVERSION;
    _lpw;

    /*--------------------------------------------------------------------*/
    /* Открываем справочник 'MY'*/
    /*    if (!( hCertStore = CertOpenSystemStore(0,"MY"))) {*/
    hCertStore = CertOpenStore(
			    CERT_STORE_PROV_SYSTEM, /* LPCSTR lpszStoreProvider*/
			    0,			    /* DWORD dwMsgAndCertEncodingType*/
			    0,			    /* HCRYPTPROV hCryptProv*/
			    CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG|
			    CERT_SYSTEM_STORE_CURRENT_USER, /* DWORD dwFlags*/
			    L"MY"		    /* const void *pvPara*/
			    );
    if (!hCertStore) {
	DebugErrorFL("CertOpenStore");
	return ret;
    }

    /* Найдем сертификат с соответствующим значением*/
    ret = CertFindCertificateInStore (hCertStore, 
	TYPE_DER,
	0, 
	CERT_FIND_SUBJECT_STR,
	A2W(subject_name),
	NULL);
    if (!ret) {
	DebugErrorFL("CertFindCertificateInStore");
    }

    if (!CertCloseStore (hCertStore, 0)) {
	DebugErrorFL("CertCloseStore");
    }

    return ret;
}

Как то так.. Взял из исходников csptest

Отредактировано пользователем 25 августа 2009 г. 19:27:21(UTC)  | Причина: Не указана

Offline EgorovAlexandr  
#17 Оставлено : 25 августа 2009 г. 20:24:05(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Сделал callback следующим образом:
Код:

PCCERT_CONTEXT WINAPI my_callback_function(void *pvGetArg,DWORD dwCertEncodingType,PCERT_INFO pSignerId,HCERTSTORE hMsgCertStore)
{
	return (PCCERT_CONTEXT)pvGetArg;
}

...

msgPara.pfnGetSignerCertificate = my_callback_function; //функция-callback
msgPara.pvGetArg = (void *)pCert; /* сертификат. Его я получаю из сертификата до callback самстоятельно, т.к. мне необходимо проверить ЭЦП сообщения по всем сертификатам из p7b-файла.*/


Ошибка по прежнему осталась.

Подпись передается в бинарном виде, размером 64 байта. Её текстовое представление:
F3 EE 54 F7 92 E9 07 B9 2C 29 B4 BB 17 52 F5 74 C4 1D 07 D6 8E 43 4D 5C B5 CB C3 BA 4B A0 35 2B 2D 96 A1 04 C9 E7 86 91 84 25 D1 E1 CA 77 3E 59 14 D2 F2 2F 7C FE 03 BC 01 4F BC 97 E6 33 7C

Отредактировано пользователем 25 августа 2009 г. 20:25:41(UTC)  | Причина: Не указана

Offline EgorovAlexandr  
#18 Оставлено : 25 августа 2009 г. 21:44:47(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Итак, вряд ли ошибка в подписи, потому решил проверить правильность сертификата. Для этого записал его в отдельный файл и пропарсил его с помощью dumpasn1.

Создание файла:
Код:
HCERTSTORE hStore;
if( !(hStore = CertOpenStore(CERT_STORE_PROV_FILENAME_A,CODE_TYPE,0,0,"123.cer")) )
{
	puts("Store not open");
}
PCCERT_CONTEXT tCert=NULL;
	
tCert = CertDuplicateCertificateContext(pCert);

if( tCert == NULL )
{
	puts("Error in duplicate cert");
}

if(!CertAddCertificateContextToStore(hStore,
                                          tCert,
                                          CERT_STORE_ADD_NEW,
                                          NULL))
{
	puts("error in export cert");
	printf("%X\n",GetLastError());
}
		
if( !CertSaveStore (hStore,X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,CERT_STORE_SAVE_AS_PKCS7,CERT_STORE_SAVE_TO_FILENAME_A,"123.cer",0) )
{
	puts("saveStore");
}

if( !CertFreeCertificateContext(tCert) )
	puts("Certificate not cleaned");
if( !CertCloseStore(hStore,CERT_CLOSE_STORE_CHECK_FLAG) )
	puts("Store not closed");


По результатам парсинга видно, что сертификат из второго хранилища полностью эквивалентен сертификату, который я сам записал в новое хранилище.

В чем проблема -- по прежнему не понимаю...
Offline Kirill Sobolev  
#19 Оставлено : 25 августа 2009 г. 21:47:45(UTC)
Кирилл Соболев

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

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

Поблагодарили: 177 раз в 168 постах
64 байта - это не CMS файл в формате p7b с сертификатом и подписью, это только подпись. такую подпись можно проверить только функцией CryptVerifySignature.
CryptVerifyDetachedMessageSignature же хочет именно PKCS#7 - то что лежит в p7b файле целиком.
Техническую поддержку оказываем тут
Наша база знаний
Offline EgorovAlexandr  
#20 Оставлено : 25 августа 2009 г. 22:24:43(UTC)
EgorovAlexandr

Статус: Участник

Группы: Участники
Зарегистрирован: 21.08.2009(UTC)
Сообщений: 21
Откуда: Москва

Kirill Sobolev написал:
64 байта - это не CMS файл в формате p7b с сертификатом и подписью, это только подпись. такую подпись можно проверить только функцией CryptVerifySignature.
CryptVerifyDetachedMessageSignature же хочет именно PKCS#7 - то что лежит в p7b файле целиком.





Функции CryptVerifyDetachedMessageSignature передал p7b файл полностью, сообщение и размер сообщения.

Если второй параметр функции (__in DWORD dwSignerIndex) == 0, то получаю ошибку 0x80090006 "Invalid Signature.", если параметр == 1, то ошибку 0x8009200E "The signed message doesn't have a signer for the specified signer index".

Уже прогресс =)

Отредактировано пользователем 25 августа 2009 г. 22:30:03(UTC)  | Причина: Не указана

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
3 Страницы<123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.