Summary: | СБиС++: не получается отправить отчёт | ||
---|---|---|---|
Product: | WINE@Etersoft | Reporter: | Александр Морозов <amorozov> |
Component: | Шифрование / ЭЦП | Assignee: | Александр Морозов <amorozov> |
Status: | CLOSED FIXED | QA Contact: | Andrey Vusik <night> |
Severity: | critical | ||
Priority: | P1 | CC: | DjSpiker, kondratyuk, lav, vitperov |
Version: | 1.0.11 | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: | |||
Заявки RT: | Связано с: | ||
Дата напоминания: | |||
Bug Depends on: | 7692 | ||
Bug Blocks: | 502, 5101 | ||
Deadline: | 2011-12-09 | ||
Attachments: |
Отправка отчётности с патчами для crypt32 из ванильного wine
Отправка отчётности в СБиС++ Подтверждение оператора |
Description
Александр Морозов
2010-06-25 15:13:44 MSD
Created attachment 1743 [details]
Отправка отчётности с патчами для crypt32 из ванильного wine
Если приложить ряд патчей для crypt32 из ванильного wine, то отправка начинается. В консоли видно, что используется нереализованная функция CryptSignMessage.
Писал тест для CryptSignMessage. Писал тест для CryptSignMessage. Реализации функции CryptSignMessage мешает то, что CryptAcquireCertificatePrivateKey в WINE завершается неудачно. CryptAcquireCertificatePrivateKey работает, только на той машине, на которой создан сертификат. Доработал тест так, чтобы он работал не только на той машине, на которой создавался используемый в нём сертификат. Для этого импортируется ключевая пара, использованная при создании сертификата. Попутно сделал на основе wine-etersoft-devel/cert/mkcert.c небольшую утилиту для генерации ключевой пары и сертификата в удобном для вставки в тест формате: wine-etersoft-devel/cert/genkeyandcert.c Дописал тест. Вообще, там не все фичи тестируются, но пока хватит. Реализация CryptSignMessage проходит меньше тестов, чем хотелось бы. Это связано с работой использующихся в ней функций CryptMsg*. Если в Windows вызывать в тесте мою реализацию CryptSignMessage, то она проходит больше тестов, чем в WINE. Исправил упоминавшийся выше баг в функциях CryptMsg*. Неправильно инициализировалось поле HashEncryptionAlgorithm. См. http://msdn.microsoft.com/en-us/library/aa378102(VS.85).aspx Инициализацию HashEncryptionAlgorithm я реализовал не совсем корректно. Поле HashEncryptionAlgorithm в структуре CMSG_SIGNER_ENCODE_INFO может отсутствовать. Переделал. Добавил поддержку pSignPara->cMsgCert и pSignPara->cMsgCrl в CryptSignMessage. В CSignedMsgData_Sign функция CryptSignHashW вызывается с жёстко заданным типом ключа. Сделал, чтобы использовался тип ключа, передаваемый в CryptMsgOpenToEncode. Теперь при отправке отчётности в окне "Подробно..." видно, что возникает ошибка на 2-м шаге из 3-х: Ошибка криптографии. Invalid parameter (0x57) Проблема была связана с тем, что использовался освобождённый хэндл криптопровайдера. Пофиксил. После этого оказалось, что используется нереализованная в WINE функция: wine: Call from 0x7e9b873f to unimplemented function crypt32.dll.CryptEncryptMessage, aborting Добавил стаб для неё. Написал тест для CryptEncryptMessage. Реализовал CryptEncryptMessage поверх функций CryptMsg*. Проверил, что реализация проходит тесты, на winxp (вставив реализацию в кросстест). В wine функция не работает, так как в CryptMsgOpenToEncode не реализована поддержка CMSG_ENVELOPED. попробуйте обновить СБИС++ до версии 2.30.50 В 2.3.50 та же проблема. Начал писать тесты для CryptMsg-функций, работающих с enveloped сообщениями. > В CSignedMsgData_Sign функция CryptSignHashW вызывается с
> жёстко заданным типом ключа. Сделал, чтобы
> использовался тип ключа, передаваемый в
> CryptMsgOpenToEncode.
Заметил, что сломал данным исправлением ряд тестов в dlls/crypt32/tests/msg.c. Исправил.
Писал тесты для тесты для CryptMsg-функций, работающих с enveloped сообщениями. Занимался реализацией поддержки enveloped сообщенией в CryptMsg-функциях. Занимался реализацией поддержки enveloped сообщенией в CryptMsg-функциях. Реализовал работу с enveloped сообщениями в нужном нам объёме. Но есть проблема. Сообщения отличаются по длине от тех, что формируются в Windows. По-видимому, как-то неправильно заполняется поле encryptedKey. При расшифровке в Windows созданного в WINE сообщения получаем NTE_BAD_DATA. Разобрался, как надо заполнять поле encryptedKey в сообщениях. От SIMPLEBLOB с зашифрованным ключом надо отрезать первые 12 байт (BLOBHEADER и ALG_ID), а затем то, что осталось, развернуть: {1, 2, 3, 4, 5, 6, 7, ...} -> {..., 7, 6, 5, 4, 3, 2, 1}. Тесты для CryptEncryptMessage теперь завершаются успешно. Но отправка отчёта в СБиС++ всё равно не работает. Судя по всему, надо добавить поддержку callback-функций, которые должны вызываться из CryptMsgOpenToEncode. Занимался добавлением поддержки callback-функций. Created attachment 1794 [details]
Отправка отчётности в СБиС++
Сейчас отчётность отправляется (переходит в состояние "Ожидается ответ оператора"), но при отправке возникают ошибки. Добавил поддержку CERT_RDN_UNICODE_STRING в CertRDNValueToStr. Надо добавить поддержку CMSG_ENVELOPED в функциях CDecodeMsg_*: fixme:crypt:CDecodeMsg_DecodeContent unimplemented for type CMSG_ENVELOPED Занимался добавлением поддержки enveloped сообщений в функциях CDecodeMsg_*. Занимался добавлением поддержки enveloped сообщений в функциях CDecodeMsg_*. Реализовал декодирование enveloped сообщений. Тесты со встроенным в wine криптопровайдером проходят. При отправке отчётности СБиС++ сообщает об ошибке "нет действительного сертификата получателя!" можно узнать на какой версии КриптоПро CSP вы тестируете ??? > можно узнать на какой версии КриптоПро CSP
> вы тестируете ???
Версия ядра СКЗИ: 3.6.5355 КС1
Версия продукта: 3.6.5402
> При отправке отчётности СБиС++ сообщает об
> ошибке "нет действительного сертификата
> получателя!"
Эта ошибка была из-за того, что была выбрана не та налоговая, для которой указан сертификат. Если выбрать правильную налоговую, то получаем "Отсутствует сертификат шифрования!"
Надо добавить поддержку CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM в CryptMsgGetParam. Занимался написанием тестов для CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM. Добавил поддержку CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM. Добавил поддержку callback-функции PFN_CMSG_IMPORT_KEY_TRANS. Created attachment 1803 [details]
Подтверждение оператора
Теперь под WINE приходит подтверждение оператора
Улучшил поддержку аргумента CERT_KEY_IDENTIFIER_PROP_ID функции CertGetCertificateContextProperty. В том случае, если нет нужного свойства, согласно MSDN, функция возвращает SHA1-хэш SubjectPublicKeyInfo. Тонкость в том, что она это делает только для подписанного сертификата. Для неподписанного возвращается FALSE и устанавливается ошибка ERROR_INVALID_DATA. В wine есть тест с неподписанным сертификатом. С подписанным, как я понял, потестировать не догадались. Исправил некоторые проблемы в коде, ответственном за получение подходящего криптопровайдера (хак для КриптоПро). При отправке отчётности завершается с ошибкой функция CryptMsgUpdate (вызываемая после CryptMsgOpenToDecode). В Windows с теми же входными данными получается та же ошибка (CRYPT_E_ASN1_BADTAG). По-видимому, проблема не в CryptMsgUpdate, а где-то раньше. Понять, откуда берутся передаваемые CryptMsgUpdate данные, пока не удалось. В логах обемена по сети, полученных с помощью tcpdump -nxi eth0 -s 10240 port 8585, найти их не удалось. Посмотрел версии 2.3.50, 2.3.55. Та же проблема. Откатил патч: commit 7596a82f55339ed7d1df1764348e01d9b8a6d1e5 Author: Alexander Morozov <amorozov@etersoft.ru> Date: Thu Aug 19 17:36:21 2010 +0400 crypt32: Add support for CERT_RDN_UNICODE_STRING (eterbug #5694). В wine появился похожий патч. Поставил СБиС++ 2.4.25 на [T] Windows XP SP3 в vbox. Отчётность отправляется, но ответы почему-то не приходят. Написал письмо в Тензор. Так как машина [T] Windows XP SP3 зависла в состоянии "Запускается", установил СБиС++ на машину Windows XP clean. С помощью специалиста из Тензора настроил отправку отчётности. Ниже инструкция для 2.4.25. 1. Сервис -> Конфигурация задачи... В поле "Оператор связи" щёлкаем на кнопке справа. Выбираем "ТЕНЗОР комания (...)", нажимаем F3. На вкладке "Сертификаты" устанавливаем сертификат oper2012.cer, скачанный на странице http://ereport.sbis.ru/uc/sertecp Сохранить, два раза щёлкаем на "ТЕНЗОР компания (...)", Сохранить 2. Контрагенты -> Налогоплательщики -> ООО "Золотое дно", Ответственные лица. Нажимаем Insert, щёлкаем на кнопке справа в поле "ФИО". Золотое дно -> Администрация, Создать, в качестве фамилии, имени и отчества пишем "Дир", Сохранить, два раза щёлкаем, чтобы выбрать, ставим галочку напротив "Представитель в ФНС", заполняем поле "С", Сохранить. Удаляем руководителя, созданного не нами. В строке с добавленным руководителем щёлкаем на "Получить сертификат", Установить с носителя (в дисководе должна быть дискета, на которую записан образ с ключом, см. письмо в папке Тензор), Загрузить сертификат, сохраняем. На вкладке Общие прописываем ИНН и КПП (см. письмо в папке Тензор), сохраняем. 3. Снова выбираем ООО "Золотое дно", Мастер создания налогоплательщика, в одной из форм ставим галочку "Обновить информацию о лицензиях", вводим код активации (см. письмо в папке Тензор), на предложение настроить почтовый протокол отвечаем "Нет", на сообщении об ошибке нажимаем "ОК", потом можно нажать "Отменить". 4. Теперь можно проверить отправку отчётности Слева выбираем "ФНС", выбираем "сентябрь и за III квартал". Нажимаем на ссылку "отчёт", выбираем "Бухгалтерская отчетность". В поле "Налоговая инспекция" выбираем "Тестовая налоговая", в поле "Руководитель" выбираем "Дир Дир Дир", Проверить отчёт, Сохранить и выйти. Передать на подпись, в качестве подписанта выбираем "Дир Дир Дир", Подписать и отправить. 5. Через какое-то время при нажатии "Получить ответы" будут получены ответы. При использовании совместно с КриптоПро CSP 3.6 в поле статус у сертификатов, срок действия которых не истёк, выводится "Криптопровайдер отсутствует или повреждён." > При использовании совместно с КриптоПро CSP 3.6 в поле статус у сертификатов,
> срок действия которых не истёк, выводится "Криптопровайдер отсутствует или
> повреждён."
После корректного исправления #7692 эта проблема ушла.
После нажатия "Передать на подпись" отчёт не переходит в состояние "Готов к отправке". В логе при передаче на подпись: trace:crypt:CryptMsgOpenToDecode (00010001, 00000000, 00000000, 00000000, (nil), (nil)) trace:crypt:CryptMsgUpdate (0x1252a160, 0x6e20a38, 2578, 1) trace:crypt:CDecodeMsg_Update (0x1252a160, 0x6e20a38, 2578, 1) trace:crypt:CryptDecodeObjectEx (0x00000001, #0021, 0x127cb8c0, 2578, 0x00008000, (nil), 0x329970, 0x32996c) trace:cryptasn:CRYPT_AsnDecodePKCSContentInfo 0x127cb8c0, 2578, 00008000, (nil), 0x329970, 1763126081 trace:cryptasn:CRYPT_AsnDecodePKCSContentInfoInternal 0x127cb8c0, 2578, 00000000, (nil), 1763126081, (nil) trace:cryptasn:CRYPT_AsnDecodeSequence 0x32975c, 2, 0x127cb8c0, 2578, 00000000, (nil), (nil), 1763126081, (nil) trace:cryptasn:CRYPT_AsnDecodeSequence returning 0 (8009310b) trace:crypt:CryptDecodeObjectEx returning 0 trace:crypt:CryptMsgClose (0x1252a160) trace:crypt:CryptMsgClose freeing 0x1252a160 Добавил в CRYPT_AsnDecodePKCSContentInfo распечатку данных, которые ей передаются на декодирование. На Windows XP с установленным КриптоПро CSP 3.6 на этих данных получается такая же ошибка. > trace:crypt:CryptMsgUpdate (0x1252a160, 0x6e20a38, 2578, 1)
Блоб, передаваемый этой функции в WINE - XML-документ.
С помощью WinDbg получил блоб, передаваемый в такой же ситуации на Windows. Полученные данные без проблем декодируются с помощью openssl asn1parse -inform DER -in имя_файла. Также сделал тест и убедился, что если в Wine установлен КриптоПро, то CryptMsgUpdate для данного блоба завершается успешно.
Таким образом, проблема не в CryptMsgUpdate, а где-то раньше.
При использовании СБиС++ ЭО 2.4.42 передача на подпись и отправка работают, но ответы не приходят. Из Тензора прислали тестовые утилиты, демонстрирующие проблему в Wine. Собрал утилиты. Создал всё необходимое для их работы. Enveloped сообщения, создаваемые в Wine и в Windows с помощью CryptMsgOpenToEncode/CryptMsgUpdate, различаются. В создаваемом в Wine сообщении отсутствуют параметры алгоритма шифрования. Callback-функция PFN_CMSG_GEN_CONTENT_ENCRYPT_KEY может менять поле ContentEncryptionAlgorithm в структуре CMSG_CONTENT_ENCRYPT_INFO (http://msdn.microsoft.com/en-us/library/windows/desktop/bb931373(v=vs.85).aspx). Добавил поддержку обновления этого поля. Вообще, поддержку callback-ов я как-то не очень хорошо реализовал. Там ещё есть подобные недоработки. Теперь файл encrypt.bin, создаваемый полученной из Тензора утилитой, такого же размера, как и в Windows. Изменил поведение CryptFindCertificateKeyProvInfo. Сделал, чтобы она работала не только для ключей AT_SIGNATURE, но и для AT_KEYEXCHANGE. Для поиска соответствующего сертификату ключа теперь используется параметр ключа KP_CERTIFICATE. Теперь обе полученные от Тензора утилиты работают в Wine. После последнего исправления после отправки отчёта приходят все ответы. Запускал на последнем eterhack в бутылке buh/sbis/2.4.42-vcrun2008 в контейнере eterhack. Для нормальной работы СБиС++ ЭО 2.4.42 там был установлен vcrun2008 через winetricks и импортирован etersoft.reg из ветки master закрытой части. > Изменил поведение CryptFindCertificateKeyProvInfo. Сделал, чтобы она работала
> не только для ключей AT_SIGNATURE, но и для AT_KEYEXCHANGE. Для поиска
> соответствующего сертификату ключа теперь используется параметр ключа
> KP_CERTIFICATE.
На всякий случай сделал, чтобы использовался старый метод проверки, если KP_CERTIFICATE не поддерживается, т.к. во встроенном в Wine криптопровайдере его поддержка не реализована.
принято |