Bug 5694

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
Не получается отправить отчёт. При щелчке на "Подписать и отправить" ничего не происходит.

/var/ftp/pvt/Windows/Учётные, бухгалтерские/SBIS/demo
2.3.38
/var/ftp/pvt/Windows/Учётные, бухгалтерские/CryptoPro
CSP/3.6/csp-win32-kc1-rus.msi
Comment 1 Александр Морозов 2010-06-25 15:28:40 MSD
Created attachment 1743 [details]
Отправка отчётности с патчами для crypt32 из ванильного wine

Если приложить ряд патчей для crypt32 из ванильного wine, то отправка начинается. В консоли видно, что используется нереализованная функция CryptSignMessage.
Comment 2 Александр Морозов 2010-06-25 20:27:00 MSD
Писал тест для CryptSignMessage.
Comment 3 Александр Морозов 2010-06-28 21:07:33 MSD
Писал тест для CryptSignMessage.
Comment 4 Александр Морозов 2010-06-29 19:54:32 MSD
Реализации функции CryptSignMessage мешает то, что CryptAcquireCertificatePrivateKey в WINE завершается неудачно.
Comment 5 Александр Морозов 2010-06-29 20:45:07 MSD
CryptAcquireCertificatePrivateKey работает, только на той машине, на которой создан сертификат.
Comment 6 Александр Морозов 2010-06-30 19:28:03 MSD
Доработал тест так, чтобы он работал не только на той машине, на которой создавался используемый в нём сертификат. Для этого импортируется ключевая пара, использованная при создании сертификата. Попутно сделал на основе wine-etersoft-devel/cert/mkcert.c небольшую утилиту для генерации ключевой пары и сертификата в удобном для вставки в тест формате: wine-etersoft-devel/cert/genkeyandcert.c
Comment 7 Александр Морозов 2010-07-01 17:34:13 MSD
Дописал тест. Вообще, там не все фичи тестируются, но пока хватит.
Реализация CryptSignMessage проходит меньше тестов, чем хотелось бы. Это связано с работой использующихся в ней функций CryptMsg*. Если в Windows вызывать в тесте мою реализацию CryptSignMessage, то она проходит больше тестов, чем в WINE.
Comment 8 Александр Морозов 2010-07-02 14:46:14 MSD
Исправил упоминавшийся выше баг в функциях CryptMsg*. Неправильно инициализировалось поле HashEncryptionAlgorithm. См. http://msdn.microsoft.com/en-us/library/aa378102(VS.85).aspx
Comment 9 Александр Морозов 2010-07-02 20:36:18 MSD
Инициализацию HashEncryptionAlgorithm я реализовал не совсем корректно. Поле HashEncryptionAlgorithm в структуре CMSG_SIGNER_ENCODE_INFO может отсутствовать. Переделал.
Добавил поддержку pSignPara->cMsgCert и pSignPara->cMsgCrl в CryptSignMessage.
В CSignedMsgData_Sign функция CryptSignHashW вызывается с жёстко заданным типом ключа. Сделал, чтобы использовался тип ключа, передаваемый в CryptMsgOpenToEncode.

Теперь при отправке отчётности в окне "Подробно..." видно, что возникает ошибка на 2-м шаге из 3-х:
Ошибка криптографии. Invalid parameter (0x57)
Comment 10 Александр Морозов 2010-07-05 15:42:17 MSD
Проблема была связана с тем, что использовался освобождённый хэндл криптопровайдера. Пофиксил. После этого оказалось, что используется нереализованная в WINE функция:
wine: Call from 0x7e9b873f to unimplemented function crypt32.dll.CryptEncryptMessage, aborting
Добавил стаб для неё.
Comment 11 Александр Морозов 2010-07-13 21:23:49 MSD
Написал тест для CryptEncryptMessage. Реализовал CryptEncryptMessage поверх функций CryptMsg*. Проверил, что реализация проходит тесты, на winxp (вставив реализацию в кросстест). В wine функция не работает, так как в CryptMsgOpenToEncode не реализована поддержка CMSG_ENVELOPED.
Comment 12 Абросимов Виктор 2010-07-14 14:26:37 MSD
попробуйте обновить СБИС++ до версии 2.30.50
Comment 13 Александр Морозов 2010-07-14 22:12:04 MSD
В 2.3.50 та же проблема.
Начал писать тесты для CryptMsg-функций, работающих с enveloped сообщениями.
Comment 14 Александр Морозов 2010-07-15 15:30:33 MSD
> В CSignedMsgData_Sign функция CryptSignHashW вызывается с
> жёстко заданным типом ключа. Сделал, чтобы
> использовался тип ключа, передаваемый в
> CryptMsgOpenToEncode.

