Pull to refresh

Итератор генератора в промисе или интеграция КриптоПро browser plugin

Reading time2 min
Views5.1K
Хочу поделиться опытом интеграции КриптоПро browser plugin в свой велосипед. Кому интересно добро пожаловать по кат. Прошу заранее простить за тяжелый слог
Так сложилось, что одним из модулей моего велосипеда было суждено стать функциональности цифровой подписи. Беглым взглядом окинув мануал поставщика я выделил на это один день, ожидая сделать все за четыре часа. В результате все вылилось в неделю кодирования :(.
Так как в фронтэнд я пока не углублялся и javascript пользуюсь по мере необходимости, я не придал значения коду асинхронной работы с плагином.
Асинхронный код из SDK
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. КриптоПро меня спас, я закосячил в асинхронном коде. Юольшое спасибо службе поддержки.

Вот в целом все. Надеюсь кому то сберегу время и здоровье, т.к. судя по форуму КриптоПро масса людей страдает из за той же проблемы.
Tags:
Hubs:
-4
Comments3

Articles

Change theme settings