Так сложилось, что одним из модулей моего велосипеда было суждено стать функциональности цифровой подписи. Беглым взглядом окинув мануал поставщика я выделил на это один день, ожидая сделать все за четыре часа. В результате все вылилось в неделю кодирования :(.
Так как в фронтэнд я пока не углублялся и javascript пользуюсь по мере необходимости, я не придал значения коду асинхронной работы с плагином.
function SignCreate(certSubjectName, dataToSign) { return new Promise(function(resolve, reject){ cadesplugin.async_spawn(function *(args) { try { var oStore = yield cadesplugin.CreateObjectAsync("CAPICOM.Store"); yield oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED); var CertificatesObj = yield oStore.Certificates; var oCertificates = yield CertificatesObj.Find( CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME, certSubjectName); var Count = yield oCertificates.Count; if (Count == 0) { throw("Certificate not found: " + args[0]); } var oCertificate = yield oCertificates.Item(1); var oSigner = yield cadesplugin.CreateObjectAsync("CAdESCOM.CPSigner"); yield oSigner.propset_Certificate(oCertificate); var oSignedData = yield cadesplugin.CreateObjectAsync("CAdESCOM.CadesSignedData"); yield oSignedData.propset_Content(dataToSign); var sSignedMessage = yield oSignedData.SignCades(oSigner, CADESCOM_CADES_BES); yield oStore.Close(); args[2](sSignedMessage); } catch (e) { args[3]("Failed to create signature. Error: " + GetErrorMessage(err)); } }, certSubjectName, dataToSign, resolve, reject); }); }
Я конечно не системный кодер, читающий ассемблер в шестнадцатеричных кодах, но признаюсь первый раз в жизни не мог три дня понять смысл этого кода. Пришлось поднимать доки по промисам и генераторам и углублятся в них, чтобы понять, что cadesplugin.async_spawn получает на вход генератор, который итерируется до done (может фронтэндщики меня поправят и я так до конца и не понял).
Более того, это не очевидно сразу, но работа с плагином из javascript должна быть реализована в четырех вариантах:
- Браузер с промисами синхронный плагин
- Браузер с промисами асинхронный плагин
- Браузер без промисов синхронный плагин
- Браузер без промисов асинхронный плагин (для полноты системы, такого наверно не бывает)
Как понять что плагин синхронный: cades_plaugin.hasOwnProperty(«CreateObject»);
Как понять, что браузер с промисами: !!window.promise;
Кроме этого как всегда IE требует подключения отдельной либы, как я понял для полифила промисов (полифилы вкурил заодно с промисами и генераторами:) ).
Как только концептуальная схема была понята, дальнейшее кодирование было делом техники.
p.s. Единственное неприятное обстоятельство, что подпись создается проверяется в FireFox, создается, но не проверяется в Crome. В чем дело не ясно, я запостил на форум КриптПро.
Update: p.p.s. КриптоПро меня спас, я закосячил в асинхронном коде. Юольшое спасибо службе поддержки.
Вот в целом все. Надеюсь кому то сберегу время и здоровье, т.к. судя по форуму КриптоПро масса людей страдает из за той же проблемы.