Заметил, что сломал данным исправлением ряд тестов в dlls/crypt32/tests/msg.c. Исправил.
Comment 15 Александр Морозов 2010-07-15 21:55:46 MSD
Писал тесты для тесты для CryptMsg-функций, работающих с enveloped сообщениями.
Comment 16 Александр Морозов 2010-08-04 20:57:06 MSD
Занимался реализацией поддержки enveloped сообщенией в CryptMsg-функциях.
Comment 17 Александр Морозов 2010-08-05 21:11:25 MSD
Занимался реализацией поддержки enveloped сообщенией в CryptMsg-функциях.
Comment 18 Александр Морозов 2010-08-06 19:35:24 MSD
Реализовал работу с enveloped сообщениями в нужном нам объёме. Но есть проблема. Сообщения отличаются по длине от тех, что формируются в Windows. По-видимому, как-то неправильно заполняется поле encryptedKey.
Comment 19 Александр Морозов 2010-08-09 18:06:35 MSD
При расшифровке в Windows созданного в WINE сообщения получаем NTE_BAD_DATA.
Comment 20 Александр Морозов 2010-08-13 22:15:04 MSD
Разобрался, как надо заполнять поле encryptedKey в сообщениях. От SIMPLEBLOB с зашифрованным ключом надо отрезать первые 12 байт (BLOBHEADER и ALG_ID), а затем то, что осталось, развернуть: {1, 2, 3, 4, 5, 6, 7, ...} -> {..., 7, 6, 5, 4, 3, 2, 1}.
Comment 21 Александр Морозов 2010-08-16 21:31:32 MSD
Тесты для CryptEncryptMessage теперь завершаются успешно. Но отправка отчёта в СБиС++ всё равно не работает. Судя по всему, надо добавить поддержку callback-функций, которые должны вызываться из CryptMsgOpenToEncode.
Comment 22 Александр Морозов 2010-08-17 21:04:40 MSD
Занимался добавлением поддержки callback-функций.
Comment 23 Александр Морозов 2010-08-18 21:11:14 MSD
Created attachment 1794 [details]
Отправка отчётности в СБиС++
Comment 24 Александр Морозов 2010-08-18 21:12:21 MSD
Сейчас отчётность отправляется (переходит в состояние "Ожидается ответ оператора"), но при отправке возникают ошибки.
Comment 25 Александр Морозов 2010-08-19 21:18:48 MSD
Добавил поддержку CERT_RDN_UNICODE_STRING в CertRDNValueToStr.
Comment 26 Александр Морозов 2010-08-20 21:43:29 MSD
Надо добавить поддержку CMSG_ENVELOPED в функциях CDecodeMsg_*:
fixme:crypt:CDecodeMsg_DecodeContent unimplemented for type CMSG_ENVELOPED
Comment 27 Александр Морозов 2010-08-23 21:53:10 MSD
Занимался добавлением поддержки enveloped сообщений в функциях CDecodeMsg_*.
Comment 28 Александр Морозов 2010-08-24 21:46:23 MSD
Занимался добавлением поддержки enveloped сообщений в функциях CDecodeMsg_*.
Comment 29 Александр Морозов 2010-08-25 20:09:52 MSD
Реализовал декодирование enveloped сообщений. Тесты со встроенным в wine криптопровайдером проходят.

При отправке отчётности СБиС++ сообщает об ошибке "нет действительного сертификата получателя!"
Comment 30 Абросимов Виктор 2010-08-25 20:12:42 MSD
можно узнать на какой версии КриптоПро CSP вы тестируете ???
Comment 31 Александр Морозов 2010-08-25 20:28:15 MSD
> можно узнать на какой версии КриптоПро CSP
> вы тестируете ???
Версия ядра СКЗИ: 3.6.5355 КС1
Версия продукта: 3.6.5402
Comment 32 Александр Морозов 2010-08-25 21:00:40 MSD
> При отправке отчётности СБиС++ сообщает об
> ошибке "нет действительного сертификата
> получателя!"
Эта ошибка была из-за того, что была выбрана не та налоговая, для которой указан сертификат. Если выбрать правильную налоговую, то получаем "Отсутствует сертификат шифрования!"
Comment 33 Александр Морозов 2010-08-26 20:40:04 MSD
Надо добавить поддержку CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM в CryptMsgGetParam.
Comment 34 Александр Морозов 2010-08-27 20:30:49 MSD
Занимался написанием тестов для CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM.
Comment 35 Александр Морозов 2010-08-30 21:52:02 MSD
Добавил поддержку CMSG_RECIPIENT_COUNT_PARAM и CMSG_RECIPIENT_INFO_PARAM.
Comment 36 Александр Морозов 2010-08-31 21:53:26 MSD
Добавил поддержку callback-функции PFN_CMSG_IMPORT_KEY_TRANS.
Comment 37 Александр Морозов 2010-08-31 21:56:53 MSD
Created attachment 1803 [details]
Подтверждение оператора

