Добрый день.
Я разобрался с причинами возникновения данной ошибки [ErrorCode: 0x8009000f] при проверке конкретной открепленной подписи в Linux.
Причин тут две:
1) Не совсем корректные по смыслу данные в файле подписи
2) Не совсем корректная процедура разбора подписи в библиотеке libcapi20.so
Начну с первой причины. Сам файл подписи является вполне реальным, содержащим две подписи (и их атрибутивный состав) к исходному документу. Эти подписи выполнены по одинаковому алгоритму ГОСТ Р 34.11/34.10-2001. Если посмотреть на файла структуру подписи (взято из rfc5652):
Код:SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms DigestAlgorithmIdentifiers,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
signerInfos SignerInfos }
то проблема с рассматриваемым файлом содержится в элементе
digestAlgorithms DigestAlgorithmIdentifiers данной структуры, где перечисляются идентификаторы хэш-функций, используемых при вычислении подписи.
В моем файле данная секция содержит две одинаковые записи об алгоритме
ГОСТ Р 34.11-94 / OID 1.2.643.2.2.9, хотя по идее там должна быть только одна такая запись т.к. обе подписи в файле выполнены по одному и тому же алгоритму. Видимо, при добавлении второй подписи в этот файл данные об идентификаторе ее хэш-функции были просто добавлены в элемент digestAlgorithms без каких либо проверок. Каким ПО была сформирована данная подпись выяснить, к сожалению, не удалось.
Теперь про вторую причину. Как я уже писал ранее, указанный файл подписи спокойно проверяется в Microsoft Windows. При этом проверка подписи в Linux при помощи кастомной утилитой, основанной на реализации ГОСТовских алгоритмов от BouncyCastle, также проходит успешно. Но при использовании в Linux КриптоПРО CSP версии 4.0 и 5.0 - возникает указанная ошибка.
Она происходит при декодировании подписи в процедуре CryptMsgUpdate модуля libcapi20.so, которая натыкается на дублирующую запись в списке идентификаторов используемых хэш-функций. Скорее всего при декодировании производится построение словаря (ключ-значение) на основе списка идентификаторов хэш-функций, и наличие повторяющейся записи как раз и приводит к указанной ошибке "Object already exists".
В ОС Windows используется нативная реализация декодирования подписи от Microsfot из модуля crypt32.dll (у BouncyCastle тоже собственная процедура). В ней при декодировании digestAlgorithms скорее всего используется не словарь, а простой список (либо словарь при добавлении предварительно проверяется), - и при таком подходе обработка рассматриваемой подписи не вызывает никаких ошибок.
Ради эксперимента я перекодировал программными средствами свой файл подписи, убрав из него дубль идентификатора алгоритма хэш-функции. После этого проверка в Linux КриптоПРО CSP прошла успешно.
Хотелось бы услышать комментарий разработчиков, будет ли указанная проблема модуля libcapi20.so исправлена в ближайших релизах для обеспечения единообразного поведения при разборе подписи с использованием КриптоПРО CSP в ОС Widows и ОС Linux?
Спасибо.