Теперь под WINE приходит подтверждение оператора
Comment 38 Александр Морозов 2010-09-01 20:47:41 MSD
Улучшил поддержку аргумента CERT_KEY_IDENTIFIER_PROP_ID функции CertGetCertificateContextProperty. В том случае, если нет нужного свойства, согласно MSDN, функция возвращает SHA1-хэш SubjectPublicKeyInfo. Тонкость в том, что она это делает только для подписанного сертификата. Для неподписанного возвращается FALSE и устанавливается ошибка ERROR_INVALID_DATA. В wine есть тест с неподписанным сертификатом. С подписанным, как я понял, потестировать не догадались.
Comment 39 Александр Морозов 2010-09-03 22:23:21 MSD
Исправил некоторые проблемы в коде, ответственном за получение подходящего криптопровайдера (хак для КриптоПро).
Comment 40 Александр Морозов 2010-09-07 21:44:23 MSD
При отправке отчётности завершается с ошибкой функция CryptMsgUpdate (вызываемая после CryptMsgOpenToDecode). В Windows с теми же входными данными получается та же ошибка (CRYPT_E_ASN1_BADTAG). По-видимому, проблема не в CryptMsgUpdate, а где-то раньше.
Comment 41 Александр Морозов 2010-09-08 21:26:41 MSD
Понять, откуда берутся передаваемые CryptMsgUpdate данные, пока не удалось. В логах обемена по сети, полученных с помощью tcpdump -nxi eth0 -s 10240 port 8585, найти их не удалось.
Comment 42 Александр Морозов 2010-09-09 15:09:00 MSD
Посмотрел версии 2.3.50, 2.3.55. Та же проблема.
Comment 43 Виталий Перов 2010-10-20 15:32:49 MSD
Откатил патч:

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 появился похожий патч.
Comment 44 Александр Морозов 2011-10-06 13:01:30 MSK
Поставил СБиС++ 2.4.25 на [T] Windows XP SP3 в vbox. Отчётность отправляется, но ответы почему-то не приходят. Написал письмо в Тензор.
Comment 45 Александр Морозов 2011-10-19 14:25:05 MSK
Так как машина [T] Windows XP SP3 зависла в состоянии "Запускается", установил СБиС++ на машину Windows XP clean.
Comment 46 Александр Морозов 2011-10-20 19:28:37 MSK
С помощью специалиста из Тензора настроил отправку отчётности. Ниже инструкция для 2.4.25.

1. Сервис -> Конфигурация задачи...
В поле "Оператор связи" щёлкаем на кнопке справа. Выбираем "ТЕНЗОР комания (...)", нажимаем F3. На вкладке "Сертификаты" устанавливаем сертификат oper2012.cer, скачанный на странице http://ereport.sbis.ru/uc/sertecp
Сохранить, два раза щёлкаем на "ТЕНЗОР компания (...)", Сохранить

2. Контрагенты -> Налогоплательщики -> ООО "Золотое дно", Ответственные лица. Нажимаем Insert, щёлкаем на кнопке справа в поле "ФИО". Золотое дно -> Администрация, Создать, в качестве фамилии, имени и отчества пишем "Дир", Сохранить, два раза щёлкаем, чтобы выбрать, ставим галочку напротив "Представитель в ФНС", заполняем поле "С", Сохранить. Удаляем руководителя, созданного не нами.
В строке с добавленным руководителем щёлкаем на "Получить сертификат", Установить с носителя (в дисководе должна быть дискета, на которую записан образ с ключом, см. письмо в папке Тензор), Загрузить сертификат, сохраняем.
На вкладке Общие прописываем ИНН и КПП (см. письмо в папке Тензор), сохраняем.

3. Снова выбираем ООО "Золотое дно", Мастер создания налогоплательщика, в одной из форм ставим галочку "Обновить информацию о лицензиях", вводим код активации (см. письмо в папке Тензор), на предложение настроить почтовый протокол отвечаем "Нет", на сообщении об ошибке нажимаем "ОК", потом можно нажать "Отменить".

4. Теперь можно проверить отправку отчётности
Слева выбираем "ФНС", выбираем "сентябрь и за III квартал".
Нажимаем на ссылку "отчёт", выбираем "Бухгалтерская отчетность". 
В поле "Налоговая инспекция" выбираем "Тестовая налоговая", в поле "Руководитель" выбираем "Дир Дир Дир", Проверить отчёт, Сохранить и выйти.
Передать на подпись, в качестве подписанта выбираем "Дир Дир Дир", Подписать и отправить.

5. Через какое-то время при нажатии "Получить ответы" будут получены ответы.
Comment 47 Александр Морозов 2011-10-21 16:26:55 MSK
При использовании совместно с КриптоПро CSP 3.6 в поле статус у сертификатов, срок действия которых не истёк, выводится "Криптопровайдер отсутствует или повреждён."
Comment 48 Александр Морозов 2011-10-28 20:41:42 MSK
> При использовании совместно с КриптоПро CSP 3.6 в поле статус у сертификатов,
> срок действия которых не истёк, выводится "Криптопровайдер отсутствует или
> повреждён."
После корректного исправления #7692 эта проблема ушла.
Comment 49 Александр Морозов 2011-10-31 15:41:54 MSK
После нажатия "Передать на подпись" отчёт не переходит в состояние "Готов к отправке".
Comment 50 Александр Морозов 2011-11-01 17:47:55 MSK
В логе при передаче на подпись:

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 на этих данных получается такая же ошибка.
Comment 51 Александр Морозов 2011-11-02 19:52:45 MSK
> trace:crypt:CryptMsgUpdate (0x1252a160, 0x6e20a38, 2578, 1)
Блоб, передаваемый этой функции в WINE - XML-документ.

С помощью WinDbg получил блоб, передаваемый в такой же ситуации на Windows. Полученные данные без проблем декодируются с помощью openssl asn1parse -inform DER -in имя_файла. Также сделал тест и убедился, что если в Wine установлен КриптоПро, то CryptMsgUpdate для данного блоба завершается успешно.

Таким образом, проблема не в CryptMsgUpdate, а где-то раньше.
Comment 53 Александр Морозов 2011-11-23 20:21:42 MSK
При использовании СБиС++ ЭО 2.4.42 передача на подпись и отправка работают, но ответы не приходят.
Comment 54 Александр Морозов 2011-11-29 17:47:40 MSK
Из Тензора прислали тестовые утилиты, демонстрирующие проблему в Wine.
Собрал утилиты. Создал всё необходимое для их работы.
Comment 56 Александр Морозов 2011-11-30 19:57:24 MSK
Enveloped сообщения, создаваемые в Wine и в Windows с помощью CryptMsgOpenToEncode/CryptMsgUpdate, различаются. В создаваемом в Wine сообщении отсутствуют параметры алгоритма шифрования.
Comment 57 Александр Морозов 2011-12-01 17:59:12 MSK
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-ов я как-то не очень хорошо реализовал. Там ещё есть подобные недоработки.
Comment 58 Александр Морозов 2011-12-01 18:01:19 MSK
Теперь файл encrypt.bin, создаваемый полученной из Тензора утилитой, такого же размера, как и в Windows.
Comment 59 Александр Морозов 2011-12-02 18:35:33 MSK
Изменил поведение CryptFindCertificateKeyProvInfo. Сделал, чтобы она работала не только для ключей AT_SIGNATURE, но и для AT_KEYEXCHANGE. Для поиска соответствующего сертификату ключа теперь используется параметр ключа KP_CERTIFICATE.

Теперь обе полученные от Тензора утилиты работают в Wine.
Comment 60 Александр Морозов 2011-12-02 19:40:45 MSK
После последнего исправления после отправки отчёта приходят все ответы.
Запускал на последнем eterhack в бутылке buh/sbis/2.4.42-vcrun2008 в контейнере eterhack. Для нормальной работы СБиС++ ЭО 2.4.42 там был установлен vcrun2008 через winetricks и импортирован etersoft.reg из ветки master закрытой части.
Comment 61 Александр Морозов 2011-12-05 15:14:58 MSK
> Изменил поведение CryptFindCertificateKeyProvInfo. Сделал, чтобы она работала
> не только для ключей AT_SIGNATURE, но и для AT_KEYEXCHANGE. Для поиска
> соответствующего сертификату ключа теперь используется параметр ключа
> KP_CERTIFICATE.

На всякий случай сделал, чтобы использовался старый метод проверки, если KP_CERTIFICATE не поддерживается, т.к. во встроенном в Wine криптопровайдере его поддержка не реализована.
Comment 62 Andrey Vusik 2011-12-13 19:41:40 MSK
принято