/////////////////////////////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2023, ООО 1С-Софт // Все права защищены. Эта программа и сопроводительные материалы предоставляются // в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0) // Текст лицензии доступен по ссылке: // https://creativecommons.org/licenses/by/4.0/legalcode /////////////////////////////////////////////////////////////////////////////////////////////////////// #Область СлужебныйПрограммныйИнтерфейс //////////////////////////////////////////////////////////////////////////////// // Обработчики событий подсистем конфигурации. // Параметры: // ФормаОтчета - ФормаКлиентскогоПриложения: // * ОтчетТабличныйДокумент - ТабличныйДокумент // Команда - КомандаФормы // Результат - Булево // Процедура ПриОбработкеКоманды(ФормаОтчета, Команда, Результат) Экспорт Если ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.ПродлениеСрокаДействияЭлектронныхПодписей" Тогда ПараметрыФормы = Новый Структура("РежимПродления", ФормаОтчета.КлючТекущегоВарианта); ОткрытьФорму("ОбщаяФорма.ПродлениеСрокаДействияЭлектронныхПодписей", ПараметрыФормы, ФормаОтчета, ФормаОтчета.КлючУникальности); КонецЕсли; КонецПроцедуры // Выполняет получение установленных криптопровайдеров. // // Параметры: // Оповещение - ОписаниеОповещения - оповещение о результате выполнения, один из типов: // = Неопределено - данные не получены (не установлено расширение для работы с криптографией или компонента) // = Структура: // # ПроверкаВыполнена = Булево - Истина, если проверка выполнена, получены установленные криптопровайдеры. // если Ложь, то будет заполнена Ошибка. // # Ошибка = Строка - текст ошибки // # Криптопровайдеры = Массив из ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеРасширенноеОписаниеПрограммы // # КриптопровайдерыНаСервере = Массив из ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеРасширенноеОписаниеПрограммы // ПараметрыПроверки - Неопределено // - Структура: // * УстанавливатьРасширение - Булево - устанавливать расширение для работы с электронной подписью. // * УстанавливатьКомпоненту - Булево - устанавливать компоненту для работы с электронной подписью. // * ПроверятьНаСервере - Булево - получить список криптопровайдеров на сервере. // Процедура ПолучитьУстановленныеКриптопровайдеры(Оповещение, ПараметрыПроверки = Неопределено) Экспорт Контекст = Новый Структура; Контекст.Вставить("УстанавливатьРасширение", Истина); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("Результат", РезультатПолученияУстановленныхКриптопровайдеров()); ПроверятьНаСервере = Неопределено; Если ТипЗнч(ПараметрыПроверки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Контекст, ПараметрыПроверки); ПроверятьНаСервере = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыПроверки, "ПроверятьНаСервере", Неопределено); КонецЕсли; Если ПроверятьНаСервере = Неопределено Тогда ПроверятьНаСервере = ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() Или ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере(); КонецЕсли; Если ПроверятьНаСервере Тогда РезультатНаСервере = ЭлектроннаяПодписьСлужебныйВызовСервера.УстановленныеКриптопровайдеры(); Если РезультатНаСервере.ПроверкаВыполнена Тогда Контекст.Результат.КриптопровайдерыНаСервере = РезультатНаСервере.Криптопровайдеры; КонецЕсли; КонецЕсли; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ПродолжатьБезУстановкиРасширения", Истина); ОповещениеОПродолжении = Новый ОписаниеОповещения("ПолучитьУстановленныеКриптопровайдерыПослеПодключенияКомпоненты", ЭтотОбъект, Контекст); ВыполнитьПослеПроверкиРасширенияИКомпоненты(ОповещениеОПродолжении, Контекст); КонецПроцедуры // Получает из сертификата адреса списков отзыва, скачивает, устанавливает в промежуточное хранилище сертификатов // // Параметры: // ПараметрыУстановкиСпискаОтзыва - см. ПараметрыУстановкиСпискаОтзыва // Процедура УстановитьСписокОтзываСертификата(ПараметрыУстановкиСпискаОтзыва) Экспорт Оповещение = Новый ОписаниеОповещения("УстановитьСписокОтзываСертификатаПослеПодключенияКомпоненты", ЭтотОбъект, ПараметрыУстановкиСпискаОтзыва); Параметры = Новый Структура; Если ЗначениеЗаполнено(ПараметрыУстановкиСпискаОтзыва.ТекстПояснения) Тогда Параметры.Вставить("ТекстПояснения", ПараметрыУстановкиСпискаОтзыва.ТекстПояснения); КонецЕсли; ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение, Параметры); КонецПроцедуры // Параметры установки списка отзыва. // // Параметры: // Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище. // - Строка - строковое представление сертификата в формате Base64. // - СертификатКриптографии // // Возвращаемое значение: // Структура: // * Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище. // - Строка - строковое представление сертификата в формате Base64. // - СертификатКриптографии // * Адреса - Строка - адрес списка отзыва, если не указан, загрузка будет с адресов, указанных в сертификате. // - Массив из Строка // * АдресВнутренний - Строка - если указан, список отзыва будет записан в кэш. // * ОповещениеОЗавершении - Неопределено // - ОписаниеОповещения - оповещение, которое вызывается после установки c результатом: // # Структура: // ## УстановкаВыполнена - Булево // ## Сообщение - сообщение о результате установки // * Форма - ФормаКлиентскогоПриложения - владелец формы установки // * ТекстПояснения - Строка - текст пояснения для установки компоненты. // Функция ПараметрыУстановкиСпискаОтзыва(Сертификат) Экспорт ПараметрыУстановкиСпискаОтзыва = Новый Структура; ПараметрыУстановкиСпискаОтзыва.Вставить("Сертификат", Сертификат); ПараметрыУстановкиСпискаОтзыва.Вставить("Адреса", Новый Массив); ПараметрыУстановкиСпискаОтзыва.Вставить("АдресВнутренний"); ПараметрыУстановкиСпискаОтзыва.Вставить("ОповещениеОЗавершении"); ПараметрыУстановкиСпискаОтзыва.Вставить("Форма"); ПараметрыУстановкиСпискаОтзыва.Вставить("ТекстПояснения"); Возврат ПараметрыУстановкиСпискаОтзыва; КонецФункции // Установить сертификат // // Параметры: // ПараметрыУстановкиСертификата - см. ПараметрыУстановкиСертификата // Процедура УстановитьСертификат(ПараметрыУстановкиСертификата) Экспорт Оповещение = Новый ОписаниеОповещения("УстановитьСертификатПослеПодключенияКомпоненты", ЭтотОбъект, ПараметрыУстановкиСертификата); ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение); КонецПроцедуры // Получить корневой сертификат из данных сертификата и установить его. // // Параметры: // ПараметрыУстановкиСертификата - см. ПараметрыУстановкиСертификата // - Структура: // * Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище // - Строка - строковое представление сертификата в формате Base64 // - СертификатКриптографии // * Хранилище - Структура: // ** Значение - Строка // ** Представление - Строка // Процедура УстановитьКорневойСертификат(ПараметрыУстановкиСертификата) Экспорт ПараметрыУстановки = ПараметрыУстановкиСертификата(ПараметрыУстановкиСертификата.Сертификат); ЗаполнитьЗначенияСвойств(ПараметрыУстановки, ПараметрыУстановкиСертификата); Оповещение = Новый ОписаниеОповещения("УстановитьКорневойСертификатПослеПодключенияКомпоненты", ЭтотОбъект, ПараметрыУстановки); ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение); КонецПроцедуры // Параметры установки сертификата. // // Параметры: // Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище // - Строка - строковое представление сертификата в формате Base64 // - СертификатКриптографии // // Возвращаемое значение: // Структура: // * Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище // - Строка - строковое представление сертификата в формате Base64 // - СертификатКриптографии // * ОповещениеОЗавершении - ОписаниеОповещения - оповещение, которое вызывается после установки. // Результат оповещения - Структура: // # УстановкаВыполнена - результат установки // # Сообщение - ошибка или сообщение о результате установки // * ВариантыУстановки - СписокЗначений - для выбора в форме установки // * Хранилище - Строка - имя хранилища // - Структура: // ** Значение - имя хранилища // ** Представление - представление в форме установки // * СвойстваКонтейнера - Структура: // ** Имя - Строка - имя контейнера // ** ТипПрограммы - Число - тип программы криптопровайдера // ** ИмяПрограммы - Строка - имя программы криптопровайдера // ** ПутьКПрограмме - Строка - имя программы криптопровайдера // * ТекстПредупреждения - Строка - для отображения в форме установки // * Форма - ФормаКлиентскогоПриложения - владелец формы установки // Функция ПараметрыУстановкиСертификата(Сертификат) Экспорт ПараметрыУстановкиСертификата = Новый Структура; ПараметрыУстановкиСертификата.Вставить("Сертификат", Сертификат); ПараметрыУстановкиСертификата.Вставить("ОповещениеОЗавершении", Неопределено); ПараметрыУстановкиСертификата.Вставить("ВариантыУстановки", Неопределено); ПараметрыУстановкиСертификата.Вставить("Хранилище", Неопределено); ПараметрыУстановкиСертификата.Вставить("СвойстваКонтейнера", Неопределено); ПараметрыУстановкиСертификата.Вставить("ТекстПредупреждения", ""); ПараметрыУстановкиСертификата.Вставить("Форма", Неопределено); Возврат ПараметрыУстановкиСертификата; КонецФункции // Открывает окно ошибки. // // Параметры: // ЗаголовокФормы - Строка - заголовок формы // ЗаголовокОшибки - Строка - заголовок ошибки // ОшибкаНаКлиенте - Структура: // * Ошибки - Массив // ОшибкаНаСервере - Структура // ДополнительныеПараметры - Неопределено, Структура: // * Сертификат // ОбработкаПродолжения - ОписаниеОповещения - обработка продолжения // Процедура ПоказатьОшибкуОбращенияКПрограмме(ЗаголовокФормы, ЗаголовокОшибки, ОшибкаНаКлиенте, ОшибкаНаСервере, ДополнительныеПараметры = Неопределено, ОбработкаПродолжения = Неопределено) Экспорт Если ТипЗнч(ОшибкаНаКлиенте) <> Тип("Структура") Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для процедуры %1 |указан некорректный тип параметра %2.'"), "ПоказатьОшибкуОбращенияКПрограмме", "ОшибкаНаКлиенте"); КонецЕсли; Если ТипЗнч(ОшибкаНаСервере) <> Тип("Структура") Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для процедуры %1 |указан некорректный тип параметра %2.'"), "ПоказатьОшибкуОбращенияКПрограмме", "ОшибкаНаСервере"); КонецЕсли; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПоказатьИнструкцию", Ложь); ПараметрыФормы.Вставить("ПоказатьПереходКНастройкеПрограмм", Ложь); ПараметрыФормы.Вставить("ПоказатьУстановкуРасширения", Ложь); ДополнительныеДанные = Новый Структура; ДополнительныеДанные.Вставить("НеподписанныеДанные"); ДополнительныеДанные.Вставить("Сертификат"); ДополнительныеДанные.Вставить("Подпись"); ДополнительныеДанные.Вставить("ДополнительныеДанныеПроверокНаКлиенте"); ДополнительныеДанные.Вставить("ДополнительныеДанныеПроверокНаСервере"); Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ПараметрыФормы, ДополнительныеПараметры); ЗаполнитьЗначенияСвойств(ДополнительныеДанные, ДополнительныеПараметры); КонецЕсли; ПараметрыФормы.Вставить("ДополнительныеДанные", ДополнительныеДанные); ПараметрыФормы.Вставить("ЗаголовокФормы", ЗаголовокФормы); ПараметрыФормы.Вставить("ЗаголовокОшибки", ЗаголовокОшибки); ПараметрыФормы.Вставить("ОшибкаНаКлиенте", ОшибкаНаКлиенте); ПараметрыФормы.Вставить("ОшибкаНаСервере", ОшибкаНаСервере); Контекст = Новый Структура; Контекст.Вставить("ПараметрыФормы", ПараметрыФормы); Контекст.Вставить("ОбработкаПродолжения", ОбработкаПродолжения); НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "ПоказатьОшибкуОбращенияКПрограммеПослеПодключенияРасширения", ЭтотОбъект, Контекст)); КонецПроцедуры // Открывает форму выбора сертификата. // // Параметры: // СерверныеПараметры - Структура: // * Организация - ОпределяемыйТип.Организация // * ФизическоеЛицо - ОпределяемыйТип.ФизическоеЛицо // * СертификатОснование - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования // * ДляШифрованияИРасшифровки - Булево, Неопределено // * ДобавлениеВСписок - Булево // * ЛичныйСписокПриДобавлении - Булево // * Организация - ОпределяемыйТип.Организация // ВладелецНовойФормы - Неопределено, Форма - владелец формы // ОбработчикЗавершения - Неопределено, ОписаниеОповещения // Процедура ВыборСертификатаДляПодписанияИлиРасшифровки(СерверныеПараметры, ВладелецНовойФормы = Неопределено, ОбработчикЗавершения = Неопределено) Экспорт Если ВладелецНовойФормы = Неопределено Тогда ВладелецНовойФормы = Новый УникальныйИдентификатор; КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("СерверныеПараметры", СерверныеПараметры); Контекст.Вставить("ВладелецНовойФормы", ВладелецНовойФормы); Контекст.Вставить("ОбработчикЗавершения", ОбработчикЗавершения); Если ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() И СерверныеПараметры.Свойство("ВыполнятьНаСервере") И СерверныеПараметры.ВыполнятьНаСервере = Истина Тогда Результат = Новый Структура; Результат.Вставить("СвойстваСертификатовНаКлиенте", Новый Массив); Результат.Вставить("ОшибкаПолученияСертификатовНаКлиенте", Новый Структура); ВыборСертификатаДляПодписанияИлиРасшифровкиПродолжение(Результат, Контекст); Иначе ПолучитьСвойстваСертификатовНаКлиенте(Новый ОписаниеОповещения( "ВыборСертификатаДляПодписанияИлиРасшифровкиПродолжение", ЭтотОбъект, Контекст), Истина, Ложь); КонецЕсли; КонецПроцедуры // См. ЭлектроннаяПодпись.СвойстваСертификата Асинх Функция СвойстваСертификата(Сертификат) Экспорт Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда ДвоичныеДанныеСертификата = Ждать Сертификат.ВыгрузитьАсинх(); ИначеЕсли ТипЗнч(Сертификат) = Тип("ФиксированнаяСтруктура") Тогда ДвоичныеДанныеСертификата = Сертификат.Сертификат; Иначе ДвоичныеДанныеСертификата = Неопределено; КонецЕсли; Возврат ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваСертификата(Сертификат, ДобавкаВремени(), ДвоичныеДанныеСертификата); КонецФункции #КонецОбласти #Область СлужебныеПроцедурыИФункции Функция ИспользуетсяИнтерактивныйРежимКриптографии(МенеджерКриптографии) Экспорт Если МенеджерКриптографии.ИспользованиеИнтерактивногоРежима = ИспользованиеИнтерактивногоРежимаКриптографииИспользовать() Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // В ОС Linux и MacOS при создании менеджера криптографии // требуется указывать путь к программе. // // Возвращаемое значение: // Булево // Функция ТребуетсяПутьКПрограмме() Экспорт Возврат ОбщегоНазначенияКлиент.ЭтоLinuxКлиент() Или ОбщегоНазначенияКлиент.ЭтоMacOSКлиент(); КонецФункции Процедура ПолучитьПутьКПрограмме(ОбработкаЗавершения, ПрограммаСсылка) Экспорт Результат = Новый Структура("ПутьКПрограмме, Существует", "", Ложь); Если Не ТребуетсяПутьКПрограмме() Тогда ВыполнитьОбработкуОповещения(ОбработкаЗавершения, Результат); Возврат; КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("ОбработкаЗавершения", ОбработкаЗавершения); Контекст.Вставить("ПрограммаСсылка", ПрограммаСсылка); ПроверенныеПутиКМодулямПрограмм = ПроверенныеПутиКМодулямПрограмм(); ОписаниеПути = ПроверенныеПутиКМодулямПрограмм.Получить(ПрограммаСсылка); Если ОписаниеПути <> Неопределено Тогда ПолучитьПутьКПрограммеЗавершение(ОписаниеПути, Контекст); Возврат; КонецЕсли; Контекст.Вставить("ПроверенныеПутиКМодулямПрограмм", ПроверенныеПутиКМодулямПрограмм); ПерсональныеНастройки = ЭлектроннаяПодписьКлиент.ПерсональныеНастройки(); ПутьКПрограмме = ПерсональныеНастройки.ПутиКПрограммамЭлектроннойПодписиИШифрования.Получить( ПрограммаСсылка); Если ЗначениеЗаполнено(ПутьКПрограмме) Тогда Контекст.Вставить("Результат", Результат); Результат.ПутьКПрограмме = ПутьКПрограмме; ПроверитьПутьКПрограмме(Новый ОписаниеОповещения( "ПолучитьПутьКПрограммеПослеПроверкиПути", ЭтотОбъект, Контекст), ПутьКПрограмме); Иначе ПолучитьПутьКПрограммеПоУмолчанию(Новый ОписаниеОповещения( "ПолучитьПутьКПрограммеЗавершение", ЭтотОбъект, Контекст), ПрограммаСсылка); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПолучитьПутьКПрограмме. Процедура ПолучитьПутьКПрограммеПослеПроверкиПути(Существует, Контекст) Экспорт Контекст.Результат.Существует = Существует; ПолучитьПутьКПрограммеЗавершение(Контекст.Результат, Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьПутьКПрограмме. Процедура ПолучитьПутьКПрограммеЗавершение(ОписаниеПути, Контекст) Экспорт Если Контекст.Свойство("ПроверенныеПутиКМодулямПрограмм") Тогда Контекст.ПроверенныеПутиКМодулямПрограмм.Вставить(Контекст.ПрограммаСсылка, ОписаниеПути); КонецЕсли; Результат = Новый Структура("ПутьКПрограмме, Существует", ОписаниеПути.ПутьКПрограмме, ОписаниеПути.Существует <> Ложь); ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Результат); КонецПроцедуры Функция ПроверенныеПутиКМодулямПрограмм() ОбщиеНастройки = ЭлектроннаяПодписьКлиент.ОбщиеНастройки(); ИмяПараметра = "СтандартныеПодсистемы.ЭлектроннаяПодпись.ОписаниеПутейКМодулямПрограмм"; ОписаниеПутейКМодулямПрограмм = ПараметрыПриложения.Получить(ИмяПараметра); Если ОписаниеПутейКМодулямПрограмм = Неопределено Или ОписаниеПутейКМодулямПрограмм.ВерсияНастроек <> ОбщиеНастройки.ВерсияНастроек Тогда ОписаниеПутейКМодулямПрограмм = Новый Структура("ПутиКМодулямПрограмм, ВерсияНастроек", Новый Соответствие, ОбщиеНастройки.ВерсияНастроек); ПараметрыПриложения.Вставить(ИмяПараметра, ОписаниеПутейКМодулямПрограмм); КонецЕсли; Возврат ОписаниеПутейКМодулямПрограмм.ПутиКМодулямПрограмм; КонецФункции Процедура ПроверитьПутьКПрограмме(ОбработкаЗавершения, ПутьКПрограмме) Контекст = Новый Структура; Контекст.Вставить("ОбработкаЗавершения", ОбработкаЗавершения); Контекст.Вставить("ПутьКПрограмме", ПутьКПрограмме); ФайловаяСистемаКлиент.ПодключитьРасширениеДляРаботыСФайлами(Новый ОписаниеОповещения( "ПроверитьПутьКПрограммеПослеПодключенияРасширенияРаботыСФайлами", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ПроверитьПутьКПрограмме. Процедура ПроверитьПутьКПрограммеПослеПодключенияРасширенияРаботыСФайлами(РасширениеПодключено, Контекст) Экспорт Если Не РасширениеПодключено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Неопределено); Возврат; КонецЕсли; Контекст.Вставить("ПутиКМодулям", СтрРазделить(Контекст.ПутьКПрограмме, ":", Ложь)); Контекст.Вставить("Индекс", -1); ПроверитьПутьКПрограммеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ПроверитьПутьКПрограмме. // // Параметры: // Контекст - Структура // Процедура ПроверитьПутьКПрограммеЦиклНачало(Контекст) Если Контекст.ПутиКМодулям.Количество() <= Контекст.Индекс + 1 Тогда // После цикла. ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Ложь); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; Файл = Новый Файл; Файл.НачатьИнициализацию(Новый ОписаниеОповещения( "ПроверитьПутьКПрограммеЦиклПослеИнициализацииФайла", ЭтотОбъект, Контекст), Контекст.ПутиКМодулям[Контекст.Индекс]); КонецПроцедуры // Продолжение процедуры ПроверитьПутьКПрограмме. Процедура ПроверитьПутьКПрограммеЦиклПослеИнициализацииФайла(Файл, Контекст) Экспорт Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения( "ПроверитьПутьКПрограммеЦиклПослеПроверкиСуществованияФайла", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ПроверитьПутьКПрограмме. Процедура ПроверитьПутьКПрограммеЦиклПослеПроверкиСуществованияФайла(Существует, Контекст) Экспорт Если Существует Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Истина); Возврат; КонецЕсли; ПроверитьПутьКПрограммеЦиклНачало(Контекст); КонецПроцедуры Процедура ПолучитьПутьКПрограммеПоУмолчанию(ОбработкаЗавершения, ПрограммаСсылка) Экспорт Результат = Новый Структура("ПутьКПрограмме, Существует", "", Ложь); Если Не ТребуетсяПутьКПрограмме() Тогда ВыполнитьОбработкуОповещения(ОбработкаЗавершения, Результат); Возврат; КонецЕсли; ОбщиеНастройки = ЭлектроннаяПодписьКлиент.ОбщиеНастройки(); Если ТипЗнч(ПрограммаСсылка) = Тип("Строка") Тогда ИдентификаторПрограммы = ПрограммаСсылка; Иначе ОписаниеПрограммы = ОбщиеНастройки.ОписанияПрограммПоСсылке.Получить(ПрограммаСсылка); // см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы Если ОписаниеПрограммы = Неопределено Тогда ВыполнитьОбработкуОповещения(ОбработкаЗавершения, Результат); Возврат; КонецЕсли; ИдентификаторПрограммы = ОписаниеПрограммы.Идентификатор; КонецЕсли; ПутиНайдены = Ложь; Для Каждого ПутиКМодулямПрограмм Из ОбщиеНастройки.ПоставляемыеПутиКМодулямПрограмм Цикл Если СтрНачинаетсяС(ИдентификаторПрограммы, ПутиКМодулямПрограмм.Ключ) Тогда ПутиНайдены = Истина; Прервать; КонецЕсли; КонецЦикла; Если Не ПутиНайдены Тогда ВыполнитьОбработкуОповещения(ОбработкаЗавершения, Результат); Возврат; КонецЕсли; ПутиКМодулямПрограммы = ПутиКМодулямПрограмм.Значение.Получить( ОбщегоНазначенияКлиентСервер.ИмяТипаПлатформы()); Если ПутиКМодулямПрограммы = Неопределено Тогда ВыполнитьОбработкуОповещения(ОбработкаЗавершения, Результат); Возврат; КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("ОбработкаЗавершения", ОбработкаЗавершения); Контекст.Вставить("ПутиКМодулямПрограммы", ПутиКМодулямПрограммы); Контекст.Вставить("Индекс", -1); ПолучитьПутьКПрограммеПоУмолчаниюЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьПутьКПрограммеПоУмолчанию. Процедура ПолучитьПутьКПрограммеПоУмолчаниюЦиклНачало(Контекст) Если Контекст.ПутиКМодулямПрограммы.Количество() <= Контекст.Индекс + 1 Тогда // После цикла. ПолучитьПутьКПрограммеПоУмолчаниюЦиклЗавершение(Контекст, Ложь); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; ПроверитьПутьКПрограмме(Новый ОписаниеОповещения( "ПолучитьПутьКПрограммеПоУмолчаниюЦиклПослеПроверкиПути", ЭтотОбъект, Контекст), Контекст.ПутиКМодулямПрограммы.Получить(Контекст.Индекс)) КонецПроцедуры // Продолжение процедуры ПолучитьПутьКПрограммеПоУмолчанию. Процедура ПолучитьПутьКПрограммеПоУмолчаниюЦиклПослеПроверкиПути(Существует, Контекст) Экспорт Если Существует <> Ложь Тогда ПолучитьПутьКПрограммеПоУмолчаниюЦиклЗавершение(Контекст, Существует); Возврат; КонецЕсли; ПолучитьПутьКПрограммеПоУмолчаниюЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьПутьКПрограммеПоУмолчанию. Процедура ПолучитьПутьКПрограммеПоУмолчаниюЦиклЗавершение(Контекст, Существует) ТекущийПуть = Контекст.ПутиКМодулямПрограммы.Получить( ?(Существует <> Истина, 0, Контекст.Индекс)); Результат = Новый Структура("ПутьКПрограмме, Существует", ТекущийПуть, Существует); ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Результат); КонецПроцедуры // Продолжение процедуры НайтиДействительныеЛичныеСертификаты. Процедура НайтиДействительныеЛичныеСертификаты(Оповещение, Отбор = Неопределено) Экспорт ПараметрыОповещения = Новый Структура; ПараметрыОповещения.Вставить("ОповещениеОЗавершении", Оповещение); Если Отбор = Неопределено Тогда Отбор = Новый Структура; КонецЕсли; Если Не Отбор.Свойство("ПроверятьСрокДействия") Тогда Отбор.Вставить("ПроверятьСрокДействия", Истина); КонецЕсли; Если Не Отбор.Свойство("ТолькоСертификатыСЗаполненнойПрограммой") Тогда Отбор.Вставить("ТолькоСертификатыСЗаполненнойПрограммой", Истина); КонецЕсли; Если Не Отбор.Свойство("ВключатьСертификатыСПустымПользователем") Тогда Отбор.Вставить("ВключатьСертификатыСПустымПользователем", Истина); КонецЕсли; Если Не Отбор.Свойство("Организация") Тогда Отбор.Вставить("Организация", Неопределено); КонецЕсли; ПараметрыОповещения.Вставить("Отбор", Отбор); Оповещение = Новый ОписаниеОповещения("НайтиДействительныеЛичныеСертификатыПослеПолученияПодписейНаКлиенте", ЭтотОбъект, ПараметрыОповещения); ПолучитьСвойстваСертификатовНаКлиенте(Оповещение, Не Отбор.ПроверятьСрокДействия, Истина); КонецПроцедуры // Продолжение процедуры НайтиДействительныеЛичныеСертификаты. Процедура НайтиДействительныеЛичныеСертификатыПослеПолученияПодписейНаКлиенте(Результат, ДополнительныеПараметры) Экспорт ЛичныеСертификаты = ЭлектроннаяПодписьСлужебныйВызовСервера.ЛичныеСертификаты(Результат.СвойстваСертификатовНаКлиенте, ДополнительныеПараметры.Отбор); ВыполнитьОбработкуОповещения(ДополнительныеПараметры.ОповещениеОЗавершении, ЛичныеСертификаты); КонецПроцедуры // Продолжение процедуры ПроверитьУстановкуПрограммКриптографии. Процедура ПроверитьУстановкуПрограммКриптографии(Форма, ПараметрыПроверки = Неопределено, ОповещениеОЗавершении = Неопределено) Экспорт Контекст = Новый Структура; Контекст.Вставить("Форма", Форма); Контекст.Вставить("ЭтоПовторнаяПроверка", Ложь); Контекст.Вставить("ПредлагатьУстановитьПрограмму", Неопределено); Контекст.Вставить("ПроверяемыеПрограммы", Неопределено); Контекст.Вставить("РасширенноеОписание", Ложь); Контекст.Вставить("Оповещение", ОповещениеОЗавершении); ПараметрыПолучения = Новый Структура; ПараметрыПолучения.Вставить("УстанавливатьКомпоненту", Истина); ПараметрыПолучения.Вставить("УстанавливатьРасширение", Истина); ПараметрыПолучения.Вставить("ПроверятьНаСервере", Неопределено); Если ТипЗнч(ПараметрыПроверки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Контекст, ПараметрыПроверки); ЗаполнитьЗначенияСвойств(ПараметрыПолучения, ПараметрыПроверки); КонецЕсли; Если Контекст.ПредлагатьУстановитьПрограмму = Неопределено Тогда Контекст.ПредлагатьУстановитьПрограмму = Контекст.ПроверяемыеПрограммы = Истина И Не ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() И Не ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() И Не ИспользоватьСервисОблачнойПодписи() И Не ИспользоватьЭлектроннуюПодписьВМоделиСервиса(); КонецЕсли; Контекст.Вставить("АлгоритмыПодписи", Новый Массив); Контекст.Вставить("ТипДанных", Неопределено); Если Контекст.ПроверяемыеПрограммы <> Неопределено Тогда Если Контекст.ПроверяемыеПрограммы = Истина Тогда Контекст.ПроверяемыеПрограммы = Неопределено; Контекст.АлгоритмыПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АктуальныеАлгоритмыПрограмм(); Контекст.ТипДанных = "Сертификат"; ИначеЕсли ТипЗнч(Контекст.ПроверяемыеПрограммы) = Тип("ДвоичныеДанные") Или ТипЗнч(Контекст.ПроверяемыеПрограммы) = Тип("Строка") Тогда ДвоичныеДанные = ЭлектроннаяПодписьСлужебныйКлиентСервер.ДвоичныеДанныеИзДанных( Контекст.ПроверяемыеПрограммы, "ЭлектроннаяПодписьСлужебныйКлиент.ПроверитьУстановкуПрограммКриптографии"); Контекст.ПроверяемыеПрограммы = Неопределено; Контекст.ТипДанных = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОпределитьТипДанных(ДвоичныеДанные); Если Контекст.ТипДанных = "Сертификат" Тогда АлгоритмПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмПодписиСертификата(ДвоичныеДанные); ИначеЕсли Контекст.ТипДанных = "Подпись" Тогда АлгоритмПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмСформированнойПодписи(ДвоичныеДанные); Иначе ВызватьИсключение НСтр("ru = 'Данные для поиска программы криптографии не являются сертификатом или подписью.'"); КонецЕсли; Контекст.АлгоритмыПодписи.Добавить(АлгоритмПодписи); КонецЕсли; КонецЕсли; ПолучитьУстановленныеКриптопровайдеры( Новый ОписаниеОповещения("ПроверитьУстановкуПрограммКриптографииПослеПолученияУстановленных", ЭтотОбъект, Контекст), ПараметрыПолучения); КонецПроцедуры // Продолжение процедуры НайтиУстановленныеПрограммы. Процедура НайтиУстановленныеПрограммы(Оповещение, ОписаниеПрограмм, ПроверятьНаСервере) Экспорт Программы = ЭлектроннаяПодписьСлужебныйВызовСервера.НайтиУстановленныеПрограммы( ОписаниеПрограмм, ПроверятьНаСервере); Контекст = КонтекстПоискаУстановленныхПрограмм(); Контекст.Индекс = -1; Контекст.Программы = Программы; Контекст.ОповещениеОЗавершении = Оповещение; Оповещение = Новый ОписаниеОповещения("НайтиУстановленныеПрограммыПослеПодключенияРасширения", ЭтотОбъект, Контекст); ЭлектроннаяПодписьКлиент.УстановитьРасширение(Истина, Оповещение); КонецПроцедуры // Продолжение процедуры НайтиУстановленныеПрограммы. Процедура НайтиУстановленныеПрограммыПослеПодключенияРасширения(Подключено, Контекст) Экспорт НайтиУстановленныеПрограммыЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры НайтиУстановленныеПрограммы. Процедура НайтиУстановленныеПрограммыЦиклНачало(Контекст) Если Контекст.Программы.Количество() <= Контекст.Индекс + 1 Тогда НайтиУстановленныеПрограммыПослеЦикла(Контекст); Возврат; КонецЕсли; Контекст = Контекст; // см. КонтекстПоискаУстановленныхПрограмм Контекст.Индекс = Контекст.Индекс + 1; ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.Программа = Контекст.Программы.Получить(Контекст.Индекс); ПараметрыСоздания.ПоказатьОшибку = Неопределено; Оповещение = Новый ОписаниеОповещения("НайтиУстановленныеПрограммыЦиклПродолжение", ЭтотОбъект, Контекст); СоздатьМенеджерКриптографии(Оповещение, "", ПараметрыСоздания); КонецПроцедуры // Продолжение процедуры НайтиУстановленныеПрограммы. Процедура НайтиУстановленныеПрограммыЦиклПродолжение(Результат, Контекст) Экспорт Контекст = Контекст; // см. КонтекстПоискаУстановленныхПрограмм ОписаниеПрограммы = Контекст.Программы.Получить(Контекст.Индекс); Если ТипЗнч(Результат) = Тип("МенеджерКриптографии") Тогда ОписаниеПрограммы.РезультатПроверкиНаКлиенте = ""; ОписаниеПрограммы.Установлена = Истина; Иначе ОписаниеПрограммы.РезультатПроверкиНаКлиенте = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиПоискаПрограммы( НСтр("ru = 'Не установлена на компьютере.'"), Результат); КонецЕсли; НайтиУстановленныеПрограммыЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры НайтиУстановленныеПрограммы. Процедура НайтиУстановленныеПрограммыПослеЦикла(Контекст) Для Каждого Программа Из Контекст.Программы Цикл Программа.Удалить("Идентификатор"); КонецЦикла; ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Контекст.Программы); КонецПроцедуры // Открывает форму просмотра данных сертификата. // // Параметры: // ДанныеСертификата - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования - ссылка на сертификат. // - СертификатКриптографии - имеющийся сертификат. // - ДвоичныеДанные - двоичные данные сертификата. // - Строка - адрес временного хранилища содержащий ДвоичныеДанные сертификата. // - Строка - отпечаток сертификата для поиска во всех хранилищах. // // ОткрытьДанные - Булево - открыть данные сертификата, а не форму элемента справочника. // Если передана не ссылка на элемент справочника и элемент справочника // не удалось найти по отпечатку, тогда будут открыты данные сертификата. // Процедура ОткрытьСертификат(ДанныеСертификата, ОткрытьДанные = Ложь) Экспорт Контекст = КонтекстОткрытияСертификата(); Контекст.ДанныеСертификата = ДанныеСертификата; Контекст.ОткрытьДанные = ОткрытьДанные; Контекст.АдресСертификата = Неопределено; Если ТипЗнч(ДанныеСертификата) = Тип("СертификатКриптографии") Тогда ДанныеСертификата.НачатьВыгрузку(Новый ОписаниеОповещения( "ОткрытьСертификатПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); Иначе ОткрытьСертификатПродолжение(Контекст); КонецЕсли; КонецПроцедуры // Возвращаемое значение: // Структура: // * АдресСертификата - Строка // * ОткрытьДанные - см. ОткрытьСертификат.ОткрытьДанные // * ДанныеСертификата - см. ОткрытьСертификат.ДанныеСертификата // Контекст открытия сертификата. // // Возвращаемое значение: // Структура - контекст открытия сертификата: // * ДанныеСертификата - см. ОткрытьСертификат.ДанныеСертификата // * ОткрытьДанные - см. ОткрытьСертификат.ОткрытьДанные // * АдресСертификата - Строка // * Ссылка - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования // * Отпечаток - Строка // * ОшибкаНаКлиенте - Структура // Функция КонтекстОткрытияСертификата() Контекст = Новый Структура; Контекст.Вставить("ДанныеСертификата"); Контекст.Вставить("ОткрытьДанные"); Контекст.Вставить("АдресСертификата"); Контекст.Вставить("Ссылка"); Контекст.Вставить("Отпечаток"); Контекст.Вставить("ОшибкаНаКлиенте", Новый Структура); Возврат Контекст; КонецФункции // Продолжение процедуры ОткрытьСертификат. Процедура ОткрытьСертификатПослеВыгрузкиСертификата(ВыгруженныеДанные, Контекст) Экспорт Контекст.АдресСертификата = ПоместитьВоВременноеХранилище(ВыгруженныеДанные); ОткрытьСертификатПродолжение(Контекст); КонецПроцедуры // Продолжение процедуры ОткрытьСертификат. Процедура ОткрытьСертификатПродолжение(Контекст) Если Контекст.АдресСертификата <> Неопределено Тогда // Сертификат подготовлен. ИначеЕсли ТипЗнч(Контекст.ДанныеСертификата) = Тип("СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования") Тогда Ссылка = Контекст.ДанныеСертификата; ИначеЕсли ТипЗнч(Контекст.ДанныеСертификата) = Тип("ДвоичныеДанные") Тогда Контекст.АдресСертификата = ПоместитьВоВременноеХранилище(Контекст.ДанныеСертификата); ИначеЕсли ТипЗнч(Контекст.ДанныеСертификата) <> Тип("Строка") Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Ошибка при вызове процедуры %1 общего модуля %2: |Некорректное значение параметра %3 ""%4"".'"), "ОткрытьСертификат", "ЭлектроннаяПодписьКлиент", "ДанныеСертификата", Строка(Контекст.ДанныеСертификата)); ИначеЕсли ЭтоАдресВременногоХранилища(Контекст.ДанныеСертификата) Тогда Контекст.АдресСертификата = Контекст.ДанныеСертификата; Иначе Отпечаток = Строка(Контекст.ДанныеСертификата); // Строка КонецЕсли; Если Не Контекст.ОткрытьДанные Тогда Если Ссылка = Неопределено Тогда Ссылка = ЭлектроннаяПодписьСлужебныйВызовСервера.СсылкаНаСертификат(Отпечаток, Контекст.АдресСертификата); КонецЕсли; Если ЗначениеЗаполнено(Ссылка) Тогда ПоказатьЗначение(, Ссылка); Возврат; КонецЕсли; КонецЕсли; Контекст.Ссылка = Ссылка; Контекст.Отпечаток = Отпечаток; Если Контекст.АдресСертификата = Неопределено И Ссылка = Неопределено Тогда ПолучитьСертификатПоОтпечатку(Новый ОписаниеОповещения( "ОткрытьСертификатПослеПоискаСертификата", ЭтотОбъект, Контекст), Отпечаток, Ложь, Неопределено); Иначе ОткрытьСертификатЗавершение(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ОткрытьСертификат. Процедура ОткрытьСертификатПослеПоискаСертификата(Результат, Контекст) Экспорт Если ТипЗнч(Результат) = Тип("СертификатКриптографии") Тогда Результат.НачатьВыгрузку(Новый ОписаниеОповещения( "ОткрытьСертификатПослеВыгрузкиНайденногоСертификата", ЭтотОбъект, Контекст)); Иначе Контекст.ОшибкаНаКлиенте = Результат; ОткрытьСертификатЗавершение(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ОткрытьСертификат. Процедура ОткрытьСертификатПослеВыгрузкиНайденногоСертификата(ВыгруженныеДанные, Контекст) Экспорт Контекст.АдресСертификата = ПоместитьВоВременноеХранилище(ВыгруженныеДанные); ОткрытьСертификатЗавершение(Контекст); КонецПроцедуры // Продолжение процедуры ОткрытьСертификат. Процедура ОткрытьСертификатЗавершение(Контекст) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Ссылка"); ПараметрыФормы.Вставить("АдресСертификата"); ПараметрыФормы.Вставить("Отпечаток"); ПараметрыФормы.Вставить("ОшибкаНаКлиенте"); ЗаполнитьЗначенияСвойств(ПараметрыФормы, Контекст); ОткрытьФорму("ОбщаяФорма.Сертификат", ПараметрыФормы); КонецПроцедуры // Сохраняет сертификат в файл. // // Параметры: // Оповещение - ОписаниеОповещения - вызывается после сохранения. // - Неопределено - продолжение не требуется. // // Сертификат - СертификатКриптографии - сертификат. // - ДвоичныеДанные - двоичные данные сертификата. // - Строка - адрес временного хранилища, содержащего двоичные данные сертификата. // Процедура СохранитьСертификат(Оповещение, Сертификат, ИмяФайлаБезРасширения = "") Экспорт Контекст = КонтекстСохраненияСертификата(); Контекст.Оповещение = Оповещение; Контекст.Сертификат = Сертификат; Контекст.ИмяФайлаБезРасширения = ИмяФайлаБезРасширения; Контекст.АдресСертификата = Неопределено; Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда Сертификат.НачатьВыгрузку(Новый ОписаниеОповещения( "СохранитьСертификатПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); Иначе СохранитьСертификатПродолжение(Контекст); КонецЕсли; КонецПроцедуры // Возвращаемое значение: // Структура: // * АдресСертификата - Строка // * ИмяФайлаБезРасширения - Строка // * Сертификат - см. СохранитьСертификат.Сертификат // * Оповещение - см. СохранитьСертификат.Оповещение // Функция КонтекстСохраненияСертификата() Контекст = Новый Структура; Контекст.Вставить("Оповещение"); Контекст.Вставить("Сертификат"); Контекст.Вставить("ИмяФайлаБезРасширения"); Контекст.Вставить("АдресСертификата"); Возврат Контекст; КонецФункции // Продолжение процедуры СохранитьСертификат. Процедура СохранитьСертификатПослеВыгрузкиСертификата(ВыгруженныеДанные, Контекст) Экспорт Контекст.АдресСертификата = ПоместитьВоВременноеХранилище(ВыгруженныеДанные, Новый УникальныйИдентификатор); Контекст.Вставить("УдалитьСертификатИзВременногоХранилища", Истина); СохранитьСертификатПродолжение(Контекст); КонецПроцедуры // Продолжение процедуры СохранитьСертификат. Процедура СохранитьСертификатПродолжение(Контекст) Если Контекст.АдресСертификата <> Неопределено Тогда // Сертификат подготовлен. ИначеЕсли ТипЗнч(Контекст.Сертификат) = Тип("ДвоичныеДанные") Тогда Контекст.АдресСертификата = ПоместитьВоВременноеХранилище(Контекст.Сертификат, Новый УникальныйИдентификатор); Контекст.Вставить("УдалитьСертификатИзВременногоХранилища", Истина); ИначеЕсли ТипЗнч(Контекст.Сертификат) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.Сертификат) Тогда Контекст.АдресСертификата = Контекст.Сертификат; Иначе Если Контекст.Оповещение <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Ложь); КонецЕсли; Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(Контекст.ИмяФайлаБезРасширения) Тогда Контекст.ИмяФайлаБезРасширения = ЭлектроннаяПодписьСлужебныйВызовСервера.ПредставлениеСубъекта(Контекст.АдресСертификата); КонецЕсли; ИмяФайла = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПодготовитьСтрокуДляИмениФайла( Контекст.ИмяФайлаБезРасширения) + ".cer"; Оповещение = Новый ОписаниеОповещения("СохранитьСертификатПослеПолученияФайлов", ЭтотОбъект, Контекст); ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла(); ПараметрыСохранения.Диалог.Заголовок = НСтр("ru = 'Выберите файл для сохранения сертификата'"); ПараметрыСохранения.Диалог.Фильтр = НСтр("ru = 'Файлы сертификатов (*.cer)|*.cer'")+ "|" + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Все файлы (%1)|%1'"), ПолучитьМаскуВсеФайлы()); ФайловаяСистемаКлиент.СохранитьФайл(Оповещение, Контекст.АдресСертификата, ИмяФайла, ПараметрыСохранения); КонецПроцедуры // Продолжение процедуры СохранитьСертификат. // // Параметры: // ПолученныеФайлы - Массив из ОписаниеПереданногоФайла // Контекст - Структура // Процедура СохранитьСертификатПослеПолученияФайлов(ПолученныеФайлы, Контекст) Экспорт Если ПолученныеФайлы = Неопределено Или ПолученныеФайлы.Количество() = 0 Тогда ЕстьПолученныеФайлы = Ложь; Иначе ЕстьПолученныеФайлы = Истина; ПоказатьОповещениеПользователя(НСтр("ru = 'Сертификат сохранен в файл:'"),, ПолученныеФайлы[0].Имя); КонецЕсли; Если Контекст.Свойство("УдалитьСертификатИзВременногоХранилища") Тогда УдалитьИзВременногоХранилища(Контекст.АдресСертификата); КонецЕсли; Если Контекст.Оповещение <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, ЕстьПолученныеФайлы); КонецЕсли; КонецПроцедуры // Сохраняет подпись на компьютер. Процедура СохранитьПодпись(АдресПодписи) Экспорт Оповещение = Новый ОписаниеОповещения("СохранитьПодписьПослеПолученияФайла", ЭтотОбъект, Неопределено); Фильтр = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Файлы электронных подписей (*.%1)|*.%1'"), ЭлектроннаяПодписьКлиент.ПерсональныеНастройки().РасширениеДляФайловПодписи); Фильтр = Фильтр + "|" + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Все файлы (%1)|%1'"), ПолучитьМаскуВсеФайлы()); ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла(); ПараметрыСохранения.Диалог.Фильтр = Фильтр; ПараметрыСохранения.Диалог.Заголовок = НСтр("ru = 'Выберите файл для сохранения подписи'"); ФайловаяСистемаКлиент.СохранитьФайл(Оповещение, АдресПодписи, "", ПараметрыСохранения); КонецПроцедуры // Продолжение процедуры СохранитьПодпись. // // Параметры: // ПолученныеФайлы - Массив из ОписаниеПереданногоФайла // Контекст - Структура // Процедура СохранитьПодписьПослеПолученияФайла(ПолученныеФайлы, Контекст) Экспорт Если ПолученныеФайлы = Неопределено Или ПолученныеФайлы.Количество() = 0 Тогда Возврат; КонецЕсли; ПоказатьОповещениеПользователя(НСтр("ru = 'Электронная подпись сохранена в файл:'"),, ПолученныеФайлы[0].Имя); КонецПроцедуры // Параметры записи сертификата. // // Возвращаемое значение: // Структура - параметры оповещения при записи сертификата и изменении статуса заявления: // * ЭтоНовый - Булево - добавление сертификата в справочник. // * Установлен - Булево - сертификат установлен в личное хранилище. // * Отозван - Булево - сертификат помечен как отозванный. // Функция ПараметрыОповещенияПриЗаписиСертификата() Экспорт ПараметрыОповещенияПриЗаписиСертификата = Новый Структура; ПараметрыОповещенияПриЗаписиСертификата.Вставить("ЭтоНовый", Ложь); ПараметрыОповещенияПриЗаписиСертификата.Вставить("Установлен", Ложь); ПараметрыОповещенияПриЗаписиСертификата.Вставить("Отозван", Ложь); Возврат ПараметрыОповещенияПриЗаписиСертификата; КонецФункции // Находит сертификат на компьютере по строке отпечатка. // // Параметры: // Оповещение - ОписаниеОповещения - оповещение о результате выполнения следующих типов: // = СертификатКриптографии - найденный сертификат. // = Неопределено - сертификат не существует в хранилище. // = Строка - текст ошибки создания менеджера криптографии (или другая ошибка). // = Структура - описание ошибки в виде структуры. // // Отпечаток - Строка - Base64 кодированный отпечаток сертификата. // ТолькоВЛичномХранилище - Булево - если Истина, тогда искать в личном хранилище, иначе везде. // - ТипХранилищаСертификатовКриптографии - указанный тип хранилища. // // ПоказатьОшибку - Булево - показать ошибку создания менеджера криптографии. // - Неопределено - не показывать ошибку и вернуть структуру ошибки, // в том числе добавить свойство СертификатНеНайден. // // Программа - Неопределено - искать с помощью любой программы. // - СправочникСсылка.ПрограммыЭлектроннойПодписиИШифрования - искать // с помощью указанной программы. // - МенеджерКриптографии - инициализированный менеджер криптографии, // который нужно использовать для поиска. // Процедура ПолучитьСертификатПоОтпечатку(Оповещение, Отпечаток, ТолькоВЛичномХранилище, ПоказатьОшибку = Истина, Программа = Неопределено) Экспорт Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("Отпечаток", Отпечаток); Контекст.Вставить("ТолькоВЛичномХранилище", ТолькоВЛичномХранилище); Контекст.Вставить("ПоказатьОшибку", ПоказатьОшибку); Если ТипЗнч(Программа) = Тип("МенеджерКриптографии") Тогда ПолучитьСертификатПоОтпечаткуПослеСозданияМенеджераКриптографии(Программа, Контекст); Иначе ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = ПоказатьОшибку; ПараметрыСоздания.Программа = Программа; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПолучитьСертификатПоОтпечаткуПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПолучениеСертификатов", ПараметрыСоздания); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); Возврат; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", Результат); ТипХранилища = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТипХранилищаДляПоискаСертификата( Контекст.ТолькоВЛичномХранилище); Попытка Контекст.Вставить("ДвоичныеДанныеОтпечатка", Base64Значение(Контекст.Отпечаток)); Исключение Если Контекст.ПоказатьОшибку = Истина Тогда ВызватьИсключение; КонецЕсли; ИнформацияОбОшибке = ИнформацияОбОшибке(); ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); ПолучитьСертификатПоОтпечаткуЗавершение(Неопределено, ПредставлениеОшибки, Контекст); Возврат; КонецПопытки; Контекст.МенеджерКриптографии.НачатьПолучениеХранилищаСертификатов( Новый ОписаниеОповещения( "ПолучитьСертификатПоОтпечаткуПослеПолученияХранилища", ЭтотОбъект, Контекст, "ПолучитьСертификатПоОтпечаткуПослеОшибкиПолученияХранилища", ЭтотОбъект), ТипХранилища); КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуПослеОшибкиПолученияХранилища(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт Если Контекст.ПоказатьОшибку = Истина Тогда Возврат; КонецЕсли; СтандартнаяОбработка = Ложь; ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); ПолучитьСертификатПоОтпечаткуЗавершение(Неопределено, ПредставлениеОшибки, Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуПослеПолученияХранилища(ХранилищеСертификатовКриптографии, Контекст) Экспорт ХранилищеСертификатовКриптографии.НачатьПоискПоОтпечатку(Новый ОписаниеОповещения( "ПолучитьСертификатПоОтпечаткуПослеПоиска", ЭтотОбъект, Контекст, "ПолучитьСертификатПоОтпечаткуПослеОшибкиПоиска", ЭтотОбъект), Контекст.ДвоичныеДанныеОтпечатка); КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуПослеОшибкиПоиска(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт Если Контекст.ПоказатьОшибку = Истина Тогда Возврат; КонецЕсли; СтандартнаяОбработка = Ложь; ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); ПолучитьСертификатПоОтпечаткуЗавершение(Неопределено, ПредставлениеОшибки, Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуПослеПоиска(Сертификат, Контекст) Экспорт ПолучитьСертификатПоОтпечаткуЗавершение(Сертификат, "", Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьСертификатПоОтпечатку. Процедура ПолучитьСертификатПоОтпечаткуЗавершение(Сертификат, ПредставлениеОшибки, Контекст) Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Сертификат); Возврат; КонецЕсли; Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Сертификат не установлен на компьютере по причине: |%1'"), ПредставлениеОшибки); Иначе ТекстОшибки = НСтр("ru = 'Сертификат не установлен на компьютере.'"); КонецЕсли; Если Контекст.ПоказатьОшибку = Неопределено Тогда Результат = Новый Структура; Результат.Вставить("ОписаниеОшибки", ТекстОшибки); Если Не ЗначениеЗаполнено(ПредставлениеОшибки) Тогда Результат.Вставить("СертификатНеНайден"); КонецЕсли; ИначеЕсли Не ЗначениеЗаполнено(ПредставлениеОшибки) Тогда Результат = Неопределено; Иначе Результат = ПредставлениеОшибки; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры // Получает отпечатки сертификатов пользователя ОС на компьютере. // // Параметры: // Оповещение - ОписаниеОповещения - вызывается для передачи возвращаемого значения одного из типов: // = Соответствие - Ключ - отпечаток в формате строки Base64, а Значение - Истина, // = Строка - текст ошибки создания менеджера криптографии (или другая ошибка). // // ТолькоЛичные - Булево - если Ложь, то к личным сертификатам добавляются сертификаты получателей. // // ПоказатьОшибку - Булево - показать ошибку создания менеджера криптографии. // Процедура ПолучитьОтпечаткиСертификатов(Оповещение, ТолькоЛичные, ПоказатьОшибку = Истина) Экспорт Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ТолькоЛичные", ТолькоЛичные); Контекст.Вставить("ПоказатьОшибку", ПоказатьОшибку = Истина); ПолучитьСвойстваСертификатовНаКлиенте(Новый ОписаниеОповещения( "ПолучитьОтпечаткиСертификатовПослеВыполнения", ЭтотОбъект, Контекст), ТолькоЛичные, Ложь, Истина, ПоказатьОшибку); КонецПроцедуры // Продолжение процедуры ПолучитьОтпечаткиСертификатов. Процедура ПолучитьОтпечаткиСертификатовПослеВыполнения(Результат, Контекст) Экспорт Если ЗначениеЗаполнено(Результат.ОшибкаПолученияСертификатовНаКлиенте) Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат.ОшибкаПолученияСертификатовНаКлиенте); Возврат; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат.СвойстваСертификатовНаКлиенте); КонецПроцедуры // Только для внутреннего использования. Функция ДобавкаВремени() Экспорт Возврат ОбщегоНазначенияКлиент.ДатаСеанса() - ОбщегоНазначенияКлиент.ДатаУниверсальная(); КонецФункции // Продолжение процедуры ЭлектроннаяПодписьКлиент.ПроверитьПодпись // // Параметры: // Оповещение - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.Оповещение // ИсходныеДанные - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.ИсходныеДанные // Подпись - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.Подпись // МенеджерКриптографии - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.МенеджерКриптографии // НаДату - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.НаДату // ПараметрыПроверки - см. ЭлектроннаяПодписьКлиент.ПроверитьПодпись.ПараметрыПроверки // Процедура ПроверитьПодпись(Оповещение, ИсходныеДанные, Подпись, МенеджерКриптографии = Неопределено, НаДату = Неопределено, ПараметрыПроверки = Неопределено) Экспорт ПараметрыДляПроверки = ЭлектроннаяПодписьКлиент.ПараметрыПроверкиПодписи(); Если ПараметрыПроверки = Неопределено Тогда ПараметрыДляПроверки.ПоказатьОшибкуСозданияМенеджераКриптографии = Истина; ИначеЕсли ТипЗнч(ПараметрыПроверки) = Тип("Булево") Тогда ПараметрыДляПроверки.ПоказатьОшибкуСозданияМенеджераКриптографии = ПараметрыПроверки; ИначеЕсли ТипЗнч(ПараметрыПроверки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ПараметрыДляПроверки, ПараметрыПроверки); КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ИсходныеДанные", ИсходныеДанные); Контекст.Вставить("Подпись", Подпись); Контекст.Вставить("АдресПодписи", ""); Контекст.Вставить("НаДату", НаДату); Контекст.Вставить("ПроверятьНаСервере", ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере()); Если ПараметрыДляПроверки.РезультатВВидеСтруктуры Тогда Контекст.Вставить("РезультатПроверки", ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи()); Иначе Контекст.Вставить("РезультатПроверки", Неопределено); КонецЕсли; Если ТипЗнч(Контекст.Подпись) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.Подпись) Тогда Контекст.АдресПодписи = Контекст.Подпись; Контекст.Подпись = ПолучитьИзВременногоХранилища(Подпись); КонецЕсли; Если Не ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() И ТипЗнч(Контекст.ИсходныеДанные) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.ИсходныеДанные) Тогда Контекст.ИсходныеДанные = ПолучитьИзВременногоХранилища(Контекст.ИсходныеДанные); КонецЕсли; Если ТипЗнч(Контекст.ИсходныеДанные) = Тип("Структура") И Контекст.ИсходныеДанные.Свойство("ПараметрыXMLDSig") Тогда // ЭтоXMLDSig. Если Не Контекст.ИсходныеДанные.Свойство("КонвертXML") Тогда Контекст.ИсходныеДанные = Новый Структура(Новый ФиксированнаяСтруктура(Контекст.ИсходныеДанные)); Контекст.ИсходныеДанные.Вставить("КонвертXML", Контекст.ИсходныеДанные.КонвертSOAP); КонецЕсли; СвойстваКонвертаXML = ЭлектроннаяПодписьСлужебныйВызовСервера.СвойстваКонвертаXML( Контекст.ИсходныеДанные.КонвертXML, Контекст.ИсходныеДанные.ПараметрыXMLDSig, Истина); Контекст.Вставить("СвойстваКонвертаXML", СвойстваКонвертаXML); Если СвойстваКонвертаXML = Неопределено Тогда ДанныеСертификата = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатИзКонвертаSOAP( Контекст.ИсходныеДанные.КонвертXML, Ложь); ИначеЕсли ЗначениеЗаполнено(СвойстваКонвертаXML.ТекстОшибки) Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи(СвойстваКонвертаXML.ТекстОшибки, Контекст.РезультатПроверки)); Возврат; Иначе ДанныеСертификата = Base64Значение(СвойстваКонвертаXML.Сертификат.ЗначениеСертификата); КонецЕсли; Контекст.Вставить("АлгоритмПодписи", ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмПодписиСертификата(ДанныеСертификата)); ИначеЕсли ТипЗнч(Контекст.Подпись) = Тип("ДвоичныеДанные") Тогда Контекст.Вставить("АлгоритмПодписи", ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмСформированнойПодписи(Контекст.Подпись)); Иначе Контекст.Вставить("АлгоритмПодписи", ""); КонецЕсли; Если МенеджерКриптографии = Неопределено Тогда ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = ПараметрыДляПроверки.ПоказатьОшибкуСозданияМенеджераКриптографии И Не Контекст.ПроверятьНаСервере И Не ИспользоватьЭлектроннуюПодписьВМоделиСервиса() И Не ПроверятьСертификатыОблачнойПодписью(); ПараметрыСоздания.АлгоритмПодписи = Контекст.АлгоритмПодписи; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПроверитьПодписьПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПроверкаПодписи", ПараметрыСоздания); Иначе ПроверитьПодписьПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если Результат = "СервисКриптографии" Тогда ПроверитьПодписьВМоделиСервиса(Контекст); Возврат; ИначеЕсли Результат = "ОблачнаяПодпись" Тогда ПроверитьПодписьОблачнаяПодпись(Контекст); Возврат; ИначеЕсли ТипЗнч(Результат) = Тип("МенеджерКриптографии") Тогда МенеджерКриптографии = Результат; Иначе МенеджерКриптографии = Неопределено; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Если Не ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() Тогда // Проверка подписи и сертификата на стороне клиента. Если МенеджерКриптографии = Неопределено Тогда Если ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда ПроверитьПодписьВМоделиСервиса(Контекст); ИначеЕсли ПроверятьСертификатыОблачнойПодписью() Тогда ПроверитьПодписьОблачнаяПодпись(Контекст); Иначе ПроверитьПодписьДобавитьСвойстваПодписиВРезультат(Контекст.Подпись, Неопределено, Контекст); КонецЕсли; Возврат; КонецЕсли; Контекст.Вставить("ПроверитьСертификатНаКлиенте"); ПроверитьПодписьНаКлиенте(Контекст); Возврат; КонецЕсли; Если МенеджерКриптографии <> Неопределено И Не ( ТипЗнч(Контекст.ИсходныеДанные) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.ИсходныеДанные)) Тогда // Математическая проверка подписи на стороне клиента для повышения производительности и // безопасности в случае, когда ИсходныеДанные являются результатом расшифровки секретного файла. // Сертификат проверяется и на сервере и на клиенте. ПроверитьПодписьНаКлиенте(Контекст); Возврат; КонецЕсли; Если ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда // Проверка подписи и сертификата в модели сервиса. ПроверитьПодписьВМоделиСервиса(Контекст); Иначе // Проверка подписи и сертификата на сервере. Если ТипЗнч(Контекст.ИсходныеДанные) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.ИсходныеДанные) Тогда АдресИсходныхДанных = Контекст.ИсходныеДанные; Иначе Если ТипЗнч(Контекст.ИсходныеДанные) = Тип("Структура") И Контекст.ИсходныеДанные.Свойство("ПараметрыCMS") Тогда Контекст.ИсходныеДанные.ПараметрыCMS.ВключениеСертификатовВПодпись = ВключениеСертификатовВПодписьСтрокой( Контекст.ИсходныеДанные.ПараметрыCMS.ВключениеСертификатовВПодпись); КонецЕсли; АдресИсходныхДанных = ПоместитьВоВременноеХранилище(Контекст.ИсходныеДанные); КонецЕсли; Если Не ЗначениеЗаполнено(Контекст.АдресПодписи) Тогда Контекст.АдресПодписи = ПоместитьВоВременноеХранилище(Контекст.Подпись); КонецЕсли; ОписаниеОшибки = ""; Результат = ЭлектроннаяПодписьСлужебныйВызовСервера.ПроверитьПодпись( АдресИсходныхДанных, Контекст.АдресПодписи, ОписаниеОшибки, Контекст.НаДату, Контекст.РезультатПроверки); Если Результат <> Истина Тогда Результат = ОписаниеОшибки; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи(Результат, Контекст.РезультатПроверки)); КонецЕсли; КонецПроцедуры Асинх Процедура ПроверитьПодписьДобавитьСвойстваПодписиВРезультат(Подпись, Результат, Контекст) ТребуетсяПроверка = Неопределено; Если ТипЗнч(Контекст.РезультатПроверки) = Тип("Структура") Тогда Если Результат = Неопределено Тогда Контекст.РезультатПроверки.ТребуетсяПроверка = Истина; ИначеЕсли ТипЗнч(Результат) = Тип("Строка") Тогда ОшибкаПоКлассификатору = ЭлектроннаяПодписьСлужебныйКлиентПовтИсп.ОшибкаПоКлассификатору(Результат); Если ОшибкаПоКлассификатору <> Неопределено Тогда ТребуетсяПроверка = ОшибкаПоКлассификатору.ТребуетПроверки; КонецЕсли; КонецЕсли; Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись И ТипЗнч( Контекст.МенеджерКриптографии) = Тип("МенеджерКриптографии") Тогда СвойстваПодписи = Ждать СвойстваПодписиЧтениеМенеджеромКриптографии(Подпись, Контекст.МенеджерКриптографии, Истина); Иначе СвойстваПодписи = Ждать СвойстваПодписиИзДвоичныхДанных(Подпись, Истина); КонецЕсли; ЗаполнитьЗначенияСвойств(Контекст.РезультатПроверки, СвойстваПодписи); КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи(Результат, Контекст.РезультатПроверки, ТребуетсяПроверка)); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиенте(Контекст) Контекст.Вставить("ДанныеПодписи", Контекст.Подпись); ЭтоXMLDSig = (ТипЗнч(Контекст) = Тип("Структура") И ТипЗнч(Контекст.ИсходныеДанные) = Тип("Структура") И Контекст.ИсходныеДанные.Свойство("ПараметрыXMLDSig")); ЭтоCMS = (ТипЗнч(Контекст) = Тип("Структура") И ТипЗнч(Контекст.ИсходныеДанные) = Тип("Структура") И Контекст.ИсходныеДанные.Свойство("ПараметрыCMS")); Если ЭтоXMLDSig Тогда ОповещениеУспех = Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеПроверкиПодписиXMLDSig", ЭтотОбъект, Контекст); ОповещениеОшибка = Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписиXMLDSig", ЭтотОбъект, Контекст); Оповещения = Новый Структура; Оповещения.Вставить("Успех", ОповещениеУспех); Оповещения.Вставить("Ошибка", ОповещениеОшибка); НачатьИнициализациюСертификатаКриптографииДляПроверкиПодписиXMLDSig(Оповещения, Контекст.ИсходныеДанные.КонвертXML, Контекст.ИсходныеДанные.ПараметрыXMLDSig, Контекст.СвойстваКонвертаXML, Контекст.МенеджерКриптографии); ИначеЕсли ЭтоCMS Тогда ОповещениеУспех = Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеПроверкиПодписиXMLDSig", ЭтотОбъект, Контекст); ОповещениеОшибка = Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписиXMLDSig", ЭтотОбъект, Контекст); Оповещения = Новый Структура; Оповещения.Вставить("Успех", ОповещениеУспех); Оповещения.Вставить("Ошибка", ОповещениеОшибка); НачатьИнициализациюСертификатаКриптографииДляПроверкиПодписиCMS( Оповещения, Контекст.ДанныеПодписи, Контекст.ИсходныеДанные.Данные, Контекст.ИсходныеДанные.ПараметрыCMS, Контекст.МенеджерКриптографии); Иначе МенеджерКриптографии = Контекст.МенеджерКриптографии; // МенеджерКриптографии МенеджерКриптографии.НачатьПроверкуПодписи(Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеПроверкиПодписи", ЭтотОбъект, Контекст, "ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи", ЭтотОбъект), Контекст.ИсходныеДанные, Контекст.ДанныеПодписи, Ложь); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписиXMLDSig(ТекстОшибки, Контекст) Экспорт ВыполнитьОбработкуОповещения(Контекст.Оповещение, ТекстОшибки); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеПослеПроверкиПодписиXMLDSig(Данные, Контекст) Экспорт Если Контекст.Свойство("ПроверитьСертификатНаКлиенте") Тогда МенеджерКриптографии = Контекст.МенеджерКриптографии; Иначе // Проверка сертификата на сервере и на клиенте. МенеджерКриптографии = Неопределено; КонецЕсли; ДополнительныеПараметры = ДополнительныеПараметрыПроверкиСертификата(); ДополнительныеПараметры.ДляПроверкиПодписи = Истина; Оповещение = Новый ОписаниеОповещения("ПроверитьПодписьПослеПроверкиСертификатаПодписи", ЭтотОбъект, Контекст); ПроверитьСертификат(Оповещение, Данные.Сертификат, МенеджерКриптографии, Данные.ДатаПодписания, ДополнительныеПараметры); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ТекстОшибки = ?(ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке), Строка(ИнформацияОбОшибке)); Если Контекст.Свойство("ДанныеПодписи") Тогда Подпись = Контекст.ДанныеПодписи; Иначе Подпись = Контекст.Подпись; КонецЕсли; ПроверитьПодписьДобавитьСвойстваПодписиВРезультат(Подпись, ТекстОшибки, Контекст) КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Асинх Процедура ПроверитьПодписьНаКлиентеПослеПроверкиПодписи(Сертификат, Контекст) Экспорт ОшибкаПроверкиПодписи = ""; Если ТипЗнч(Контекст.МенеджерКриптографии) = Тип("МенеджерКриптографии") Тогда СвойстваСертификата = Неопределено; Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись Тогда СвойстваПодписи = Ждать СвойстваПодписиЧтениеМенеджеромКриптографии(Контекст.ДанныеПодписи, Контекст.МенеджерКриптографии, Ложь); Если СвойстваПодписи.ТипПодписи <> ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.ОбычнаяCMS") И СвойстваПодписи.ТипПодписи <> ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.БазоваяCAdESBES") Тогда // Проверка дополнительных атрибутов. Попытка Ждать Контекст.МенеджерКриптографии.ПроверитьПодписьАсинх( Контекст.ИсходныеДанные, Контекст.ДанныеПодписи, Истина); Исключение ОшибкаПроверкиПодписи = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); КонецПопытки; КонецЕсли; Иначе СвойстваПодписи = Ждать СвойстваПодписиИзДвоичныхДанных(Контекст.ДанныеПодписи, Ложь); СвойстваСертификата = Ждать СвойстваСертификата(Сертификат); СвойстваПодписи.Отпечаток = СвойстваСертификата.Отпечаток; СвойстваПодписи.КомуВыданСертификат = СвойстваСертификата.КомуВыдан; КонецЕсли; Если ТипЗнч(Контекст.РезультатПроверки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Контекст.РезультатПроверки, СвойстваПодписи); Контекст.РезультатПроверки.Сертификат = Ждать Сертификат.ВыгрузитьАсинх(); КонецЕсли; Если Не ПустаяСтрока(ОшибкаПроверкиПодписи) Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи( ОшибкаПроверкиПодписи, Контекст.РезультатПроверки)); Возврат; КонецЕсли; Иначе // после проверки в облачных сервисах. СвойстваПодписи = Ждать СвойстваПодписиИзДвоичныхДанных(Контекст.ДанныеПодписи, Истина); Если СвойстваПодписи.Сертификат = Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи( НСтр("ru = 'Сертификат не существует в данных подписи.'"), Контекст.РезультатПроверки)); Возврат; КонецЕсли; Сертификат = СвойстваПодписи.Сертификат; Если ТипЗнч(Контекст.РезультатПроверки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Контекст.РезультатПроверки, СвойстваПодписи); Контекст.РезультатПроверки.Сертификат = Сертификат; КонецЕсли; КонецЕсли; Если Не Контекст.Свойство("ПроверитьСертификатНаКлиенте") Тогда // Проверка сертификата на сервере и на клиенте. Контекст.Вставить("МенеджерКриптографии", Неопределено); КонецЕсли; Контекст.Вставить("Сертификат", Сертификат); ДатаПодписания = ЭлектроннаяПодписьСлужебныйКлиентСервер.ДатаДляПроверкиСертификатаПодписи(СвойстваПодписи); Если Не ЗначениеЗаполнено(ДатаПодписания) Тогда ДатаПодписания = Контекст.НаДату; КонецЕсли; ДополнительныеПараметры = ДополнительныеПараметрыПроверкиСертификата(); ДополнительныеПараметры.ДляПроверкиПодписи = Истина; Оповещение = Новый ОписаниеОповещения("ПроверитьПодписьПослеПроверкиСертификатаПодписи", ЭтотОбъект, Контекст); ПроверитьСертификат(Оповещение, Контекст.Сертификат, Контекст.МенеджерКриптографии, ДатаПодписания, ДополнительныеПараметры); КонецПроцедуры Процедура ПроверитьПодписьПослеПроверкиСертификатаПодписи(РезультатПроверки, Контекст) Экспорт Если ТипЗнч(РезультатПроверки) = Тип("Структура") Тогда Результат = РезультатПроверки.ОбщееОписаниеОшибки; Если Контекст.РезультатПроверки <> Неопределено Тогда Если РезультатПроверки.СертификатОтозван Тогда Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиДляОтозванногоСертификатаПодписи( Контекст.РезультатПроверки); КонецЕсли; Контекст.РезультатПроверки.СертификатОтозван = РезультатПроверки.СертификатОтозван; Контекст.РезультатПроверки.ТребуетсяПроверка = РезультатПроверки.ТребуетсяПроверка; КонецЕсли; ИначеЕсли РезультатПроверки = Неопределено Тогда Результат = РезультатПроверки; Если Контекст.РезультатПроверки <> Неопределено Тогда Контекст.РезультатПроверки.ТребуетсяПроверка = Истина; КонецЕсли; Иначе Результат = РезультатПроверки; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверкиПодписи(Результат, Контекст.РезультатПроверки)); КонецПроцедуры // Проверяет действительность сертификата криптографии. // // Параметры: // Оповещение - ОписаниеОповещения - оповещение о результате выполнения следующих типов: // = Булево - Истина, если проверка выполнена успешно. // = Строка - описание ошибки проверки сертификата. // = Неопределено - не удалось получить менеджер криптографии (когда не указан). // = Структура - в случае ошибки, если ДополнительныеПараметры.ДляПроверкиПодписи И ДополнительныеПараметры.ОбъединитьОшибкиДанныхСертификата // # ОбщееОписаниеОшибки - Строка // # СертификатОтозван - Булево - ошибка связана с тем, что сертификат отозван в удостоверяющем центре. // # ТребуетсяПроверка - Булево - ошибка требует перепроверки подписи после дополнительных действий, // например, установки корневого сертификата. // = Структура - в случае ошибки, если ДополнительныеПараметры.ДляПроверкиПодписи И Не ДополнительныеПараметры.ОбъединитьОшибкиДанныхСертификата // # ОписаниеОшибкиНаКлиенте - Строка // # ОписаниеОшибкиНаСервере - Строка // # ДополнительныеДанныеПроверкиНаСервере - см. ЭлектроннаяПодписьСлужебныйКлиентСервер.ПредупреждениеПриПроверкеУдостоверяющегоЦентраСертификата // # ДополнительныеДанныеПроверкиНаКлиенте - см. ЭлектроннаяПодписьСлужебныйКлиентСервер.ПредупреждениеПриПроверкеУдостоверяющегоЦентраСертификата // # СертификатОтозван - Булево - см. выше. // # ТребуетсяПроверка - Булево - см. выше. // // Сертификат - СертификатКриптографии - сертификат. // - ДвоичныеДанные - двоичные данные сертификата. // - Строка - адрес временного хранилища, содержащего двоичные данные сертификата. // // МенеджерКриптографии - Неопределено - получить менеджер криптографии автоматически. // - МенеджерКриптографии - использовать указанный менеджер криптографии // (проверка на сервере не будет выполнена). // // НаДату - Дата - проверить сертификат на указанную дату. // Если параметр не указан или указана пустая дата, тогда проверять на текущую. // // ДополнительныеПараметры - см. ДополнительныеПараметрыПроверкиСертификата. // Процедура ПроверитьСертификат(Оповещение, Сертификат, МенеджерКриптографии = Неопределено, НаДату = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт Контекст = КонтекстПроверкиСертификата(); Контекст.Оповещение = Оповещение; Контекст.Сертификат = Сертификат; Контекст.МенеджерКриптографии = МенеджерКриптографии; Контекст.НаДату = НаДату; Если ДополнительныеПараметры <> Неопределено Тогда Контекст.ПоказатьОшибку = ДополнительныеПараметры.ПоказатьОшибку; Контекст.ОбъединитьОшибкиДанныхСертификата = ДополнительныеПараметры.ОбъединитьОшибкиДанныхСертификата; Контекст.ПроверитьВСервисеПослеОшибки = ДополнительныеПараметры.ПроверитьВСервисеПослеОшибки; Контекст.ВыполнятьПроверкуУдостоверяющегоЦентра = ДополнительныеПараметры.ВыполнятьПроверкуУдостоверяющегоЦентра; Контекст.ДляПроверкиПодписи = ДополнительныеПараметры.ДляПроверкиПодписи; КонецЕсли; Контекст.ОписаниеОшибкиНаКлиенте = Неопределено; Контекст.ОписаниеОшибкиНаСервере = Неопределено; Если Контекст.МенеджерКриптографии = Неопределено И ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() Тогда Контекст.ТребуетПроверкиНаСервере = Ложь; // Проверка на сервере перед проверкой на клиенте. Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда Сертификат.НачатьВыгрузку(Новый ОписаниеОповещения("ПроверитьСертификатПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); Иначе ПроверитьСертификатПослеВыгрузкиСертификата(Сертификат, Контекст); КонецЕсли; Иначе // Когда менеджер криптографии указан, тогда проверка выполняется только на клиенте. ПроверитьСертификатНаКлиенте(Контекст); КонецЕсли; КонецПроцедуры // Возвращаемое значение: // Структура: // * ОписаниеОшибкиНаСервере - Строка // * ОписаниеОшибкиНаКлиенте - Строка // * ТребуетПроверкиНаКлиенте - Неопределено, Булево // * ТребуетПроверкиНаСервере - Неопределено, Булево // * СертификатОтозван - Булево // * ПоказатьОшибку - см. ПроверитьСертификат.ПоказатьОшибку // * НаДату - см. ПроверитьСертификат.НаДату // * МенеджерКриптографии - см. ПроверитьСертификат.МенеджерКриптографии // * Сертификат - см. ПроверитьСертификат.Сертификат // * Оповещение - см. ПроверитьСертификат.Оповещение // * ОбъединитьОшибкиДанныхСертификата - Булево // * ПроверитьВСервисеПослеОшибки - Булево // Функция КонтекстПроверкиСертификата() Контекст = Новый Структура; Контекст.Вставить("Оповещение"); Контекст.Вставить("Сертификат"); Контекст.Вставить("СертификатОтозван", Ложь); Контекст.Вставить("МенеджерКриптографии"); Контекст.Вставить("НаДату"); Контекст.Вставить("ОписаниеОшибкиНаКлиенте"); Контекст.Вставить("ТребуетПроверкиНаКлиенте"); Контекст.Вставить("ДополнительныеДанныеПроверкиНаКлиенте"); Контекст.Вставить("ОписаниеОшибкиНаСервере"); Контекст.Вставить("ТребуетПроверкиНаСервере"); Контекст.Вставить("ДополнительныеДанныеПроверкиНаСервере"); Контекст.Вставить("ПоказатьОшибку", Истина); Контекст.Вставить("ОбъединитьОшибкиДанныхСертификата", Истина); Контекст.Вставить("ПроверитьВСервисеПослеОшибки", Истина); Контекст.Вставить("ВыполнятьПроверкуУдостоверяющегоЦентра", Истина); Контекст.Вставить("ДляПроверкиПодписи", Ложь); Контекст.Вставить("ДействияДляУстраненияОшибок", Новый Соответствие); Контекст.Вставить("СвойстваСертификата"); Возврат Контекст; КонецФункции // Дополнительные параметры проверки сертификата. // // Возвращаемое значение: // Структура - дополнительные параметры проверки сертификата: // * ПоказатьОшибку - Булево - показать ошибку создания менеджера криптографии (когда не указан). // * ОбъединитьОшибкиДанныхСертификата - Булево - объединить ошибки проверки данных сертификата на клиенте и сервере в // строку. // * ПроверитьВСервисеПослеОшибки - Булево - в случае ошибки при проверке данных сертификата на клиенте, проверить в сервисе. // * ВыполнятьПроверкуУдостоверяющегоЦентра - Булево - проверять юридическую значимость в зависимости от издателя. // * ДляПроверкиПодписи - Булево - не показывать оповещения для сертификатов, возвращать результат, // как указано в вызывающей процедуре проверки подписи. // Функция ДополнительныеПараметрыПроверкиСертификата() Экспорт Структура = Новый Структура; Структура.Вставить("ПоказатьОшибку", Истина); Структура.Вставить("ОбъединитьОшибкиДанныхСертификата", Истина); Структура.Вставить("ПроверитьВСервисеПослеОшибки", Истина); Структура.Вставить("ВыполнятьПроверкуУдостоверяющегоЦентра", Истина); Структура.Вставить("ДляПроверкиПодписи", Ложь); Возврат Структура; КонецФункции // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеВыгрузкиСертификата(Сертификат, Контекст) Экспорт // Проверка сертификата на сервере. Если ТипЗнч(Сертификат) = Тип("ДвоичныеДанные") Тогда АдресСертификата = ПоместитьВоВременноеХранилище(Сертификат); Иначе АдресСертификата = Сертификат; КонецЕсли; ДополнительныеПараметры = Новый Структура; ДополнительныеПараметры.Вставить("ВыполнятьПроверкуУдостоверяющегоЦентра", Контекст.ВыполнятьПроверкуУдостоверяющегоЦентра); ДополнительныеПараметры.Вставить("ДляПроверкиПодписи", Контекст.ДляПроверкиПодписи); ДополнительныеПараметры.Вставить("Предупреждение"); ДополнительныеПараметры.Вставить("Сертификат"); Если ЭлектроннаяПодписьСлужебныйВызовСервера.ПроверитьСертификат(АдресСертификата, Контекст.ОписаниеОшибкиНаСервере, Контекст.НаДату, ДополнительныеПараметры) Тогда Если ЗначениеЗаполнено(ДополнительныеПараметры.Предупреждение) И Не Контекст.ДляПроверкиПодписи И ДополнительныеПараметры.Сертификат <> Неопределено Тогда ПараметрыОткрытияФормы = Новый Структура("Сертификат, ДополнительныеДанныеПроверки", ДополнительныеПараметры.Сертификат, ДополнительныеПараметры.Предупреждение); ДействиеПриНажатии = Новый ОписаниеОповещения("ОткрытьФормуОповещенияОНеобходимостиЗаменыСертификата", ЭлектроннаяПодписьСлужебныйКлиент, ПараметрыОткрытияФормы); ПоказатьОповещениеПользователя( НСтр("ru = 'Необходима замена сертификата'"), ДействиеПриНажатии, ДополнительныеПараметры.Сертификат, БиблиотекаКартинок.Предупреждение32, СтатусОповещенияПользователя.Важное, ДополнительныеПараметры.Сертификат); КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина); Иначе ПроверитьСертификатНаКлиенте(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатНаКлиенте(Контекст) Контекст.ТребуетПроверкиНаКлиенте = Ложь; СертификатДляПроверки = Контекст.Сертификат; Если ТипЗнч(СертификатДляПроверки) = Тип("Строка") Тогда СертификатДляПроверки = ПолучитьИзВременногоХранилища(СертификатДляПроверки); КонецЕсли; Контекст.Вставить("СертификатДляПроверки", СертификатДляПроверки); Если ТипЗнч(СертификатДляПроверки) = Тип("ДвоичныеДанные") Тогда ЭлектроннаяПодписьКлиент.УстановитьРасширение(Ложь, Новый ОписаниеОповещения( "ПроверитьСертификатНаКлиентеПослеПодключенияРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст), НСтр("ru = 'Для продолжения установите расширение для работы с криптографией.'")); Иначе ПроверитьСертификатПослеИнициализацииСертификата(СертификатДляПроверки, Контекст) КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатНаКлиентеПослеПодключенияРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт Если Подключено = Истина Тогда СертификатКриптографии = Новый СертификатКриптографии; СертификатКриптографии.НачатьИнициализацию(Новый ОписаниеОповещения( "ПроверитьСертификатПослеИнициализацииСертификата", ЭтотОбъект, Контекст), Контекст.СертификатДляПроверки); Иначе ПроверитьСертификатНаКлиентеПослеОшибкиПроверки( НСтр("ru = 'Не установлено расширение для работы с криптографией.'"), Ложь, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеИнициализацииСертификата(СертификатКриптографии, Контекст) Экспорт Контекст.Вставить("СертификатКриптографии", СертификатКриптографии); Контекст.Вставить("РежимыПроверкиСертификата", ЭлектроннаяПодписьСлужебныйКлиентСервер.РежимыПроверкиСертификата( ЗначениеЗаполнено(Контекст.НаДату))); Если ТипЗнч(Контекст.СертификатДляПроверки) = Тип("СертификатКриптографии") Тогда Контекст.СертификатДляПроверки.НачатьВыгрузку(Новый ОписаниеОповещения( "ПроверитьСертификатПослеОпределенияАлгоритмаПодписания", ЭтотОбъект, Контекст)); Иначе ПроверитьСертификатПослеОпределенияАлгоритмаПодписания(Контекст.СертификатДляПроверки, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеОпределенияАлгоритмаПодписания(ДанныеСертификата, Контекст) Экспорт Контекст.Вставить("ДанныеСертификата", ДанныеСертификата); Контекст.Вставить("АлгоритмПодписи", ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмПодписиСертификата(ДанныеСертификата)); ПродолжитьПроверкуСертификатаНаКлиенте(Контекст); КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПродолжитьПроверкуСертификатаНаКлиенте(Контекст) Если Контекст.МенеджерКриптографии = Неопределено Тогда ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); Если Контекст.ПоказатьОшибку = Истина И Контекст.ОписаниеОшибкиНаСервере = Неопределено И Не ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда ПараметрыСоздания.ПоказатьОшибку = Истина; Иначе ПараметрыСоздания.ПоказатьОшибку = Неопределено; КонецЕсли; ПараметрыСоздания.АлгоритмПодписи = Контекст.АлгоритмПодписи; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПроверитьСертификатПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПроверкаСертификата", ПараметрыСоздания); Иначе Если Контекст.МенеджерКриптографии = "СервисКриптографии" Тогда ПроверитьСертификатВМоделиСервиса(Контекст); ИначеЕсли Контекст.МенеджерКриптографии = "ОблачнаяПодпись" Тогда ПроверитьСертификатОблачнаяПодпись(Контекст); Иначе ПроверитьСертификатПослеСозданияМенеджераКриптографии(Контекст.МенеджерКриптографии, Контекст); КонецЕсли; КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") Тогда Если ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда ПроверитьСертификатВМоделиСервиса(Контекст); ИначеЕсли ПроверятьСертификатыОблачнойПодписью() Тогда ПроверитьСертификатОблачнаяПодпись(Контекст); Иначе Если ТипЗнч(Результат) = Тип("Структура") Тогда Контекст.ОписаниеОшибкиНаКлиенте = Результат; КонецЕсли; ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); КонецЕсли; Возврат; КонецЕсли; Контекст.МенеджерКриптографии = Результат; Контекст.МенеджерКриптографии.НачатьПроверкуСертификата(Новый ОписаниеОповещения( "ПроверитьСертификатНаКлиентеПослеПроверки", ЭтотОбъект, Контекст, "ПроверитьСертификатНаКлиентеПослеОшибкиПроверки", ЭтотОбъект), Контекст.СертификатКриптографии, Контекст.РежимыПроверкиСертификата); КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатНаКлиентеПослеОшибкиПроверки(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда ОписаниеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); ОшибкаПоКлассификатору = ЭлектроннаяПодписьСлужебныйКлиентПовтИсп.ОшибкаПоКлассификатору(ОписаниеОшибки); // Локализация Если ОшибкаПоКлассификатору <> Неопределено И ЗначениеЗаполнено(ОшибкаПоКлассификатору.ДействияДляУстранения) Тогда Действие = Неопределено; Для Каждого ТекущееДействие Из ОшибкаПоКлассификатору.ДействияДляУстранения Цикл Если Контекст.ДействияДляУстраненияОшибок.Получить(ТекущееДействие) = Неопределено Тогда Действие = ТекущееДействие; Прервать; КонецЕсли; КонецЦикла; Если Действие <> Неопределено Тогда Контекст.ДействияДляУстраненияОшибок.Вставить(Действие, ОписаниеОшибки); Контекст.ДействияДляУстраненияОшибок.Вставить("ДействиеПриПовторнойПроверке", Действие); Если Действие = "УстановитьСписокОтзываСертификата" Тогда ИмяИздателя = НРег(ЭлектроннаяПодписьКлиент.СвойстваИздателяСертификата(Контекст.СертификатКриптографии).ОбщееИмя); Если ЗначениеЗаполнено(ИмяИздателя) Тогда ИмяИздателя = СтроковыеФункцииКлиент.СтрокаЛатиницей(ИмяИздателя); АдресСпискаОтзываВнутренний = ЭлектроннаяПодписьСлужебныйКлиентСервер.АдресСпискаОтзываВнутренний( ИмяИздателя, Контекст.ДанныеСертификата); Если ЗначениеЗаполнено(АдресСпискаОтзываВнутренний.АдресВнутренний) Тогда ПараметрыУстановкиСпискаОтзыва = ПараметрыУстановкиСпискаОтзыва( Контекст.СертификатКриптографии); ПараметрыУстановкиСпискаОтзыва.Адреса = АдресСпискаОтзываВнутренний.АдресВнешний; ПараметрыУстановкиСпискаОтзыва.АдресВнутренний = АдресСпискаОтзываВнутренний.АдресВнутренний; ПараметрыУстановкиСпискаОтзыва.ОповещениеОЗавершении = Новый ОписаниеОповещения("ПроверитьСертификатПовторно", ЭтотОбъект, Контекст); ПараметрыУстановкиСпискаОтзыва.ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для проверки сертификата требуется установка списка отзыва с помощью внешней компоненты %1.'"), "ExtraCryptoAPI"); УстановитьСписокОтзываСертификата(ПараметрыУстановкиСпискаОтзыва); Возврат; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Конец локализация Если ОшибкаПоКлассификатору <> Неопределено Тогда ОбработатьОшибкуПоКлассификатору(ОписаниеОшибки, Контекст.ТребуетПроверкиНаКлиенте, Контекст, ОшибкаПоКлассификатору); КонецЕсли; Иначе ОписаниеОшибки = Строка(ИнформацияОбОшибке); КонецЕсли; Контекст.ОписаниеОшибкиНаКлиенте = ОписаниеОшибки; Если Контекст.ПроверитьВСервисеПослеОшибки И ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда ПроверитьСертификатВМоделиСервиса(Контекст); ИначеЕсли Контекст.ПроверитьВСервисеПослеОшибки И ПроверятьСертификатыОблачнойПодписью() Тогда ПроверитьСертификатОблачнаяПодпись(Контекст, Ложь); Иначе ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПовторно(Результат, Контекст) Экспорт Если Контекст.ДействияДляУстраненияОшибок.Получить("ДействиеПриПовторнойПроверке") = "УстановитьСписокОтзываСертификата" Тогда Если Не Результат.УстановкаВыполнена Тогда ТекстПредыдущейОшибки = Контекст.ДействияДляУстраненияОшибок.Получить("УстановитьСписокОтзываСертификата"); ПроверитьСертификатНаКлиентеПослеОшибкиПроверки(ТекстПредыдущейОшибки, Ложь, Контекст); ТекстОшибкиУстановкиСпискаОтзыва = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить список отзыва при проверке сертификата: %1'"), Результат.Сообщение); ЖурналРегистрацииКлиент.ДобавитьСообщениеДляЖурналаРегистрации( НСтр("ru = 'Электронная подпись.Обновление списков отзыва'", ОбщегоНазначенияКлиент.КодОсновногоЯзыка()), "Предупреждение", ТекстОшибкиУстановкиСпискаОтзыва,, Истина); Возврат; КонецЕсли; КонецЕсли; Контекст.МенеджерКриптографии.НачатьПроверкуСертификата(Новый ОписаниеОповещения( "ПроверитьСертификатНаКлиентеПослеПроверки", ЭтотОбъект, Контекст, "ПроверитьСертификатНаКлиентеПослеОшибкиПроверки", ЭтотОбъект), Контекст.СертификатКриптографии, Контекст.РежимыПроверкиСертификата); КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Асинх Процедура ПроверитьСертификатНаКлиентеПослеПроверки(Контекст) Экспорт ОшибкаПросрочки = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатПросрочен( Контекст.СертификатКриптографии, Контекст.НаДату, ДобавкаВремени()); Если ЗначениеЗаполнено(ОшибкаПросрочки) Тогда ПроверитьСертификатНаКлиентеПослеОшибкиПроверки(ОшибкаПросрочки, Ложь, Контекст); Иначе Если Контекст.ДляПроверкиПодписи Тогда СвойстваСертификата = Ждать СвойстваСертификата(Контекст.СертификатКриптографии); Контекст.СвойстваСертификата = СвойстваСертификата; ОшибкаПросрочки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗакрытыйКлючПросрочен( СвойстваСертификата, Контекст.НаДату); Если ЗначениеЗаполнено(ОшибкаПросрочки) Тогда ПроверитьСертификатНаКлиентеПослеОшибкиПроверки(ОшибкаПросрочки, Ложь, Контекст); Возврат; КонецЕсли; КонецЕсли; ДополнительнаяПроверкаСертификата(Контекст.СертификатКриптографии, Ложь, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Асинх Процедура ДополнительнаяПроверкаСертификата(СертификатКриптографии, ПроверкаНаСервере, Контекст) Если Контекст.ВыполнятьПроверкуУдостоверяющегоЦентра Тогда РезультатПроверкиУдостоверяющегоЦентраСертификата = Ждать РезультатПроверкиУдостоверяющегоЦентраСертификата( СертификатКриптографии, Контекст.НаДату, Контекст.ДляПроверкиПодписи, Контекст.СвойстваСертификата); Если Не РезультатПроверкиУдостоверяющегоЦентраСертификата.Действует Или ЗначениеЗаполнено( РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение.ТекстОшибки) И Не Контекст.ДляПроверкиПодписи Тогда ПользовательскиеНастройкиСертификата = ЭлектроннаяПодписьСлужебныйВызовСервера.ПользовательскиеНастройкиСертификата( СертификатКриптографии.Отпечаток); Если Не РезультатПроверкиУдостоверяющегоЦентраСертификата.Действует И ПользовательскиеНастройкиСертификата.ПодписаниеРазрешено <> Истина Тогда Если ПроверкаНаСервере Тогда Контекст.ОписаниеОшибкиНаСервере = РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение.ТекстОшибки; Контекст.ДополнительныеДанныеПроверкиНаСервере = РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение; Иначе Контекст.ОписаниеОшибкиНаКлиенте = РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение.ТекстОшибки; Контекст.ДополнительныеДанныеПроверкиНаКлиенте = РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение; КонецЕсли; ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; Если ЗначениеЗаполнено(РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение.ТекстОшибки) И Не Контекст.ДляПроверкиПодписи Тогда СсылкаНаСертификат = ПользовательскиеНастройкиСертификата.СсылкаНаСертификат; Если Не ПользовательскиеНастройкиСертификата.Оповещен И СсылкаНаСертификат <> Неопределено Тогда ПараметрыОткрытияФормы = Новый Структура("Сертификат, ДополнительныеДанныеПроверки", СсылкаНаСертификат, РезультатПроверкиУдостоверяющегоЦентраСертификата.Предупреждение); ДействиеПриНажатии = Новый ОписаниеОповещения("ОткрытьФормуОповещенияОНеобходимостиЗаменыСертификата", ЭлектроннаяПодписьСлужебныйКлиент, ПараметрыОткрытияФормы); ПоказатьОповещениеПользователя( НСтр("ru = 'Необходима замена сертификата'"), ДействиеПриНажатии, СсылкаНаСертификат, БиблиотекаКартинок.Предупреждение32, СтатусОповещенияПользователя.Важное, СсылкаНаСертификат); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина); КонецПроцедуры Асинх Функция РезультатПроверкиУдостоверяющегоЦентраСертификата(СертификатКриптографии, НаДату = Неопределено, ЭтоПроверкаПодписи = Ложь, СвойстваСертификата = Неопределено) Экспорт Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатПроверкиУдостоверяющегоЦентраПоУмолчанию(); // Локализация Если Не ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаПроверкаПоСпискуУЦ Тогда Возврат Результат; КонецЕсли; МодульЭлектроннаяПодписьКлиентСерверЛокализация = ОбщегоНазначенияКлиент.ОбщийМодуль( "ЭлектроннаяПодписьКлиентСерверЛокализация"); ДанныеДляПроверкиУдостоверяющегоЦентра = МодульЭлектроннаяПодписьКлиентСерверЛокализация.ДанныеДляПроверкиУдостоверяющегоЦентра( СертификатКриптографии); Если ДанныеДляПроверкиУдостоверяющегоЦентра.ЗначенияПоиска = Неопределено Тогда Возврат Результат; КонецЕсли; ДанныеУдостоверяющегоЦентра = ЭлектроннаяПодписьСлужебныйКлиентПовтИсп.ДанныеУдостоверяющегоЦентра( ДанныеДляПроверкиУдостоверяющегоЦентра.ЗначенияПоиска); Если ДанныеУдостоверяющегоЦентра = Неопределено Тогда Возврат Результат; КонецЕсли; КонтекстПроверки = МодульЭлектроннаяПодписьКлиентСерверЛокализация.КонтекстПроверкиУдостоверяющегоЦентраСертификата(); КонтекстПроверки.ДанныеУдостоверяющегоЦентра = ДанныеУдостоверяющегоЦентра; КонтекстПроверки.НаименованиеУдостоверяющегоЦентра = ДанныеДляПроверкиУдостоверяющегоЦентра.НаименованиеУдостоверяющегоЦентра; КонтекстПроверки.ЗначенияПоиска = ДанныеДляПроверкиУдостоверяющегоЦентра.ЗначенияПоиска; КонтекстПроверки.НаДату = ?(НаДату = Неопределено, ОбщегоНазначенияКлиент.ДатаСеанса(), НаДату); КонтекстПроверки.ДобавкаВремени = ДобавкаВремени(); КонтекстПроверки.ЭтоПроверкаПодписи = ЭтоПроверкаПодписи; Если СвойстваСертификата = Неопределено Тогда КонтекстПроверки.СвойстваСертификата = Ждать СвойстваСертификата(СертификатКриптографии); Иначе КонтекстПроверки.СвойстваСертификата = СвойстваСертификата; КонецЕсли; Результат = МодульЭлектроннаяПодписьКлиентСерверЛокализация.РезультатПроверкиУдостоверяющегоЦентраСертификата( СертификатКриптографии, КонтекстПроверки); Если ЗначениеЗаполнено(Результат.Предупреждение.Причина) Тогда Результат.Предупреждение.Причина = СтроковыеФункцииКлиент.ФорматированнаяСтрока( Результат.Предупреждение.Причина); КонецЕсли; Если ЗначениеЗаполнено(Результат.Предупреждение.Решение) Тогда Результат.Предупреждение.Решение = СтроковыеФункцииКлиент.ФорматированнаяСтрока( Результат.Предупреждение.Решение); КонецЕсли; // Конец Локализация Возврат Результат; КонецФункции // Продолжение процедуры ПроверитьСертификат. // // Параметры: // Контекст - Структура: // * Сертификат - СертификатКриптографии // Процедура ПроверитьСертификатВМоделиСервиса(Контекст) Если ТипЗнч(Контекст.Сертификат) = Тип("СертификатКриптографии") Тогда Контекст.Сертификат.НачатьВыгрузку(Новый ОписаниеОповещения( "ПроверитьСертификатВМоделиСервисаПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); Иначе ПроверитьСертификатВМоделиСервисаПослеВыгрузкиСертификата(Контекст.Сертификат, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатВМоделиСервисаПослеВыгрузкиСертификата(Сертификат, Контекст) Экспорт Если ТипЗнч(Сертификат) = Тип("ДвоичныеДанные") Тогда ДанныеСертификата = Сертификат; Иначе ДанныеСертификата = ПолучитьИзВременногоХранилища(Сертификат); КонецЕсли; МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); ПараметрыПроверки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПараметрыПроверкиСертификатаВСервисе( ЭлектроннаяПодписьКлиент.ОбщиеНастройки(), Контекст.РежимыПроверкиСертификата); Если ПараметрыПроверки <> Неопределено Тогда // АПК:287-выкл - №640 - допустимо вызывать несуществующую процедуру БТС, // так как проверяется версия БТС 2.0.3, начиная с которой процедура существует. МодульСервисКриптографииКлиент.ПроверитьСертификатСПараметрами(Новый ОписаниеОповещения( "ПроверитьСертификатПослеПроверкиВМоделиСервиса", ЭтотОбъект, Контекст), ДанныеСертификата, ПараметрыПроверки); // АПК:287-вкл Иначе МодульСервисКриптографииКлиент.ПроверитьСертификат(Новый ОписаниеОповещения( "ПроверитьСертификатПослеПроверкиВМоделиСервиса", ЭтотОбъект, Контекст), ДанныеСертификата); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеПроверкиВМоделиСервиса(Результат, Контекст) Экспорт Если Не Результат.Выполнено Тогда Контекст.ОписаниеОшибкиНаСервере = ОбработкаОшибок.КраткоеПредставлениеОшибки(Результат.ИнформацияОбОшибке); ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; Если Не Результат.Действителен Тогда Контекст.ОписаниеОшибкиНаСервере = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиСервисаСертификатНедействителен(); ОбработатьОшибкуПоКлассификатору(Контекст.ОписаниеОшибкиНаСервере, Контекст.ТребуетПроверкиНаСервере, Контекст); ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; ОшибкаПросрочки = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатПросрочен( Контекст.СертификатКриптографии, Контекст.НаДату, ДобавкаВремени()); Если ЗначениеЗаполнено(ОшибкаПросрочки) Тогда Контекст.ОписаниеОшибкиНаСервере = ОшибкаПросрочки; ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; ДополнительнаяПроверкаСертификата(Контекст.СертификатКриптографии, Истина, Контекст); КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеНеуспешнойПроверки(Контекст) Если Контекст.ОбъединитьОшибкиДанныхСертификата Тогда Если Контекст.ОписаниеОшибкиНаКлиенте = Неопределено И Контекст.ОписаниеОшибкиНаСервере = Неопределено Тогда ОбщееОписаниеОшибки = Неопределено; Иначе ОбщееОписаниеОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбщееОписаниеОшибки( Контекст.ОписаниеОшибкиНаКлиенте, Контекст.ОписаниеОшибкиНаСервере, Неопределено); КонецЕсли; Если Контекст.ДляПроверкиПодписи Тогда Структура = Новый Структура; Структура.Вставить("ОбщееОписаниеОшибки", ОбщееОписаниеОшибки); Структура.Вставить("СертификатОтозван", Контекст.СертификатОтозван); Структура.Вставить("ТребуетсяПроверка", ОбщееОписаниеОшибки = Неопределено Или (Контекст.ТребуетПроверкиНаСервере = Неопределено Или Контекст.ТребуетПроверкиНаСервере) И (Контекст.ТребуетПроверкиНаКлиенте = Неопределено Или Контекст.ТребуетПроверкиНаКлиенте)); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Структура); Иначе ВыполнитьОбработкуОповещения(Контекст.Оповещение, ОбщееОписаниеОшибки); КонецЕсли; Иначе Структура = Новый Структура; Структура.Вставить("ОписаниеОшибкиНаКлиенте", Контекст.ОписаниеОшибкиНаКлиенте); Структура.Вставить("ОписаниеОшибкиНаСервере", Контекст.ОписаниеОшибкиНаСервере); Структура.Вставить("ДополнительныеДанныеПроверкиНаСервере", Контекст.ДополнительныеДанныеПроверкиНаСервере); Структура.Вставить("ДополнительныеДанныеПроверкиНаКлиенте", Контекст.ДополнительныеДанныеПроверкиНаКлиенте); Если Контекст.ДляПроверкиПодписи Тогда Структура.Вставить("СертификатОтозван", Контекст.СертификатОтозван); Структура.Вставить("ТребуетсяПроверка", ОбщееОписаниеОшибки = Неопределено Или (Контекст.ТребуетПроверкиНаСервере = Неопределено Или Контекст.ТребуетПроверкиНаСервере) И (Контекст.ТребуетПроверкиНаКлиенте = Неопределено Или Контекст.ТребуетПроверкиНаКлиенте)); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Структура); Иначе ВыполнитьОбработкуОповещения(Контекст.Оповещение, Структура); КонецЕсли; КонецЕсли; КонецПроцедуры // Возвращает дополнительные параметры создания менеджера криптографии. // // Возвращаемое значение: // Структура: // * ПоказатьОшибку - Булево - если Истина, тогда будет открыта форма ОшибкаОбращенияКПрограмме // из которой можно перейти к списку установленных программ // в форму персональных настроек на страницу "Установленные программы", // в которой можно увидеть почему программу не удалось задействовать, // а также открыть инструкцию по установке. // - Неопределено - вернуть все ошибки обращения к программам (см. выше). // // * Программа - Неопределено - возвращает менеджер криптографии первой // программы из справочника для которой удалось его создать. // - СправочникСсылка.ПрограммыЭлектроннойПодписиИШифрования - программа // для которой нужно создать и вернуть менеджер криптографии. // - Структура - см. ЭлектроннаяПодпись.НовоеОписаниеПрограммы // - ДвоичныеДанные - данные подписи или сертификата в кодировке DER для определения программы. // - Строка - адрес двоичных данных, описанных выше, во временном хранилище. // // // * ИнтерактивныйРежим - Булево - если Истина, тогда менеджер криптографии будет создан // в режиме использования интерактивного режима криптографии // (установка свойства ПарольДоступаКЗакрытомуКлючу будет запрещена). // // * АлгоритмПодписи - Строка - если параметр заполнен, возвращает программу с указанным алгоритмом подписи. // * Автоопределение - Булево - использовать автоопределение программ, установленных на компьютере, // если программа не указана. // Функция ПараметрыСозданияМенеджераКриптографии() Экспорт ПараметрыСозданияМенеджераКриптографии = Новый Структура; ПараметрыСозданияМенеджераКриптографии.Вставить("ПоказатьОшибку", Ложь); ПараметрыСозданияМенеджераКриптографии.Вставить("Программа", Неопределено); ПараметрыСозданияМенеджераКриптографии.Вставить("ИнтерактивныйРежим", Ложь); ПараметрыСозданияМенеджераКриптографии.Вставить("АлгоритмПодписи", ""); ПараметрыСозданияМенеджераКриптографии.Вставить("Автоопределение", Истина); Возврат ПараметрыСозданияМенеджераКриптографии; КонецФункции // Создает и возвращает менеджер криптографии (на клиенте) для указанной программы. // // Параметры: // Оповещение - ОписаниеОповещения - оповещение о результате выполнения следующих типов: // = Строка - описание ошибки при создании менеджера криптографии. // = Структура - см. ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеОписаниеОшибок // = МенеджерКриптографии - инициализированный менеджер криптографии. // // Операция - Строка - если не пустая, то должна содержать одну из строк, которые определяют // операцию для вставки в описание ошибки: Подписание, ПроверкаПодписи, Шифрование, // Расшифровка, ПроверкаСертификата, ПолучениеСертификатов. // ПараметрыСозданияМенеджераКриптографии - см. ПараметрыСозданияМенеджераКриптографии. // Процедура СоздатьМенеджерКриптографии(Оповещение, Операция, ПараметрыСозданияМенеджераКриптографии = Неопределено) Экспорт Если ПараметрыСозданияМенеджераКриптографии = Неопределено Тогда ПараметрыСозданияМенеджераКриптографии = ПараметрыСозданияМенеджераКриптографии(); КонецЕсли; Контекст = КонтекстСоздатьМенеджерКриптографии(); Контекст.Операция = Операция; Контекст.Оповещение = Оповещение; Контекст.Программа = ПараметрыСозданияМенеджераКриптографии.Программа; Контекст.ПоказатьОшибку = ПараметрыСозданияМенеджераКриптографии.ПоказатьОшибку; Контекст.АлгоритмПодписи = ПараметрыСозданияМенеджераКриптографии.АлгоритмПодписи; Контекст.ИнтерактивныйРежим = ПараметрыСозданияМенеджераКриптографии.ИнтерактивныйРежим; Контекст.Автоопределение = ПараметрыСозданияМенеджераКриптографии.Автоопределение; НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "СоздатьМенеджерКриптографииПослеПодключенияРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); КонецПроцедуры // Возвращаемое значение: // Структура: // * ИнтерактивныйРежим - Булево // * АлгоритмПодписи - Строка // * ПоказатьОшибку - Булево // * Программа - СправочникСсылка.ПрограммыЭлектроннойПодписиИШифрования // - ДвоичныеДанные - данные подписи или сертификата в кодировке DER // - Строка - адрес данных, указанных выше во временном хранилище // - Структура - см. ЭлектроннаяПодпись.НовоеОписаниеПрограммы // - ФиксированнаяСтруктура - см. ЭлектроннаяПодпись.НовоеОписаниеПрограммы // * Оповещение - ОписаниеОповещения // * Операция - см. СоздатьМенеджерКриптографии.Операция // * Автоопределение - Булево // * ОписаниеПрограмм - Массив из см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы // * СвойстваОшибки - Массив из Структура: // ** Описание - Строка // * Индекс - Число // Функция КонтекстСоздатьМенеджерКриптографии() Контекст = Новый Структура; Контекст.Вставить("Операция"); Контекст.Вставить("Оповещение"); Контекст.Вставить("Программа"); Контекст.Вставить("ПоказатьОшибку"); Контекст.Вставить("АлгоритмПодписи"); Контекст.Вставить("ИнтерактивныйРежим"); Контекст.Вставить("Автоопределение"); Возврат Контекст; КонецФункции // Продолжение процедуры СоздатьМенеджерКриптографии. Асинх Процедура СоздатьМенеджерКриптографииПослеПодключенияРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт ЗаголовокФормы = НСтр("ru = 'Требуется программа электронной подписи и шифрования'"); ЗаголовокОшибки = ЗаголовокОшибкиОперации(Контекст.Операция, Контекст.ПоказатьОшибку); ОписаниеОшибок = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеОписаниеОшибок(); ОписаниеОшибок.ЗаголовокОшибки = ЗаголовокОшибки; ТекстОбщейОшибки = ""; Если Не ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() И Не ОбщегоНазначенияКлиент.ЭтоLinuxКлиент() И Не ОбщегоНазначенияКлиент.ЭтоMacOSКлиент() Тогда ТекстОбщейОшибки = ТекстОшибкиУстройствоНеПоддерживается(); СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); СвойстваОшибки.НеПоддерживается = Истина; КонецЕсли; Если Не Подключено Тогда ТекстОбщейОшибки = НСтр("ru = 'В браузере установите расширение |для работы с электронной подписью и шифрованием.'"); СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); СвойстваОшибки.НетРасширения = Истина; КонецЕсли; Если ТипЗнч(Контекст.Программа) = Тип("Строка") Или ТипЗнч(Контекст.Программа) = Тип("ДвоичныеДанные") Тогда ТребуетсяЗакрытыйКлюч = Контекст.Операция = "Подписание" Или Контекст.Операция = "Расшифровка"; Результат = Ждать ЗаполнитьПараметрыДляСозданияМенеджераКриптографии(Контекст, ТребуетсяЗакрытыйКлюч); Контекст = Результат.Контекст; Если ЗначениеЗаполнено(Результат.Ошибка) Тогда Если ТребуетсяЗакрытыйКлюч И Контекст.Программа = Неопределено Тогда ТекстОбщейОшибки = Результат.Ошибка; СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); Иначе СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); СвойстваОшибки.Описание = Результат.Ошибка; ОписаниеОшибок.Ошибки.Добавить(СвойстваОшибки); КонецЕсли; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ТекстОбщейОшибки) Тогда СвойстваОшибки.Описание = ТекстОбщейОшибки; ОписаниеОшибок.Общая = Истина; ОписаниеОшибок.Ошибки.Добавить(СвойстваОшибки); ОписаниеОшибок.ОписаниеОшибки = СокрЛП(ЗаголовокОшибки + Символы.ПС + ТекстОбщейОшибки); Если Контекст.ПоказатьОшибку = Неопределено Тогда ОписаниеОшибки = ОписаниеОшибок; Иначе ОписаниеОшибки = ОписаниеОшибок.ОписаниеОшибки; КонецЕсли; Если Контекст.ПоказатьОшибку = Истина Тогда ПоказатьОшибкуОбращенияКПрограмме(ЗаголовокФормы, "", ОписаниеОшибок, Новый Структура); КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, ОписаниеОшибки); Возврат; КонецЕсли; ПрограммыАвто = Неопределено; Если Контекст.Автоопределение И ТипЗнч(Контекст.Программа) <> Тип("Структура") И ТипЗнч(Контекст.Программа) <> Тип("ФиксированнаяСтруктура") Тогда КриптопровайдерыРезультат = Ждать УстановленныеКриптопровайдерыИзКэша(); ПрограммыАвто = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатПоискаКриптопровайдеров(КриптопровайдерыРезультат); Если ТипЗнч(ПрограммыАвто) = Тип("Строка") Тогда СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); СвойстваОшибки.Описание = ПрограммыАвто; ОписаниеОшибок.Ошибки.Добавить(СвойстваОшибки); ПрограммыАвто = Неопределено; КонецЕсли; КонецЕсли; Контекст.Вставить("ЗаголовокФормы", ЗаголовокФормы); Контекст.Вставить("ОписаниеОшибок", ОписаниеОшибок); Контекст.Вставить("ЭтоLinux", ТребуетсяПутьКПрограмме()); ОписанияПрограмм = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииОписанияПрограмм( Контекст.Программа, ОписаниеОшибок.Ошибки, ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ОписанияПрограмм, ПрограммыАвто); Контекст.Вставить("Менеджер", Неопределено); Если ОписанияПрограмм = Неопределено Или ОписанияПрограмм.Количество() = 0 Тогда СоздатьМенеджерКриптографииПослеЦикла(Контекст); Возврат; КонецЕсли; Контекст.Вставить("ОписанияПрограмм", ОписанияПрограмм); Контекст.Вставить("Индекс", -1); СоздатьМенеджерКриптографииЦиклНачало(Контекст); КонецПроцедуры // Для процедуры СоздатьМенеджерКриптографии. Функция ЗаголовокОшибкиОперации(Операция, ПоказатьОшибку) Если Операция = "Подписание" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось подписать данные по причине:'"); ИначеЕсли Операция = "ПроверкаПодписи" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось проверить подпись по причине:'"); ИначеЕсли Операция = "Шифрование" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось зашифровать данные по причине:'"); ИначеЕсли Операция = "Расшифровка" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось расшифровать данные по причине:'"); ИначеЕсли Операция = "ПроверкаСертификата" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось проверить сертификат по причине:'"); ИначеЕсли Операция = "ПолучениеСертификатов" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось получить сертификаты по причине:'"); ИначеЕсли Операция = "ЧтениеПодписи" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось прочитать все свойства подписи по причине:'"); ИначеЕсли Операция = "ПродлениеСрокаДействияПодписи" Тогда ЗаголовокОшибки = НСтр("ru = 'Не удалось продлить действие подписи по причине:'"); ИначеЕсли Операция = Null И ПоказатьОшибку <> Истина Тогда ЗаголовокОшибки = ""; ИначеЕсли Операция <> "" Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Ошибка в функции %1. |Неверное значение параметра Операция ""%2"".'"), "МенеджерКриптографии", Операция); Иначе ЗаголовокОшибки = НСтр("ru = 'Не удалось выполнить операцию по причине:'"); КонецЕсли; Возврат ЗаголовокОшибки; КонецФункции // Для процедуры СоздатьМенеджерКриптографии. // // Возвращает уточненный контекст создания менеджера криптографии для указанных данных подписи или сертификата. // Контекст - см. КонтекстСоздатьМенеджерКриптографии // Асинх Функция ЗаполнитьПараметрыДляСозданияМенеджераКриптографии(Контекст, ТребуетсяЗакрытыйКлюч) Результат = Новый Структура("Контекст, Ошибка", Контекст, ""); Данные = Контекст.Программа; Попытка ТипДанных = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОпределитьТипДанных(Данные); Исключение Результат.Контекст.Программа = Неопределено; Результат.Ошибка = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку( НСтр("ru = 'Не удалось определить программу для переданных данных: %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); Возврат Результат; КонецПопытки; Если ТипДанных = "Сертификат" Тогда ПрограммаПоСертификатуРезультат = Ждать ПрограммаПоСертификату(Данные, ТребуетсяЗакрытыйКлюч,, Истина); Если ЗначениеЗаполнено(ПрограммаПоСертификатуРезультат.Ошибка) Тогда Результат.Ошибка = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиНеУдалосьОпределитьПрограмму( ПрограммаПоСертификатуРезультат.Ошибка); Результат.Контекст.АлгоритмПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмПодписиСертификата(Данные); Результат.Контекст.Программа = Неопределено; Иначе Результат.Контекст.Программа = ПрограммаПоСертификатуРезультат.Программа; КонецЕсли; Возврат Результат; ИначеЕсли ТипДанных = "Подпись" Тогда Результат.Контекст.Программа = Неопределено; Результат.Контекст.АлгоритмПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмСформированнойПодписи(Данные); Возврат Результат; ИначеЕсли ТипДанных = "ЗашифрованныеДанные" Тогда Результат.Контекст.Программа = Неопределено; Результат.Ошибка = НСтр("ru = 'Для определения программы для расшифровки в процедуру должны быть переданы данные сертификата.'"); Возврат Результат; КонецЕсли; Результат.Контекст.Программа = Неопределено; Результат.Ошибка = НСтр("ru = 'Не удалось определить программу для переданных данных.'"); Возврат Результат; КонецФункции // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииЦиклНачало(Контекст) Экспорт Если Контекст.ОписанияПрограмм.Количество() <= Контекст.Индекс + 1 Тогда СоздатьМенеджерКриптографииПослеЦикла(Контекст); Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения( "СоздатьМенеджерКриптографииЦиклНачалоПродолжение", ЭтотОбъект, Контекст); СтандартныеПодсистемыКлиент.НачатьВыполнениеОбработкиОповещения(Оповещение); КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииЦиклНачалоПродолжение(Результат, Контекст) Экспорт Контекст = Контекст; // см. КонтекстСоздатьМенеджерКриптографии Контекст.Индекс = Контекст.Индекс + 1; ОписаниеПрограммы = Контекст.ОписанияПрограмм[Контекст.Индекс]; // см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы Контекст.Вставить("ОписаниеПрограммы", ОписаниеПрограммы); Если ЗначениеЗаполнено(Контекст.АлгоритмПодписи) Тогда АлгоритмПодписиПоддерживается = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииАлгоритмПодписиПоддерживается( ОписаниеПрограммы, ?(Контекст.Свойство("Операция"), Контекст.Операция, ""), Контекст.АлгоритмПодписи, Контекст.ОписаниеОшибок.Ошибки, Ложь, Контекст.Программа <> Неопределено); Если Не АлгоритмПодписиПоддерживается Тогда Контекст.Менеджер = Неопределено; СоздатьМенеджерКриптографииЦиклНачало(Контекст); Возврат; КонецЕсли; КонецЕсли; Если ОписаниеПрограммы.Свойство("Автоопределение") Тогда ОписаниеПути = Новый Структура("ПутьКПрограмме, Существует", ОписаниеПрограммы.ПутьКПрограммеАвто, Истина); СоздатьМенеджерКриптографииЦиклПослеПолученияПутиКПрограмме(ОписаниеПути, Контекст); Возврат; КонецЕсли; ИдентификаторПутиКПрограмме = ?(ЗначениеЗаполнено(ОписаниеПрограммы.Ссылка), ОписаниеПрограммы.Ссылка, ОписаниеПрограммы.Идентификатор); ПолучитьПутьКПрограмме(Новый ОписаниеОповещения("СоздатьМенеджерКриптографииЦиклПослеПолученияПутиКПрограмме", ЭтотОбъект, Контекст), ИдентификаторПутиКПрограмме); КонецПроцедуры Процедура СоздатьМенеджерКриптографииЦиклПослеПолученияПутиКПрограмме(ОписаниеПути, Контекст) Экспорт СвойстваПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииСвойстваПрограммы( Контекст.ОписаниеПрограммы, Контекст.ЭтоLinux, Контекст.ОписаниеОшибок.Ошибки, Ложь, ОписаниеПути); Если СвойстваПрограммы = Неопределено Тогда СоздатьМенеджерКриптографииЦиклНачало(Контекст); Возврат; КонецЕсли; Контекст.Вставить("СвойстваПрограммы", СвойстваПрограммы); СредстваКриптографии.НачатьПолучениеИнформацииМодуляКриптографии(Новый ОписаниеОповещения( "СоздатьМенеджерКриптографииЦиклПослеПолученияИнформации", ЭтотОбъект, Контекст, "СоздатьМенеджерКриптографииЦиклПослеОшибкиПолученияИнформации", ЭтотОбъект), Контекст.СвойстваПрограммы.ИмяПрограммы, Контекст.СвойстваПрограммы.ПутьКПрограмме, Контекст.СвойстваПрограммы.ТипПрограммы); КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииЦиклПослеОшибкиПолученияИнформации(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СоздатьМенеджерКриптографииЦиклПриОшибкеИнициализации(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст); КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. // // Параметры: // ИнформацияМодуля - ИнформацияМодуляКриптографии // Контекст - Структура // Процедура СоздатьМенеджерКриптографииЦиклПослеПолученияИнформации(ИнформацияМодуля, Контекст) Экспорт Если ИнформацияМодуля = Неопределено Тогда ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииПрограммаНеНайдена( Контекст.ОписаниеПрограммы, Контекст.ОписаниеОшибок.Ошибки, Ложь); Контекст.Менеджер = Неопределено; СоздатьМенеджерКриптографииЦиклНачало(Контекст); Возврат; КонецЕсли; Если Не Контекст.ЭтоLinux Тогда ИмяПрограммыПолученное = ИнформацияМодуля.Имя; ИмяПрограммыСовпадает = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииИмяПрограммыСовпадает( Контекст.ОписаниеПрограммы, ИмяПрограммыПолученное, Контекст.ОписаниеОшибок.Ошибки, Ложь); Если Не ИмяПрограммыСовпадает Тогда Контекст.Менеджер = Неопределено; СоздатьМенеджерКриптографииЦиклНачало(Контекст); Возврат; КонецЕсли; КонецЕсли; Контекст.Менеджер = Новый МенеджерКриптографии; Если Не Контекст.ИнтерактивныйРежим Тогда Контекст.Менеджер.НачатьИнициализацию(Новый ОписаниеОповещения( "СоздатьМенеджерКриптографииЦиклПослеИнициализации", ЭтотОбъект, Контекст, "СоздатьМенеджерКриптографииЦиклПриОшибкеИнициализации", ЭтотОбъект), Контекст.СвойстваПрограммы.ИмяПрограммы, Контекст.СвойстваПрограммы.ПутьКПрограмме, Контекст.СвойстваПрограммы.ТипПрограммы); Иначе Контекст.Менеджер.НачатьИнициализацию(Новый ОписаниеОповещения( "СоздатьМенеджерКриптографииЦиклПослеИнициализации", ЭтотОбъект, Контекст, "СоздатьМенеджерКриптографииЦиклПриОшибкеИнициализации", ЭтотОбъект), Контекст.СвойстваПрограммы.ИмяПрограммы, Контекст.СвойстваПрограммы.ПутьКПрограмме, Контекст.СвойстваПрограммы.ТипПрограммы, ИспользованиеИнтерактивногоРежимаКриптографииИспользовать()); КонецЕсли; КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииЦиклПриОшибкеИнициализации(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; Контекст.Менеджер = Неопределено; ОписаниеПрограммы = Контекст.ОписаниеПрограммы; // см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииДобавитьОшибку( Контекст.ОписаниеОшибок.Ошибки, ОписаниеПрограммы.Ссылка, ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке), Ложь, Истина, Истина); СоздатьМенеджерКриптографииЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииЦиклПослеИнициализации(Неопределен, Контекст) Экспорт АлгоритмыУстановлены = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииАлгоритмыУстановлены( Контекст.ОписаниеПрограммы, Контекст.Менеджер, Контекст.ОписаниеОшибок.Ошибки); Если Не АлгоритмыУстановлены Тогда СоздатьМенеджерКриптографииЦиклНачало(Контекст); Возврат; КонецЕсли; // Требуемый менеджер криптографии получен. СоздатьМенеджерКриптографииПослеЦикла(Контекст); КонецПроцедуры // Продолжение процедуры СоздатьМенеджерКриптографии. Процедура СоздатьМенеджерКриптографииПослеЦикла(Контекст) Если Контекст.Менеджер <> Неопределено Или Не Контекст.Свойство("ЗаголовокФормы") Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Контекст.Менеджер); Возврат; КонецЕсли; ОписаниеОшибок = Контекст.ОписаниеОшибок; ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииЗаполнитьПредставлениеОшибок( ОписаниеОшибок, Контекст.Программа, Контекст.АлгоритмПодписи, ПользователиКлиент.ЭтоПолноправныйПользователь(), Ложь); Если Контекст.ПоказатьОшибку = Неопределено Тогда ОписаниеОшибки = ОписаниеОшибок; Иначе ОписаниеОшибки = ОписаниеОшибок.ОписаниеОшибки; КонецЕсли; Если Контекст.ПоказатьОшибку = Истина Тогда ПоказатьОшибкуОбращенияКПрограмме(Контекст.ЗаголовокФормы, "", ОписаниеОшибок, Новый Структура); КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, ОписаниеОшибки); КонецПроцедуры Асинх Функция ОбъектВнешнейКомпонентыExtraCryptoAPI(ПредложитьУстановить = Истина, ТекстПояснения = Неопределено) Экспорт Если Не ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() И Не ОбщегоНазначенияКлиент.ЭтоLinuxКлиент() И Не ОбщегоНазначенияКлиент.ЭтоMacOSКлиент() Тогда ВызватьИсключение ТекстОшибкиУстройствоНеПоддерживается(); КонецЕсли; ОписаниеКомпоненты = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеКомпоненты(); ПараметрыПодключения = ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты(); Если ТекстПояснения = Неопределено Тогда ПараметрыПодключения.ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для упрощения работы с криптографией требуется установка внешней компоненты %1.'"), ОписаниеКомпоненты.ИмяОбъекта); Иначе ПараметрыПодключения.ТекстПояснения = ТекстПояснения; КонецЕсли; ПараметрыПодключения.ПредложитьУстановить = ПредложитьУстановить; ПараметрыПодключения.ПредложитьЗагрузить = Ложь; Результат = Ждать ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакетаАсинх( ОписаниеКомпоненты.ИмяОбъекта, ОписаниеКомпоненты.ПолноеИмяМакета, ПараметрыПодключения); Если Результат.Подключено Тогда ОбъектКомпоненты = Результат.ПодключаемыйМодуль; ОбъектКомпоненты = Ждать НастроитьКомпоненту(ОбъектКомпоненты); ИначеЕсли ЗначениеЗаполнено(Результат.ОписаниеОшибки) Тогда ВызватьИсключение Результат.ОписаниеОшибки; Иначе ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось подключить внешнюю компоненту %1.'"), ОписаниеКомпоненты.ИмяОбъекта); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат ОбъектКомпоненты; КонецФункции Асинх Функция НастроитьКомпоненту(ОбъектКомпоненты) Попытка Ждать ОбъектКомпоненты.УстановитьСоответствиеOIDАсинх( ЭлектроннаяПодписьСлужебныйКлиентСервер.ИдентификаторыАлгоритмовХешированияИОткрытогоКлюча()); Исключение ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить свойство %1 компоненты %2 по причине: |%3'"), "СоответствиеOID", "ExtraCryptoAPI", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Возврат ОбъектКомпоненты; КонецФункции Асинх Функция ПрограммаПоСертификату(Сертификат, ТребуетсяЗакрытыйКлюч = Неопределено, ОбъектКомпоненты = Неопределено, ПредложитьУстановить = Ложь) Экспорт Результат = Новый Структура("Программа, Ошибка"); Если ОбъектКомпоненты = Неопределено Тогда ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для получения данных о программе для работы с сертификатом электронной подписи требуется установка внешней компоненты %1.'"), "ExtraCryptoAPI"); Попытка ОбъектКомпоненты = Ждать ОбъектВнешнейКомпонентыExtraCryptoAPI(ПредложитьУстановить, ТекстПояснения); Исключение Результат.Ошибка = ТекстОшибкиНеУстановленаКомпонента(); Возврат Результат; КонецПопытки; КонецЕсли; Сертификат = Ждать СертификатBase64Строка(Сертификат); Если ТребуетсяЗакрытыйКлюч <> Ложь Тогда Попытка РезультатСвойстваКриптопровайдера = Ждать ОбъектКомпоненты.ПолучитьСвойстваКриптопровайдераАсинх(Сертификат); ТекущийКриптопровайдер = КриптопровайдерИзОтветаКомпоненты(РезультатСвойстваКриптопровайдера.Значение); Исключение Результат.Ошибка = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); Возврат Результат; КонецПопытки; ПрограммыПоИменамСТипом = ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ПрограммыПоИменамСТипом; РасширенноеОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.РасширенноеОписаниеПрограммы( ТекущийКриптопровайдер, ПрограммыПоИменамСТипом); Если РасширенноеОписаниеПрограммы <> Неопределено Тогда Результат.Программа = РасширенноеОписаниеПрограммы; Возврат Результат; ИначеЕсли ТребуетсяЗакрытыйКлюч = Истина И ТекущийКриптопровайдер.Получить("type") <> 0 Тогда Результат.Ошибка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Сертификат связан с программой %1 с типом %2, настройте ее в справочнике для использования.'"), ТекущийКриптопровайдер.Получить("name"), ТекущийКриптопровайдер.Получить("type")); Возврат Результат; КонецЕсли; КонецЕсли; Если ТребуетсяЗакрытыйКлюч = Истина Тогда Результат.Ошибка = ТекстОшибкиНеУдалосьОпределитьПрограммуПоЗакрытомуКлючуСертификата(); Возврат Результат; КонецЕсли; СвойстваСертификата = Ждать ПолучитьСвойстваСертификатаАсинх(Сертификат, ОбъектКомпоненты); Если ЗначениеЗаполнено(СвойстваСертификата.Ошибка) Тогда Результат.Ошибка = СвойстваСертификата.Ошибка; Возврат Результат; КонецЕсли; СвойстваСертификата = СвойстваСертификата.СвойстваСертификата; УстановленныеКриптопровайдеры = Ждать УстановленныеКриптопровайдерыИзКэша( ПредложитьУстановить); Если УстановленныеКриптопровайдеры.ПроверкаВыполнена Тогда ПрограммыПоИдентификаторамАлгоритмовОткрытогоКлюча = ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ПрограммыПоИдентификаторамАлгоритмовОткрытогоКлюча; Ошибка = ""; РасширенноеОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОпределитьПрограмму(СвойстваСертификата, УстановленныеКриптопровайдеры.Криптопровайдеры, ПрограммыПоИдентификаторамАлгоритмовОткрытогоКлюча, Ошибка); Результат.Программа = РасширенноеОписаниеПрограммы; Если Результат.Программа = Неопределено Тогда Результат.Ошибка = Ошибка; КонецЕсли; Возврат Результат; Иначе Результат.Ошибка = УстановленныеКриптопровайдеры.Ошибка; Возврат Результат; КонецЕсли; КонецФункции Функция ТекстОшибкиНеУдалосьОпределитьПрограммуПоЗакрытомуКлючуСертификата() Возврат НСтр("ru = 'Не удалось определить программу по закрытому ключу сертификата.'"); КонецФункции Функция КриптопровайдерИзОтветаКомпоненты(Знач Текст) Результат = Новый Соответствие; Попытка ЗаполнитьСоответствиеИзОтветаJSON(Результат, Текст); Возврат Результат; Исключение ИнформацияОбОшибке = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось прочитать ответ компоненты: %1 |%2'"), Текст, ИнформацияОбОшибке); КонецПопытки; Возврат Результат; КонецФункции // Для функции КриптопровайдерИзОтветаКомпоненты Процедура ЗаполнитьСоответствиеИзОтветаJSON(Результат, Знач ТекстJSON) ТекстJSON = СтрЗаменить(СокрЛП(ТекстJSON), Символы.ПС, ""); ТекстJSON = СокрЛП(Сред(ТекстJSON, 2, СтрДлина(ТекстJSON)-2)); Пока ТекстJSON <> "" Цикл Позиция = СтрНайти(ТекстJSON, ":"); Если Позиция = 0 Тогда Прервать; КонецЕсли; ИмяЗначения = СокрЛП(Лев(ТекстJSON, Позиция-1)); ИмяЗначения = СтрЗаменить(ИмяЗначения, """",""); ЭтоЧисло = Ложь; ТекстJSON = СокрЛП(Сред(ТекстJSON, Позиция+1)); Если Лев(ТекстJSON, 1) = """" Тогда ТекстJSON = СокрЛП(Сред(ТекстJSON, 2)); Иначе ЭтоЧисло = Истина; КонецЕсли; Позиция = 0; Для НоваяПозиция = 1 По СтрДлина(ТекстJSON) Цикл Символ = Сред(ТекстJSON, НоваяПозиция, 1); СледующийСимвол = Неопределено; Если Символ = "," Тогда Для СледующаяПозиция = НоваяПозиция + 1 По СтрДлина(ТекстJSON) Цикл СледующийСимвол = Сред(ТекстJSON, СледующаяПозиция, 1); Если СледующийСимвол <> " " Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если Символ = "," И (СледующийСимвол = Неопределено ИЛИ СледующийСимвол = """") Тогда Позиция = НоваяПозиция; Прервать; КонецЕсли; КонецЦикла; Если Позиция = 0 Тогда Значение = ТекстJSON; ТекстJSON = ""; Иначе Значение = Лев(ТекстJSON, Позиция-1); ТекстJSON = СокрЛП(Сред(ТекстJSON, Позиция + ?(Сред(ТекстJSON, Позиция, 1) = ",", 1, 0))); КонецЕсли; Значение = СокрЛП(Значение); Если Значение = "true" Тогда Значение = Истина; ИначеЕсли Значение = "false" Тогда Значение = Ложь; ИначеЕсли Значение = "null" Тогда Значение = Неопределено; Иначе Если ЭтоЧисло Тогда Значение = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(Значение); Иначе Значение = Лев(Значение, СтрДлина(Значение)-1); КонецЕсли; КонецЕсли; Результат.Вставить(ИмяЗначения, Значение); КонецЦикла; КонецПроцедуры // Контейнеры по сертификату. // // Параметры: // Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище // - Строка - строковое представление сертификата в формате Base64 // - СертификатКриптографии // ОбъектКомпоненты - ОбъектВнешнейКомпоненты - экземпляр объекта внешней компоненты // // Возвращаемое значение: // Обещание - Массив из см. НовыеСвойстваКонтейнера // Асинх Функция КонтейнерыПоСертификату(Сертификат, ОбъектКомпоненты = Неопределено) Экспорт Если ОбъектКомпоненты = Неопределено Тогда ОбъектКомпоненты = Ждать ОбъектВнешнейКомпонентыExtraCryptoAPI(Истина); КонецЕсли; Сертификат = Ждать СертификатBase64Строка(Сертификат); Контейнеры = Новый Массив; СвойстваСертификатаРезультат = Ждать ПолучитьСвойстваСертификатаАсинх(Сертификат, ОбъектКомпоненты); Если Не ПустаяСтрока(СвойстваСертификатаРезультат.Ошибка) Тогда ВызватьИсключение СвойстваСертификатаРезультат.Ошибка; КонецЕсли; СвойстваСертификата = СвойстваСертификатаРезультат.СвойстваСертификата; ИменаКонтейнеров = Новый Соответствие; ПрограммаПоСертификатуРезультат = Ждать ПрограммаПоСертификату(Сертификат, Неопределено, ОбъектКомпоненты, Истина); Если ПрограммаПоСертификатуРезультат.Программа <> Неопределено Тогда Контейнеры = Ждать ДобавитьКонтейнерыПоСертификатуПоКриптопровайдеру( СвойстваСертификата, ПрограммаПоСертификатуРезультат.Программа, ОбъектКомпоненты, Контейнеры, ИменаКонтейнеров); Для Каждого ТекущийКонтейнер Из Контейнеры Цикл ИменаКонтейнеров.Вставить(ТекущийКонтейнер.Имя, Истина); КонецЦикла; КонецЕсли; КриптопровайдерыРезультат = Ждать УстановленныеКриптопровайдеры(ОбъектКомпоненты); Если Не КриптопровайдерыРезультат.ПроверкаВыполнена Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось получить список установленных криптопровайдеров: |%1'"), КриптопровайдерыРезультат.Ошибка); КонецЕсли; Для Каждого ТекущийКриптопровайдер Из КриптопровайдерыРезультат.Криптопровайдеры Цикл Контейнеры = Ждать ДобавитьКонтейнерыПоСертификатуПоКриптопровайдеру( СвойстваСертификата, ТекущийКриптопровайдер, ОбъектКомпоненты, Контейнеры, ИменаКонтейнеров); Для Каждого ТекущийКонтейнер Из Контейнеры Цикл ИменаКонтейнеров.Вставить(ТекущийКонтейнер.Имя, Истина); КонецЦикла; КонецЦикла; Возврат Контейнеры; КонецФункции // Для КонтейнерыПоСертификату Асинх Функция ДобавитьКонтейнерыПоСертификатуПоКриптопровайдеру(СвойстваСертификата, Криптопровайдер, ОбъектКомпоненты, Контейнеры, ИменаКонтейнеров) Результат = Ждать ОбъектКомпоненты.НайтиКонтейнерыАсинх( Криптопровайдер.ТипПрограммы, Криптопровайдер.ИмяПрограммы, СвойстваСертификата.Сертификат); Если ЗначениеЗаполнено(Результат.Значение) И Результат.Значение <> "null" Тогда Прочитано = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПрочитатьОтветКомпоненты(Результат.Значение); Иначе Возврат Контейнеры; КонецЕсли; КонтейнерыКриптопровайдера = Прочитано.Получить(Криптопровайдер.ИмяПрограммы); СвойстваКонтейнеров = КонтейнерыКриптопровайдера.Получить("containers"); Если СвойстваКонтейнеров = Неопределено Тогда Возврат Контейнеры; КонецЕсли; Для Каждого ТекущийКонтейнер Из СвойстваКонтейнеров Цикл ИмяКонтейнера = ТекущийКонтейнер.Получить("FQCN"); Если ИменаКонтейнеров.Получить(ИмяКонтейнера) = Истина Тогда Продолжить; КонецЕсли; ЭтоТекущийКонтейнер = ИмяКонтейнера = СвойстваСертификата.ИмяКонтейнера; Контейнер = НовыеСвойстваКонтейнера(); Контейнер.Имя = ИмяКонтейнера; Контейнер.ДружественноеИмя = ТекущийКонтейнер.Получить("Friendly name"); Если Не ЗначениеЗаполнено(Контейнер.ДружественноеИмя) Тогда Контейнер.ДружественноеИмя = Контейнер.Имя; КонецЕсли; Контейнер.ТипПрограммы = Криптопровайдер.ТипПрограммы; Контейнер.ИмяПрограммы = Криптопровайдер.ИмяПрограммы; Контейнер.ПутьКПрограмме = Криптопровайдер.ПутьКПрограммеАвто; Контейнер.Вставить("ЭтоТекущийКонтейнер", ЭтоТекущийКонтейнер); Контейнеры.Добавить(Контейнер); КонецЦикла; Возврат Контейнеры; КонецФункции // Свойства контейнера закрытого ключа. // // Возвращаемое значение: // Структура: // * Имя - Строка // * ДружественноеИмя - Строка // * ТипПрограммы - Число // * ИмяПрограммы - Строка // * ПутьКПрограмме - Строка // Функция НовыеСвойстваКонтейнера() Экспорт Контейнер = Новый Структура; Контейнер.Вставить("Имя", ""); Контейнер.Вставить("ДружественноеИмя", ""); Контейнер.Вставить("ТипПрограммы", 0); Контейнер.Вставить("ИмяПрограммы", ""); Контейнер.Вставить("ПутьКПрограмме", ""); Возврат Контейнер; КонецФункции // Только для внутреннего назначения. // // Параметры: // ПараметрыСоздания - см. ПараметрыДобавленияСертификата // ОбработчикЗавершения - Неопределено - обработчик завершения // Процедура ДобавитьСертификат(ПараметрыСоздания = Неопределено, ОбработчикЗавершения = Неопределено) Экспорт ПараметрыДобавленияСертификата = ПараметрыДобавленияСертификата(); ЗаполнитьЗначенияСвойств(ПараметрыДобавленияСертификата, ПараметрыСоздания); ПараметрыДобавленияСертификата.ОбработчикЗавершения = ОбработчикЗавершения; Если ПараметрыДобавленияСертификата.СоздатьЗаявление = Истина Тогда ДобавитьСертификатПослеВыбораНазначения("ЗаявлениеНаВыпускСертификата", ПараметрыДобавленияСертификата); Возврат; КонецЕсли; Если ПараметрыДобавленияСертификата.СкрытьЗаявление = Неопределено Тогда ПараметрыДобавленияСертификата.СкрытьЗаявление = Истина; КонецЕсли; Форма = ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ДобавлениеСертификата", Новый Структура("СкрытьЗаявление", ПараметрыДобавленияСертификата.СкрытьЗаявление),,,,, Новый ОписаниеОповещения("ДобавитьСертификатПослеВыбораНазначения", ЭтотОбъект, ПараметрыДобавленияСертификата)); Если Форма = Неопределено Тогда ДобавитьСертификатПослеВыбораНазначения("ДляПодписанияШифрованияИРасшифровки", ПараметрыДобавленияСертификата); КонецЕсли; КонецПроцедуры // Только для внутреннего назначения. // // Возвращаемое значение: // Структура - параметры добавления сертификата: // * ВЛичныйСписок - Булево - если не указано, значит Ложь. // * Организация - ОпределяемыйТип.Организация - значение по умолчанию. // * ФизическоеЛицо - СправочникСсылка - физическое лицо, для которого нужно создать заявление // на выпуск сертификата (когда заполнено, имеет приоритет над организацией). // Значение по умолчанию - Неопределено. // * СертификатОснование - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования - сертификат, который надо перевыпустить. // * ОбработчикЗавершения - ОписаниеОповещения // * СоздатьЗаявление - Булево - сразу открыть форму создания заявления на выпуск сертификата. // * СкрытьЗаявление - Булево - не предлагать создать заявление на выпуск сертификата. // Функция ПараметрыДобавленияСертификата() Экспорт Структура = Новый Структура; Структура.Вставить("ВЛичныйСписок", Ложь); Структура.Вставить("Организация", Неопределено); Структура.Вставить("ФизическоеЛицо", Неопределено); Структура.Вставить("СертификатОснование", Неопределено); Структура.Вставить("ОбработчикЗавершения", Неопределено); Структура.Вставить("СоздатьЗаявление", Неопределено); Структура.Вставить("СкрытьЗаявление", Неопределено); Возврат Структура; КонецФункции // Только для внутреннего назначения. Процедура ДобавитьСертификатПослеВыбораНазначения(Назначение, ПараметрыСоздания) Экспорт ПараметрыФормы = Новый Структура; Если Назначение = "ЗаявлениеНаВыпускСертификата" Тогда ПараметрыФормы.Вставить("Организация", ПараметрыСоздания.Организация); ПараметрыФормы.Вставить("ФизическоеЛицо", ПараметрыСоздания.ФизическоеЛицо); ПараметрыФормы.Вставить("СертификатОснование", ПараметрыСоздания.СертификатОснование); ИмяФормы = "Обработка.ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.Форма.Форма"; ОткрытьФорму(ИмяФормы, ПараметрыФормы, , , , , ПараметрыСоздания.ОбработчикЗавершения); Возврат; КонецЕсли; Если Назначение = "ТолькоДляШифрованияИзФайла" Тогда ДобавитьСертификатТолькоДляШифрованияИзФайла(ПараметрыСоздания); Возврат; КонецЕсли; Если Назначение = "ТолькоДляШифрованияИзФайлов" Тогда ДобавитьСертификатТолькоДляШифрованияИзФайла(ПараметрыСоздания, Истина); Возврат; КонецЕсли; Если Назначение = "ТолькоДляШифрованияИзКаталога" Тогда ДобавитьСертификатТолькоДляШифрованияИзКаталога(ПараметрыСоздания); Возврат; КонецЕсли; Если Назначение <> "ТолькоДляШифрования" Тогда ПараметрыФормы.Вставить("ДляШифрованияИРасшифровки", Неопределено); Если Назначение = "ДляШифрованияИРасшифровки" Тогда ПараметрыФормы.Вставить("ДляШифрованияИРасшифровки", Истина); ИначеЕсли Назначение <> "ДляПодписанияШифрованияИРасшифровки" Тогда Возврат; КонецЕсли; ПараметрыФормы.Вставить("ДобавлениеВСписок", Истина); ПараметрыФормы.Вставить("ЛичныйСписокПриДобавлении", ПараметрыСоздания.ВЛичныйСписок); ПараметрыФормы.Вставить("Организация", ПараметрыСоздания.Организация); ВыборСертификатаДляПодписанияИлиРасшифровки(ПараметрыФормы, , ПараметрыСоздания.ОбработчикЗавершения); Возврат; КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("ПараметрыСоздания", ПараметрыСоздания); ПолучитьСвойстваСертификатовНаКлиенте(Новый ОписаниеОповещения( "ДобавитьСертификатПослеПолученияСвойствСертификатовНаКлиенте", ЭтотОбъект, Контекст), Ложь, Ложь); КонецПроцедуры // Продолжение процедуры ДобавитьСертификатПослеВыбораНазначения. Процедура ДобавитьСертификатПослеПолученияСвойствСертификатовНаКлиенте(Результат, Контекст) Экспорт ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("СвойстваСертификатовНаКлиенте", Результат.СвойстваСертификатовНаКлиенте); ПараметрыФормы.Вставить("ОшибкаПолученияСертификатовНаКлиенте", Результат.ОшибкаПолученияСертификатовНаКлиенте); Если Контекст.ПараметрыСоздания.Свойство("ВЛичныйСписок") Тогда ПараметрыФормы.Вставить("ЛичныйСписокПриДобавлении", Контекст.ПараметрыСоздания.ВЛичныйСписок); КонецЕсли; Если Контекст.ПараметрыСоздания.Свойство("Организация") Тогда ПараметрыФормы.Вставить("Организация", Контекст.ПараметрыСоздания.Организация); КонецЕсли; ОбработчикЗавершения = Неопределено; Контекст.ПараметрыСоздания.Свойство("ОбработчикЗавершения", ОбработчикЗавершения); ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ДобавлениеСертификатаДляШифрования", ПараметрыФормы, , , , , ОбработчикЗавершения); КонецПроцедуры // Только для внутреннего назначения. Процедура ПолучитьСвойстваСертификатовНаКлиенте(Оповещение, Личные, БезОтбора, ТолькоОтпечатки = Ложь, ПоказатьОшибку = Неопределено) Экспорт Результат = Новый Структура; Результат.Вставить("ОшибкаПолученияСертификатовНаКлиенте", Новый Структура); Результат.Вставить("СвойстваСертификатовНаКлиенте", ?(ТолькоОтпечатки, Новый Соответствие, Новый Массив)); Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("Личные", Личные); Контекст.Вставить("БезОтбора", БезОтбора); Контекст.Вставить("ТолькоОтпечатки", ТолькоОтпечатки); Контекст.Вставить("Результат", Результат); ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = ПоказатьОшибку; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПолучитьСвойстваСертификатовНаКлиентеПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПолучениеСертификатов", ПараметрыСоздания); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст) Экспорт Если ТипЗнч(МенеджерКриптографии) <> Тип("МенеджерКриптографии") Тогда Контекст.Результат.ОшибкаПолученияСертификатовНаКлиенте = МенеджерКриптографии; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Контекст.Результат); Возврат; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Контекст.МенеджерКриптографии.НачатьПолучениеХранилищаСертификатов( Новый ОписаниеОповещения( "ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияПерсональногоХранилища", ЭтотОбъект, Контекст), ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияПерсональногоХранилища(Хранилище, Контекст) Экспорт Хранилище.НачатьПолучениеВсех(Новый ОписаниеОповещения( "ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсехПерсональныхСертификатов", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсехПерсональныхСертификатов(Массив, Контекст) Экспорт Контекст.Вставить("МассивСертификатов", Массив); Если Контекст.Личные Тогда ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсех(Контекст); Возврат; КонецЕсли; Контекст.МенеджерКриптографии.НачатьПолучениеХранилищаСертификатов( Новый ОписаниеОповещения( "ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияХранилищаПолучателей", ЭтотОбъект, Контекст), ТипХранилищаСертификатовКриптографии.СертификатыПолучателей); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияХранилищаПолучателей(Хранилище, Контекст) Экспорт Хранилище.НачатьПолучениеВсех(Новый ОписаниеОповещения( "ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсехСертификатовПолучателей", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. // // Параметры: // Контекст - Структура: // * МассивСертификатов - Массив // Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсехСертификатовПолучателей(Массив, Контекст) Экспорт Для каждого Сертификат Из Массив Цикл Контекст.МассивСертификатов.Добавить(Сертификат); КонецЦикла; ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсех(Контекст); КонецПроцедуры // Продолжение процедуры ПолучитьСвойстваСертификатовНаКлиенте. Процедура ПолучитьСвойстваСертификатовНаКлиентеПослеПолученияВсех(Контекст) ПараметрыДобавленияСвойств = Новый Структура("ТолькоОтпечатки", Контекст.ТолькоОтпечатки); ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьСвойстваСертификатов( Контекст.Результат.СвойстваСертификатовНаКлиенте, Контекст.МассивСертификатов, Контекст.БезОтбора, ДобавкаВремени(), ОбщегоНазначенияКлиент.ДатаСеанса(), ПараметрыДобавленияСвойств); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Контекст.Результат); КонецПроцедуры // Только для внутреннего назначения. Процедура ДобавитьСертификатТолькоДляШифрованияИзФайла(ПараметрыСоздания, МножественныйВыбор = Ложь) Экспорт Оповещение = Новый ОписаниеОповещения("ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайлов", ЭтотОбъект, ПараметрыСоздания); ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла(); ПараметрыЗагрузки.Диалог.Заголовок = НСтр("ru = 'Выберите файл сертификата (только для шифрования)'"); ПараметрыЗагрузки.Диалог.Фильтр = НСтр("ru = 'Сертификат X.509 (*.cer;*.crt)|*.cer;*.crt'")+ "|" + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Все файлы (%1)|%1'"), ПолучитьМаскуВсеФайлы()); Если МножественныйВыбор Тогда ПараметрыЗагрузки.Диалог.МножественныйВыбор = МножественныйВыбор; ФайловаяСистемаКлиент.ЗагрузитьФайлы(Оповещение, ПараметрыЗагрузки); Иначе ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки); КонецЕсли; КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзФайла. Процедура ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайлов(ПомещенныеФайлы, Контекст) Экспорт Если Не ЗначениеЗаполнено(ПомещенныеФайлы) Тогда Возврат; КонецЕсли; Если ТипЗнч(ПомещенныеФайлы) = Тип("Массив") Тогда Если ПомещенныеФайлы.Количество() = 1 Тогда ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайла(ПомещенныеФайлы[0].Хранение, Контекст); Возврат; КонецЕсли; ДобавитьСертификатыТолькоДляШифрованияИзФайлаПослеПомещенияФайлов(ПомещенныеФайлы, Контекст); Возврат; КонецЕсли; ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайла(ПомещенныеФайлы.Хранение, Контекст); КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзФайла. Процедура ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайла(Адрес, Контекст) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("АдресДанныхСертификата", Адрес); ПараметрыФормы.Вставить("ЛичныйСписокПриДобавлении", Контекст.ВЛичныйСписок); ПараметрыФормы.Вставить("Организация", Контекст.Организация); ОбработчикЗавершения = ?(Контекст.Свойство("ОбработчикЗавершения"), Контекст.ОбработчикЗавершения, Неопределено); Форма = ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ДобавлениеСертификатаДляШифрования", ПараметрыФормы, , , , , ОбработчикЗавершения); Если Форма = Неопределено Тогда ПоказатьПредупреждение(, НСтр("ru = 'Файл сертификата должен быть в формате DER X.509, операция прервана.'")); Возврат; КонецЕсли; Если Не Форма.Открыта() Тогда Кнопки = Новый СписокЗначений; Кнопки.Добавить("Открыть", НСтр("ru = 'Открыть'")); Кнопки.Добавить("Отмена", НСтр("ru = 'Отмена'")); ПоказатьВопрос( Новый ОписаниеОповещения("ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПредупрежденияОСуществующем", ЭтотОбъект, Форма.Сертификат), НСтр("ru = 'Сертификат уже добавлен.'"), Кнопки); КонецЕсли; КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзФайла. Процедура ДобавитьСертификатыТолькоДляШифрованияИзФайлаПослеПомещенияФайлов(ПомещенныеФайлы, Контекст) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПомещенныеФайлы", ПомещенныеФайлы); ПараметрыФормы.Вставить("Организация", Контекст.Организация); ОбработчикЗавершения = ?(Контекст.Свойство("ОбработчикЗавершения"), Контекст.ОбработчикЗавершения, Неопределено); ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ДобавлениеСертификатовДляШифрования", ПараметрыФормы, , , , , ОбработчикЗавершения); КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзФайла. Процедура ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПредупрежденияОСуществующем(Ответ, Сертификат) Экспорт Если Ответ <> "Открыть" Тогда Возврат; КонецЕсли; ОткрытьСертификат(Сертификат); КонецПроцедуры // Только для внутреннего назначения. Процедура ДобавитьСертификатТолькоДляШифрованияИзКаталога(ПараметрыСоздания) Оповещение = Новый ОписаниеОповещения("ДобавитьСертификатТолькоДляШифрованияИзКаталогаПослеПодключенияРасширения", ЭтотОбъект, ПараметрыСоздания); ТекстПредложения = НСтр("ru = 'Для загрузки сертификатов из каталога требуется установить расширение для работы с 1С:Предприятием.'"); ФайловаяСистемаКлиент.ПодключитьРасширениеДляРаботыСФайлами(Оповещение, ТекстПредложения, Ложь); КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзКаталога. Процедура ДобавитьСертификатТолькоДляШифрованияИзКаталогаПослеПодключенияРасширения(Результат, ПараметрыСоздания) Экспорт Если Результат <> Истина Тогда Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения("ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеВыбораКаталога", ЭтотОбъект, ПараметрыСоздания); Заголовок = НСтр("ru = 'Выберите каталог файлов сертификатов (только для шифрования)'"); ФайловаяСистемаКлиент.ВыбратьКаталог(Оповещение, Заголовок); КонецПроцедуры // Продолжение процедуры ДобавитьСертификатТолькоДляШифрованияИзКаталога. Асинх Процедура ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеВыбораКаталога(ВыбранныйКаталог, Контекст) Экспорт Если Не ЗначениеЗаполнено(ВыбранныйКаталог) Тогда Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения("ДобавитьСертификатТолькоДляШифрованияИзФайлаПослеПомещенияФайлов", ЭтотОбъект, Контекст); ОписаниеПередаваемыхФайлов = Новый Массив; Файлы = Ждать НайтиФайлыАсинх(ВыбранныйКаталог,"*.*", Истина); Для Каждого ТекущийФайл Из Файлы Цикл Если Ждать ТекущийФайл.ЭтоКаталогАсинх() Тогда Продолжить; КонецЕсли; ОписаниеПередаваемогоФайла = Новый ОписаниеПередаваемогоФайла(ТекущийФайл.ПолноеИмя); ОписаниеПередаваемыхФайлов.Добавить(ОписаниеПередаваемогоФайла); КонецЦикла; Если ОписаниеПередаваемыхФайлов.Количество() = 0 Тогда ВызватьИсключение НСтр("ru = 'Указанный каталог не содержит файлов.'"); КонецЕсли; ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла(); ПараметрыЗагрузки.Интерактивно = Ложь; ФайловаяСистемаКлиент.ЗагрузитьФайлы(Оповещение, ПараметрыЗагрузки, ОписаниеПередаваемыхФайлов); КонецПроцедуры // Продолжение процедуры ПоказатьОшибкуОбращенияКПрограмме. Процедура ПоказатьОшибкуОбращенияКПрограммеПослеПодключенияРасширения(Подключено, Контекст) Экспорт Контекст.ПараметрыФормы.Вставить("РасширениеПодключено", Подключено); ОткрытьФорму("Справочник.ПрограммыЭлектроннойПодписиИШифрования.Форма.ОшибкаОбращенияКПрограмме", Контекст.ПараметрыФормы,,,, , Контекст.ОбработкаПродолжения); КонецПроцедуры // Только для внутреннего использования. Процедура УстановитьПарольСертификата(СертификатСсылка, Пароль, ПояснениеПароля = Неопределено) Экспорт ФормаПередачаПараметров().УстановитьПарольСертификата(СертификатСсылка, Пароль, ПояснениеПароля); КонецПроцедуры // Только для внутреннего использования. Функция ПарольСертификатаУстановлен(СертификатСсылка) Экспорт Возврат ФормаПередачаПараметров().ПарольСертификатаУстановлен(СертификатСсылка); КонецФункции // Только для внутреннего использования. Процедура ОткрытьНовуюФорму(ВидФормы, КлиентскиеПараметры, СерверныеПараметры, ОбработкаЗавершения) Экспорт ОписаниеДанных = КлиентскиеПараметры.ОписаниеДанных; СерверныеПараметры.Вставить("БезПодтверждения", Ложь); Если СерверныеПараметры.Свойство("ОтборСертификатов") И ТипЗнч(СерверныеПараметры.ОтборСертификатов) = Тип("Массив") И СерверныеПараметры.ОтборСертификатов.Количество() = 1 И ОписаниеДанных.Свойство("БезПодтверждения") И ОписаниеДанных.БезПодтверждения Тогда СерверныеПараметры.Вставить("БезПодтверждения", Истина); КонецЕсли; Если СерверныеПараметры.Свойство("НаборСертификатов") И ОписаниеДанных.Свойство("БезПодтверждения") И ОписаниеДанных.БезПодтверждения Тогда СерверныеПараметры.Вставить("БезПодтверждения", Истина); КонецЕсли; НастроитьПредставлениеДанных(КлиентскиеПараметры, СерверныеПараметры); Контекст = Новый Структура; Контекст.Вставить("ВидФормы", ВидФормы); Контекст.Вставить("КлиентскиеПараметры", КлиентскиеПараметры); Контекст.Вставить("СерверныеПараметры", СерверныеПараметры); Контекст.Вставить("ОбработкаЗавершения", ОбработкаЗавершения); Если ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() И СерверныеПараметры.Свойство("ВыполнятьНаСервере") И СерверныеПараметры.ВыполнятьНаСервере = Истина Тогда ОткрытьНовуюФормуЗавершение(Новый Массив, Контекст); Иначе ПолучитьОтпечаткиСертификатовНаКлиенте(Новый ОписаниеОповещения( "ОткрытьНовуюФормуЗавершение", ЭтотОбъект, Контекст), ВидФормы = "РасшифровкаДанных"); КонецЕсли; КонецПроцедуры // Продолжение процедуры ОткрытьНовуюФорму. Процедура ОткрытьНовуюФормуЗавершение(ОтпечаткиСертификатовНаКлиенте, Контекст) Экспорт Контекст.СерверныеПараметры.Вставить("ОтпечаткиСертификатовНаКлиенте", ОтпечаткиСертификатовНаКлиенте); ФормаПередачаПараметров().ОткрытьНовуюФорму( Контекст.ВидФормы, Контекст.СерверныеПараметры, Контекст.КлиентскиеПараметры, Контекст.ОбработкаЗавершения); КонецПроцедуры // Только для внутреннего использования. Процедура ОткрытьФормуОповещенияОНеобходимостиЗаменыСертификата(Параметры) Экспорт ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ОповещениеОбОкончанииСрокаДействия", Параметры,,,,,,РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс); КонецПроцедуры // Только для внутреннего использования. Процедура ОбновитьФормуПередПовторнымИспользованием(Форма, КлиентскиеПараметры) Экспорт СерверныеПараметры = Новый Структура; НастроитьПредставлениеДанных(КлиентскиеПараметры, СерверныеПараметры); Форма.ПредставлениеДанных = СерверныеПараметры.ПредставлениеДанных; КонецПроцедуры // Только для внутреннего использования. Процедура НастроитьПредставлениеДанных(КлиентскиеПараметры, СерверныеПараметры) Экспорт ОписаниеДанных = КлиентскиеПараметры.ОписаниеДанных; Если ОписаниеДанных.Свойство("СписокПредставлений") Тогда СписокПредставлений = ОписаниеДанных.СписокПредставлений; Иначе СписокПредставлений = Новый Массив; Если ОписаниеДанных.Свойство("Данные") Или ОписаниеДанных.Свойство("Объект") Тогда ЗаполнитьСписокПредставлений(СписокПредставлений, ОписаниеДанных); Иначе Для каждого ЭлементДанных Из ОписаниеДанных.НаборДанных Цикл ЗаполнитьСписокПредставлений(СписокПредставлений, ЭлементДанных); КонецЦикла; КонецЕсли; КонецЕсли; ТекущийСписокПредставлений = Новый СписокЗначений; Для каждого ЭлементСписка Из СписокПредставлений Цикл Если ТипЗнч(ЭлементСписка) = Тип("Строка") Тогда Представление = ЭлементСписка.Представление; Значение = Неопределено; ИначеЕсли ТипЗнч(ЭлементСписка) = Тип("Структура") Тогда Представление = ЭлементСписка.Представление; Значение = ЭлементСписка.Значение; Иначе // Ссылка Представление = ""; Значение = ЭлементСписка.Значение; КонецЕсли; Если ЗначениеЗаполнено(ЭлементСписка.Представление) Тогда Представление = ЭлементСписка.Представление; Иначе Представление = Строка(ЭлементСписка.Значение); КонецЕсли; ТекущийСписокПредставлений.Добавить(Значение, Представление); КонецЦикла; Если ТекущийСписокПредставлений.Количество() > 1 Тогда СерверныеПараметры.Вставить("ПредставлениеДанныхОткрывается", Истина); СерверныеПараметры.Вставить("ПредставлениеДанных", СтрЗаменить( ОписаниеДанных.ПредставлениеНабора, "%1", ОписаниеДанных.НаборДанных.Количество())); Иначе СерверныеПараметры.Вставить("ПредставлениеДанныхОткрывается", ТипЗнч(ТекущийСписокПредставлений[0].Значение) = Тип("ОписаниеОповещения") Или ЗначениеЗаполнено(ТекущийСписокПредставлений[0].Значение)); СерверныеПараметры.Вставить("ПредставлениеДанных", ТекущийСписокПредставлений[0].Представление); КонецЕсли; КлиентскиеПараметры.Вставить("ТекущийСписокПредставлений", ТекущийСписокПредставлений); КонецПроцедуры // Только для внутреннего использования. Процедура НачалоВыбораСертификатаПриУстановленномОтборе(Форма) Экспорт ДоступныеСертификаты = ""; НедоступныеСертификаты = ""; Текст = НСтр("ru = 'Сертификаты, которые могут быть использованы для этой операции ограничены.'"); Для каждого ЭлементСписка Из Форма.ОтборСертификатов Цикл Если Форма.СертификатСписокВыбора.НайтиПоЗначению(ЭлементСписка.Значение) = Неопределено Тогда НедоступныеСертификаты = НедоступныеСертификаты + Символы.ПС + Строка(ЭлементСписка.Значение); Иначе ДоступныеСертификаты = ДоступныеСертификаты + Символы.ПС + Строка(ЭлементСписка.Значение); КонецЕсли; КонецЦикла; Если ЗначениеЗаполнено(ДоступныеСертификаты) Тогда Заголовок = НСтр("ru = 'Следующие разрешенные сертификаты доступны для выбора:'"); Текст = Текст + Символы.ПС + Символы.ПС + Заголовок + Символы.ПС + СокрЛП(ДоступныеСертификаты); КонецЕсли; Если ЗначениеЗаполнено(НедоступныеСертификаты) Тогда Если ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() Тогда Если ЗначениеЗаполнено(ДоступныеСертификаты) Тогда Заголовок = НСтр("ru = 'Следующие разрешенные сертификаты не установлены ни на компьютере, ни на сервере:'"); Иначе Заголовок = НСтр("ru = 'Ни один из следующих разрешенных сертификатов не установлен ни на компьютере, ни на сервере:'"); КонецЕсли; Иначе Если ЗначениеЗаполнено(ДоступныеСертификаты) Тогда Заголовок = НСтр("ru = 'Следующие разрешенные сертификаты не установлены на компьютере:'"); Иначе Заголовок = НСтр("ru = 'Ни один из следующих разрешенных сертификатов не установлен на компьютере:'"); КонецЕсли; КонецЕсли; Текст = Текст + Символы.ПС + Символы.ПС + Заголовок + Символы.ПС + СокрЛП(НедоступныеСертификаты); КонецЕсли; ПоказатьПредупреждение(, Текст); КонецПроцедуры // Продолжение процедуры ВыборСертификатаДляПодписанияИлиРасшифровки. Процедура ВыборСертификатаДляПодписанияИлиРасшифровкиПродолжение(Результат, Контекст) Экспорт Контекст.СерверныеПараметры.Вставить("СвойстваСертификатовНаКлиенте", Результат.СвойстваСертификатовНаКлиенте); Контекст.СерверныеПараметры.Вставить("ОшибкаПолученияСертификатовНаКлиенте", Результат.ОшибкаПолученияСертификатовНаКлиенте); ФормаПередачаПараметров().ОткрытьНовуюФорму("ВыборСертификатаДляПодписанияИлиРасшифровки", Контекст.СерверныеПараметры, , Контекст.ОбработчикЗавершения, Контекст.ВладелецНовойФормы); КонецПроцедуры // Только для внутреннего использования. Процедура ПроверитьСертификатСправочника(Сертификат, ДополнительныеПараметры) Экспорт СерверныеПараметры = Новый Структура; СерверныеПараметры.Вставить("ЗаголовокФормы"); СерверныеПараметры.Вставить("ПроверкаПриВыборе"); СерверныеПараметры.Вставить("ПараметрыДополнительныхПроверок"); Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда УказанКонтекстДругойОперации = Ложь; Если ДополнительныеПараметры.Свойство("КонтекстОперации") И ТипЗнч(ДополнительныеПараметры.КонтекстОперации) = Тип("ФормаКлиентскогоПриложения") Тогда Если Не ДополнительныеПараметры.Свойство("БезПодтверждения") Тогда ДополнительныеПараметры.Вставить("БезПодтверждения"); КонецЕсли; УказанКонтекстДругойОперации = Истина; ДополнительныеПараметры.БезПодтверждения = Истина; ИначеЕсли ДополнительныеПараметры.Свойство("НеПоказыватьРезультаты") Тогда ДополнительныеПараметры.НеПоказыватьРезультаты = Ложь; КонецЕсли; КлиентскиеПараметры = ДополнительныеПараметры; Если УказанКонтекстДругойОперации Тогда КлиентскиеПараметры.Вставить("УказанКонтекстДругойОперации"); КонецЕсли; ЗаполнитьЗначенияСвойств(СерверныеПараметры, ДополнительныеПараметры); Иначе КлиентскиеПараметры = Новый Структура; КонецЕсли; СерверныеПараметры.Вставить("Сертификат", Сертификат); ВладелецФормы = Неопределено; КлиентскиеПараметры.Свойство("ВладелецФормы", ВладелецФормы); ОбработкаЗавершения = Неопределено; КлиентскиеПараметры.Свойство("ОбработкаЗавершения", ОбработкаЗавершения); ФормаПередачаПараметров().ОткрытьНовуюФорму("ПроверкаСертификата", СерверныеПараметры, КлиентскиеПараметры, ОбработкаЗавершения, ВладелецФормы); КонецПроцедуры // Только для внутреннего использования. Процедура СтандартноеЗавершение(Успех, КлиентскиеПараметры) Экспорт КлиентскиеПараметры.ОписаниеДанных.Вставить("Успех", Успех = Истина); КлиентскиеПараметры.ОписаниеДанных.Вставить("Отказ", Успех = Неопределено); Если КлиентскиеПараметры.ОбработкаРезультата <> Неопределено Тогда ОбработкаРезультата = КлиентскиеПараметры.ОбработкаРезультата; КлиентскиеПараметры.ОбработкаРезультата = Неопределено; ВыполнитьОбработкуОповещения(ОбработкаРезультата, КлиентскиеПараметры.ОписаниеДанных); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьПодписьИзФайла. Процедура ДобавитьПодписьИзФайлаПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если Контекст.ПроверитьМенеджерКриптографииНаКлиенте И ТипЗнч(Результат) <> Тип("МенеджерКриптографии") Тогда ПоказатьОшибкуОбращенияКПрограмме( НСтр("ru = 'Требуется программа электронной подписи и шифрования'"), "", Результат, Контекст.ФормаДобавления.МенеджерКриптографииНаСервереОписаниеОшибки); Иначе Контекст.ФормаДобавления.Открыть(); Если Контекст.ФормаДобавления.Открыта() Тогда Возврат; КонецЕсли; КонецЕсли; Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Контекст.ОписаниеДанных); КонецЕсли; КонецПроцедуры // Предлагает пользователю выбрать подписи для сохранения вместе с данными объекта. // // Общий подход к обработке значений свойств с типом ОписаниеОповещения в параметре ОписаниеДанных. // При выполнении обработки оповещения в нее передается структура параметров, в которой всегда есть // свойство "Оповещение" типа ОписаниеОповещения, обработку которого нужно выполнить для продолжения. // Кроме того, в структуре всегда есть свойство ОписаниеДанных, полученное при вызове процедуры. // При вызове оповещения в качестве значения должна передаваться структура. Если в процессе асинхронного // выполнения возникает ошибка, тогда в эту структуру нужно вставить свойство ОписаниеОшибки типа Строка. // // Параметры: // ОписаниеДанных - Структура: // * ЗаголовокДанных - Строка - заголовок элемента данных, например Файл. // * ПоказатьКомментарий - Булево - (необязательный) - разрешает ввод комментария в форме // добавления подписей. Если не указан, значит Ложь. // * Представление - ЛюбаяСсылка // - Строка - (необязательный), если не указан, тогда // представление вычисляется по значению свойства Объект. // * Объект - ЛюбаяСсылка - ссылка на объект с табличной частью ЭлектронныеПодписи, // из которой нужно получить список подписей. // - Строка - адрес временного хранилища массива подписей с составом свойств, // как возвращает процедура ДобавитьПодписьИзФайла. // * Данные - ОписаниеОповещения - обработчик сохранения данных и получения полного имени // файла с путем (после его сохранения), возвращаемое в свойстве ПолноеИмяФайла // типа Строка для сохранения электронных подписей (смотри выше общий подход). // Если расширение для работы с 1С:Предприятием не подключено, то нужно вернуть // имя файла без пути. // Если свойство не будет вставлено или заполнено - это считается отказом // от продолжения и будет вызвана ОбработкаРезультата с результатом Ложь. // // Для пакетного запроса разрешений у пользователя веб-клиента на сохранение файла данных // и подписей, нужно вставить параметр ОбработкаЗапросаРазрешений типа ОписаниеОповещения. // В процедуру будет передана Структура: // # Вызовы - Массив - с описанием вызовов для сохранения подписей. // # ОбработкаПродолжения - ОписаниеОповещения - оповещение, которое нужно выполнить // после запроса разрешений, - параметры процедуры как у // оповещения для метода НачатьЗапросРазрешенияПользователя. // Если разрешение не получено, значит все отменено. // // ОбработкаРезультата - ОписаниеОповещения - в результат передается параметр: // Булево - Истина, если все прошло успешно. // Процедура СохранитьДанныеВместеСПодписью(ОписаниеДанных, ОбработкаРезультата = Неопределено) Экспорт Контекст = Новый Структура; Контекст.Вставить("ОписаниеДанных", ОписаниеДанных); Контекст.Вставить("ОбработкаРезультата", ОбработкаРезультата); ПерсональныеНастройки = ЭлектроннаяПодписьКлиент.ПерсональныеНастройки(); СохранятьВсеПодписи = ПерсональныеНастройки.ДействияПриСохраненииСЭП = "СохранятьВсеПодписи"; СохранятьСертификатВместеСПодписью = ПерсональныеНастройки.СохранятьСертификатВместеСПодписью; СерверныеПараметры = Новый Структура; СерверныеПараметры.Вставить("ЗаголовокДанных", НСтр("ru = 'Данные'")); СерверныеПараметры.Вставить("ПоказатьКомментарий", Ложь); ЗаполнитьЗначенияСвойств(СерверныеПараметры, ОписаниеДанных); Контекст.Вставить("СохранятьСертификатВместеСПодписью", СохранятьСертификатВместеСПодписью); СерверныеПараметры.Вставить("СохранятьВсеПодписи", СохранятьВсеПодписи); СерверныеПараметры.Вставить("Объект", ОписаниеДанных.Объект); КлиентскиеПараметры = Новый Структура; КлиентскиеПараметры.Вставить("ОписаниеДанных", ОписаниеДанных); НастроитьПредставлениеДанных(КлиентскиеПараметры, СерверныеПараметры); ФормаСохранения = ОткрытьФорму("ОбщаяФорма.СохранениеВместеСЭлектроннойПодписью", СерверныеПараметры,,,,, Новый ОписаниеОповещения("СохранитьДанныеВместеСПодписьюПослеВыбораПодписей", ЭтотОбъект, Контекст)); Завершить = Ложь; Контекст.Вставить("Форма", ФормаСохранения); Если ФормаСохранения = Неопределено Тогда Завершить = Истина; Иначе ФормаСохранения.КлиентскиеПараметры = КлиентскиеПараметры; Если СохранятьВсеПодписи Тогда СохранитьДанныеВместеСПодписьюПослеВыбораПодписей(ФормаСохранения.ТаблицаПодписей, Контекст); Возврат; ИначеЕсли Не ФормаСохранения.Открыта() Тогда Завершить = Истина; КонецЕсли; КонецЕсли; Если Завершить И Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Ложь); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеВыбораПодписей(КоллекцияПодписей, Контекст) Экспорт Если ТипЗнч(КоллекцияПодписей) <> Тип("ДанныеФормыКоллекция") Тогда Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Ложь); КонецЕсли; Возврат; КонецЕсли; Контекст.Вставить("КоллекцияПодписей", КоллекцияПодписей); ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", Контекст.ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "СохранитьДанныеВместеСПодписьюПослеСохраненияФайлаДанных", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(Контекст.ОписаниеДанных.Данные, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); СохранитьДанныеВместеСПодписьюПослеСохраненияФайлаДанных( Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)), Контекст); КонецПопытки; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеСохраненияФайлаДанных(Результат, Контекст) Экспорт Если Результат.Свойство("ОписаниеОшибки") Тогда Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Не удалось записать файл по причине:'") + Символы.ПС + Результат.ОписаниеОшибки); ПоказатьОшибкуОбращенияКПрограмме( НСтр("ru = 'Не удалось сохранить подписи вместе с файлом'"), "", Ошибка, Новый Структура); Возврат; ИначеЕсли Не Результат.Свойство("ПолноеИмяФайла") Или ТипЗнч(Результат.ПолноеИмяФайла) <> Тип("Строка") Или ПустаяСтрока(Результат.ПолноеИмяФайла) Тогда Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Ложь); КонецЕсли; Возврат; КонецЕсли; Если Результат.Свойство("ОбработкаЗапросаРазрешений") Тогда Контекст.Вставить("ОбработкаЗапросаРазрешений", Результат.ОбработкаЗапросаРазрешений); КонецЕсли; Контекст.Вставить("ПолноеИмяФайла", Результат.ПолноеИмяФайла); Контекст.Вставить("СоставИмениФайлаДанных", ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ПолноеИмяФайла)); ФайловаяСистемаКлиент.ПодключитьРасширениеДляРаботыСФайлами(Новый ОписаниеОповещения( "СохранитьДанныеВместеСПодписьюПослеПодключенияРасширенияРаботыСФайлами", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеПодключенияРасширенияРаботыСФайлами(Подключено, Контекст) Экспорт Контекст.Вставить("Подключено", Подключено); Контекст.Вставить("РасширениеДляФайловПодписи", ЭлектроннаяПодписьКлиент.ПерсональныеНастройки().РасширениеДляФайловПодписи); Если Контекст.Подключено Тогда Контекст.Вставить("ПолучаемыеФайлы", Новый Массив); Если ЗначениеЗаполнено(Контекст.СоставИмениФайлаДанных.Путь) Тогда Контекст.Вставить("ПутьКФайлам", ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути( Контекст.СоставИмениФайлаДанных.Путь)); Иначе Контекст.Вставить("ПутьКФайлам", ""); КонецЕсли; КонецЕсли; Контекст.Вставить("ИменаФайлов", Новый Соответствие); Контекст.ИменаФайлов.Вставить(Контекст.СоставИмениФайлаДанных.Имя, Истина); Контекст.Вставить("Индекс", -1); СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. // // Параметры: // Контекст - Структура: // * Индекс - Число // Процедура СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст) Если Контекст.КоллекцияПодписей.Количество() <= Контекст.Индекс + 1 Тогда СохранитьДанныеВместеСПодписьюПослеЦикла(Контекст); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; Контекст.Вставить("ОписаниеПодписи", Контекст.КоллекцияПодписей[Контекст.Индекс]); Если Не Контекст.ОписаниеПодписи.Пометка Тогда СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст); Возврат; КонецЕсли; Контекст.Вставить("ИмяФайлаПодписи", Контекст.ОписаниеПодписи.ИмяФайлаПодписи); Если ПустаяСтрока(Контекст.ИмяФайлаПодписи) Тогда Контекст.ИмяФайлаПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.ИмяФайлаПодписи(Контекст.СоставИмениФайлаДанных.ИмяБезРасширения, Строка(Контекст.ОписаниеПодписи.КомуВыданСертификат), Контекст.РасширениеДляФайловПодписи); Иначе Если Не ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() И СтрДлина(Контекст.ИмяФайлаПодписи) > 127 Тогда СоставИмениФайлаПодписи = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ИмяФайлаПодписи); Контекст.ИмяФайлаПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.ИмяФайлаПодписи( СоставИмениФайлаПодписи.ИмяБезРасширения,"", СоставИмениФайлаПодписи.Расширение, Ложь); Иначе Контекст.ИмяФайлаПодписи = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыВИмениФайла(Контекст.ИмяФайлаПодписи); КонецЕсли; КонецЕсли; СоставИмениФайлаПодписи = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ИмяФайлаПодписи); Контекст.Вставить("ИмяФайлаПодписиБезРасширения", СоставИмениФайлаПодписи.ИмяБезРасширения); Контекст.Вставить("Счетчик", 1); СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст) Контекст.Счетчик = Контекст.Счетчик + 1; Если Контекст.Подключено Тогда Контекст.Вставить("ПолноеИмяФайлаПодписи", Контекст.ПутьКФайлам + Контекст.ИмяФайлаПодписи); Иначе Контекст.Вставить("ПолноеИмяФайлаПодписи", Контекст.ИмяФайлаПодписи); КонецЕсли; Если Контекст.ИменаФайлов[Контекст.ИмяФайлаПодписи] <> Неопределено Тогда СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Истина, Контекст); ИначеЕсли Контекст.Подключено Тогда Файл = Новый Файл(Контекст.ПолноеИмяФайлаПодписи); Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения( "СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла", ЭтотОбъект, Контекст)); Иначе СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Ложь, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Существует, Контекст) Экспорт Если Не Существует Тогда СохранитьДанныеВместеСПодписьюЦиклПослеВнутреннегоЦикла(Контекст); Возврат; КонецЕсли; Контекст.ИмяФайлаПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.ИмяФайлаПодписи(Контекст.ИмяФайлаПодписиБезРасширения, "(" + Строка(Контекст.Счетчик) + ")", Контекст.РасширениеДляФайловПодписи, Ложь); СохранитьДанныеВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. // // Параметры: // Контекст - Структура: // * ПолучаемыеФайлы - Массив // Процедура СохранитьДанныеВместеСПодписьюЦиклПослеВнутреннегоЦикла(Контекст) СоставИмениФайлаПодписи = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ПолноеИмяФайлаПодписи); Контекст.ИменаФайлов.Вставить(СоставИмениФайлаПодписи.Имя, Ложь); Если Контекст.Подключено Тогда Описание = Новый ОписаниеПередаваемогоФайла(СоставИмениФайлаПодписи.Имя, Контекст.ОписаниеПодписи.АдресПодписи); Контекст.ПолучаемыеФайлы.Добавить(Описание); СохранитьДанныеВместеСПодписьюЦиклПослеСохраненияПодписи(Неопределено, Контекст); Иначе // Сохранение файла из программы на компьютер. ФайловаяСистемаКлиент.СохранитьФайл( Новый ОписаниеОповещения("СохранитьДанныеВместеСПодписьюЦиклПослеСохраненияПодписи", ЭтотОбъект, Контекст), Контекст.ОписаниеПодписи.АдресПодписи, СоставИмениФайлаПодписи.Имя); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюЦиклПослеСохраненияПодписи(Результат, Контекст) Экспорт Если Контекст.СохранятьСертификатВместеСПодписью Тогда СохранитьДанныеСертификатаВместеСПодписьюЦиклНачало(Контекст); Иначе СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст) Если Контекст.Подключено Тогда Контекст.Вставить("ПолноеИмяФайлаСертификата", Контекст.ПутьКФайлам + Контекст.ИмяФайлаСертификата); Иначе Контекст.Вставить("ПолноеИмяФайлаСертификата", Контекст.ИмяФайлаСертификата); КонецЕсли; Если Контекст.ИменаФайлов[Контекст.ИмяФайлаСертификата] <> Неопределено Тогда СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Истина, Контекст); ИначеЕсли Контекст.Подключено Тогда Файл = Новый Файл(Контекст.ПолноеИмяФайлаСертификата); Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения( "СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла", ЭтотОбъект, Контекст)); Иначе СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Ложь, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклПослеПроверкиСуществованияФайла(Существует, Контекст) Экспорт Если Не Существует Тогда СохранитьДанныеСертификатаВместеСПодписьюЦиклПослеВнутреннегоЦикла(Контекст); Возврат; КонецЕсли; Контекст.ИмяФайлаСертификата = ЭлектроннаяПодписьСлужебныйКлиентСервер.ИмяФайлаСертификата(Контекст.ИмяФайлаСертификатаБезРасширения, "(" + Строка(Контекст.Счетчик) + ")", Контекст.ОписаниеПодписи.РасширениеСертификата, Ложь); СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеСертификатаВместеСПодписьюЦиклНачало(Контекст) Контекст.Вставить("ИмяФайлаСертификата", ""); Контекст.ИмяФайлаСертификата = ЭлектроннаяПодписьСлужебныйКлиентСервер.ИмяФайлаСертификата(Контекст.СоставИмениФайлаДанных.ИмяБезРасширения, Строка(Контекст.ОписаниеПодписи.КомуВыданСертификат), Контекст.ОписаниеПодписи.РасширениеСертификата); СоставИмениФайлаСертификата = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ИмяФайлаСертификата); Контекст.Вставить("ИмяФайлаСертификатаБезРасширения", СоставИмениФайлаСертификата.ИмяБезРасширения); СохранитьДанныеСертификатаВместеСПодписьюЦиклВнутреннийЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. // // Параметры: // Контекст - Структура: // * ПолучаемыеФайлы - Массив // Процедура СохранитьДанныеСертификатаВместеСПодписьюЦиклПослеВнутреннегоЦикла(Контекст) СоставИмениФайлаСертификата = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(Контекст.ПолноеИмяФайлаСертификата); Контекст.ИменаФайлов.Вставить(СоставИмениФайлаСертификата.Имя, Ложь); Если Контекст.Подключено Тогда Описание = Новый ОписаниеПередаваемогоФайла(СоставИмениФайлаСертификата.Имя, Контекст.ОписаниеПодписи.АдресСертификата); Контекст.ПолучаемыеФайлы.Добавить(Описание); СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст); Иначе // Сохранение файла из программы на компьютер. ФайловаяСистемаКлиент.СохранитьФайл( Новый ОписаниеОповещения("СохранитьДанныеСертификатаВместеСПодписьюЦиклПослеСохраненияСертификата", ЭтотОбъект, Контекст), Контекст.ОписаниеПодписи.АдресСертификата, СоставИмениФайлаСертификата.Имя); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеСертификатаВместеСПодписьюЦиклПослеСохраненияСертификата(Результат, Контекст) Экспорт СохранитьДанныеВместеСПодписьюЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеЦикла(Контекст) Если Не Контекст.Подключено Тогда Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Истина); КонецЕсли; Возврат; КонецЕсли; // Сохранение файла из программы на компьютер. Если Контекст.ПолучаемыеФайлы.Количество() > 0 Тогда Контекст.Вставить("ПолучаемыеФайлы", Контекст.ПолучаемыеФайлы); Вызовы = Новый Массив; Вызов = Новый Массив; Вызов.Добавить("НачатьПолучениеФайлов"); Вызов.Добавить(Контекст.ПолучаемыеФайлы); Вызов.Добавить(Контекст.ПутьКФайлам); Вызов.Добавить(Ложь); Вызовы.Добавить(Вызов); ОбработкаПродолжения = Новый ОписаниеОповещения( "СохранитьДанныеВместеСПодписьюПослеПолученияРазрешений", ЭтотОбъект, Контекст); Если Контекст.Свойство("ОбработкаЗапросаРазрешений") Тогда ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("Вызовы", Вызовы); ПараметрыВыполнения.Вставить("ОбработкаПродолжения", ОбработкаПродолжения); ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗапросаРазрешений, ПараметрыВыполнения); Иначе НачатьЗапросРазрешенияПользователя(ОбработкаПродолжения, Вызовы); КонецЕсли; Иначе СохранитьДанныеВместеСПодписьюПослеПолученияРазрешений(Ложь, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеПолученияРазрешений(РазрешенияПолучены, Контекст) Экспорт Если Не РазрешенияПолучены И Контекст.ПолучаемыеФайлы.Количество() > 0 И Контекст.Свойство("ОбработкаЗапросаРазрешений") Тогда // Файл данных не был получен - отчет не требуется. Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Ложь); КонецЕсли; ИначеЕсли РазрешенияПолучены Тогда ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайлов(); ПараметрыСохранения.Интерактивно = Не ЗначениеЗаполнено(Контекст.ПутьКФайлам); ПараметрыСохранения.Диалог.Каталог = Контекст.ПутьКФайлам; ФайловаяСистемаКлиент.СохранитьФайлы(Новый ОписаниеОповещения( "СохранитьДанныеВместеСПодписьюПослеПолученияФайлов", ЭтотОбъект, Контекст), Контекст.ПолучаемыеФайлы, ПараметрыСохранения); Иначе СохранитьДанныеВместеСПодписьюПослеПолученияФайлов(Неопределено, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. // // Параметры: // ПолученныеФайлы - Массив из ОписаниеПередаваемогоФайла // Процедура СохранитьДанныеВместеСПодписьюПослеПолученияФайлов(ПолученныеФайлы, Контекст) Экспорт ИменаПолученныхФайлов = Новый Соответствие; ИменаПолученныхФайлов.Вставить(Контекст.СоставИмениФайлаДанных.Имя, Истина); Если ТипЗнч(ПолученныеФайлы) = Тип("Массив") Тогда Для каждого ПолученныйФайл Из ПолученныеФайлы Цикл СоставИмениФайлаПодписи = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(ПолученныйФайл.ПолноеИмя); ИменаПолученныхФайлов.Вставить(СоставИмениФайлаПодписи.Имя, Истина); Если Не ЗначениеЗаполнено(Контекст.ПутьКФайлам) Тогда Контекст.ПутьКФайлам = СоставИмениФайлаПодписи.Путь; КонецЕсли; КонецЦикла; КонецЕсли; Текст = НСтр("ru = 'Папка с файлами:'") + Символы.ПС + Контекст.ПутьКФайлам + Символы.ПС + Символы.ПС + НСтр("ru = 'Файлы:'") + Символы.ПС; Для Каждого КлючИЗначение Из ИменаПолученныхФайлов Цикл Текст = Текст + КлючИЗначение.Ключ + Символы.ПС; КонецЦикла; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Текст", Текст); Если Не ЗначениеЗаполнено(Контекст.СоставИмениФайлаДанных.Путь) Тогда ПараметрыФормы.Вставить("КаталогСФайлами", Контекст.ПутьКФайлам); Иначе ПараметрыФормы.Вставить("КаталогСФайлами", Контекст.СоставИмениФайлаДанных.Путь); КонецЕсли; ОткрытьФорму("ОбщаяФорма.ОтчетОСохраненииФайловЭлектронныхПодписей", ПараметрыФормы,,,,, Новый ОписаниеОповещения("СохранитьДанныеВместеСПодписьюПослеЗакрытияОтчета", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.СохранитьДанныеВместеСПодписью. Процедура СохранитьДанныеВместеСПодписьюПослеЗакрытияОтчета(Результат, Контекст) Экспорт Если Контекст.ОбработкаРезультата <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, Истина); КонецЕсли; КонецПроцедуры // Только для внутреннего использования. Процедура ОткрытьИнструкциюПоРаботеСПрограммами() Экспорт Раздел = "БухгалтерскийИНалоговыйУчет"; ЭлектроннаяПодписьКлиентПереопределяемый.ПриОпределенииРазделаСтатьиНаИТС(Раздел); НавигационнаяСсылка = ""; ЭлектроннаяПодписьКлиентСерверЛокализация.ПриОпределенииСсылкиНаИнструкциюПоРаботеСПрограммами( Раздел, НавигационнаяСсылка); Если Не ПустаяСтрока(НавигационнаяСсылка) Тогда ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(НавигационнаяСсылка); КонецЕсли; КонецПроцедуры // См. ЭлектроннаяПодписьКлиент.УстановитьРасширение Процедура УстановитьРасширение(БезВопроса, ОбработчикРезультата = Неопределено, ТекстВопроса = "", ЗаголовокВопроса = "") Экспорт Контекст = Новый Структура; Контекст.Вставить("Оповещение", ОбработчикРезультата); Контекст.Вставить("ТекстВопроса", ТекстВопроса); Контекст.Вставить("ЗаголовокВопроса", ЗаголовокВопроса); Контекст.Вставить("БезВопроса", БезВопроса); НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "УстановитьРасширениеПослеПроверкиПодключенияРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры УстановитьРасширение. Процедура УстановитьРасширениеПослеПроверкиПодключенияРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт Если Подключено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина); Возврат; КонецЕсли; НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "УстановитьРасширениеПослеПодключенияРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры УстановитьРасширение. Процедура УстановитьРасширениеПослеПодключенияРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт Если Подключено Тогда Если Контекст.Оповещение <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина); КонецЕсли; Возврат; КонецЕсли; Обработчик = Новый ОписаниеОповещения("УстановитьРасширениеПослеОтвета", ЭтотОбъект, Контекст); Если Контекст.БезВопроса Тогда ВыполнитьОбработкуОповещения(Обработчик, КодВозвратаДиалога.Да); Возврат; КонецЕсли; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ЗаголовокВопроса", Контекст.ЗаголовокВопроса); ПараметрыФормы.Вставить("ТекстВопроса", Контекст.ТекстВопроса); ОткрытьФорму("ОбщаяФорма.ВопросОбУстановкеРасширенияРаботыСКриптографией", ПараметрыФормы,,,,, Обработчик); КонецПроцедуры // Продолжение процедуры УстановитьРасширение. Процедура УстановитьРасширениеПослеОтвета(Ответ, Контекст) Экспорт Если Ответ = КодВозвратаДиалога.Да Тогда НачатьУстановкуРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "УстановитьРасширениеПослеУстановкиРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); Иначе Если Контекст.Оповещение <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Неопределено); КонецЕсли; КонецЕсли; КонецПроцедуры // Продолжение процедуры УстановитьРасширение. Процедура УстановитьРасширениеПослеУстановкиРасширенияРаботыСКриптографией(Контекст) Экспорт НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "УстановитьРасширениеПослеПодключенияУстановленногоРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры УстановитьРасширение. Процедура УстановитьРасширениеПослеПодключенияУстановленногоРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт Если Подключено Тогда Оповестить("Установка_РасширениеРаботыСКриптографией"); КонецЕсли; Если Контекст.Оповещение <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Подключено); КонецЕсли; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Общие процедуры и функции управляемых форм. // Только для внутреннего использования. Процедура ПродолжитьОткрытиеНачало(Оповещение, Форма, КлиентскиеПараметры, Шифрование = Ложь, Расшифровка = Ложь) Экспорт Если Не Шифрование Тогда ВходныеПараметры = Неопределено; КлиентскиеПараметры.ОписаниеДанных.Свойство("ПараметрыДополнительныхДействий", ВходныеПараметры); ВыходныеПараметры = Форма.ВыходныеПараметрыДополнительныхДействий; Форма.ВыходныеПараметрыДополнительныхДействий = Неопределено; ЭлектроннаяПодписьКлиентПереопределяемый.ПередНачаломОперации( ?(Расшифровка, "Расшифровка", "Подписание"), ВходныеПараметры, ВыходныеПараметры); КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ОшибкаНаСервере", Новый Структура); Если ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() Тогда Если Не ЗначениеЗаполнено(Форма.МенеджерКриптографииНаСервереОписаниеОшибки) Тогда ВыполнитьОбработкуОповещения(Оповещение, Истина); Возврат; КонецЕсли; Контекст.ОшибкаНаСервере = Форма.МенеджерКриптографииНаСервереОписаниеОшибки; КонецЕсли; ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Неопределено; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПродолжитьОткрытиеНачалоПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПолучениеСертификатов", ПараметрыСоздания); КонецПроцедуры // Продолжение процедуры ПродолжитьОткрытиеНачало. Процедура ПродолжитьОткрытиеНачалоПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") И Не ИспользоватьЭлектроннуюПодписьВМоделиСервиса() И Не ИспользоватьСервисОблачнойПодписи() Тогда ПоказатьОшибкуОбращенияКПрограмме( НСтр("ru = 'Требуется программа электронной подписи и шифрования'"), "", Результат, Контекст.ОшибкаНаСервере); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Ложь); Возврат; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина); КонецПроцедуры // Только для внутреннего использования. Процедура ПолучитьОтпечаткиСертификатовНаКлиенте(Оповещение, ВключаяПросроченные = Ложь) Экспорт Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ВключаяПросроченные", ВключаяПросроченные); ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Ложь; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ПолучитьОтпечаткиСертификатовНаКлиентеПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПолучениеСертификатов", ПараметрыСоздания); КонецПроцедуры // Продолжение процедуры ПолучитьОтпечаткиСертификатовНаКлиенте. Процедура ПолучитьОтпечаткиСертификатовНаКлиентеПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст) Экспорт Если ТипЗнч(МенеджерКриптографии) <> Тип("МенеджерКриптографии") Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Новый Массив); Возврат; КонецЕсли; МенеджерКриптографии.НачатьПолучениеХранилищаСертификатов( Новый ОписаниеОповещения( "ПолучитьОтпечаткиСертификатовНаКлиентеПослеПолученияХранилища", ЭтотОбъект, Контекст), ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты); КонецПроцедуры // Продолжение процедуры ПолучитьОтпечаткиСертификатовНаКлиенте. Процедура ПолучитьОтпечаткиСертификатовНаКлиентеПослеПолученияХранилища(ХранилищеСертификатовКриптографии, Контекст) Экспорт ХранилищеСертификатовКриптографии.НачатьПолучениеВсех(Новый ОписаниеОповещения( "ПолучитьОтпечаткиСертификатовНаКлиентеПослеПолученияВсех", ЭтотОбъект, Контекст)); КонецПроцедуры // Продолжение процедуры ПолучитьОтпечаткиСертификатовНаКлиенте. Процедура ПолучитьОтпечаткиСертификатовНаКлиентеПослеПолученияВсех(МассивСертификатов, Контекст) Экспорт ОтпечаткиСертификатовНаКлиенте = Новый Массив; ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьОтпечаткиСертификатов(ОтпечаткиСертификатовНаКлиенте, МассивСертификатов, ДобавкаВремени(), ?(Контекст.ВключаяПросроченные, Неопределено, ОбщегоНазначенияКлиент.ДатаСеанса())); ВыполнитьОбработкуОповещения(Контекст.Оповещение, ОтпечаткиСертификатовНаКлиенте); КонецПроцедуры // Только для внутреннего использования. // // Параметры: // Форма - ФормаКлиентскогоПриложения // Процедура ОбработатьПарольВФорме(Форма, ВнутренниеДанные, СвойстваПароля, ДополнительныеПараметры = Неопределено, НовыйПароль = Null) Экспорт Если ТипЗнч(СвойстваПароля) <> Тип("Структура") Тогда СвойстваПароля = Новый Структура; СвойстваПароля.Вставить("Значение", Неопределено); СвойстваПароля.Вставить("ОбработкаПоясненияПароля", Неопределено); // Свойство ПарольПроверен разрешает запоминание без проверки. // Включается когда указан НовыйПароль и при успешном выполнении операции. СвойстваПароля.Вставить("ПарольПроверен", Ложь); КонецЕсли; Если ДополнительныеПараметры = Неопределено Тогда ДополнительныеПараметры = Новый Структура; КонецЕсли; ДополнительныеПараметры.Вставить("Сертификат", Форма.Сертификат); ДополнительныеПараметры.Вставить("ВводитьПарольВПрограммеЭлектроннойПодписи", Форма.СертификатВводитьПарольВПрограммеЭлектроннойПодписи); Если Не ДополнительныеПараметры.Свойство("ПриУстановкеПароляИзДругойОперации") Тогда ДополнительныеПараметры.Вставить("ПриУстановкеПароляИзДругойОперации", Ложь); КонецЕсли; Если Не ДополнительныеПараметры.Свойство("ПриИзмененииРеквизитаПароль") Тогда ДополнительныеПараметры.Вставить("ПриИзмененииРеквизитаПароль", Ложь); КонецЕсли; Если Не ДополнительныеПараметры.Свойство("ПриИзмененииРеквизитаЗапомнитьПароль") Тогда ДополнительныеПараметры.Вставить("ПриИзмененииРеквизитаЗапомнитьПароль", Ложь); КонецЕсли; Если Не ДополнительныеПараметры.Свойство("ПриУспешномВыполненииОперации") Тогда ДополнительныеПараметры.Вставить("ПриУспешномВыполненииОперации", Ложь); КонецЕсли; Если Не ДополнительныеПараметры.Свойство("ПриИзмененииСвойствСертификата") Тогда ДополнительныеПараметры.Вставить("ПриИзмененииСвойствСертификата", Ложь); КонецЕсли; ДополнительныеПараметры.Вставить("ПарольВПамяти", Ложь); ДополнительныеПараметры.Вставить("ПарольУстановленПрограммно", Ложь); ДополнительныеПараметры.Вставить("ПояснениеПароля"); ОбработатьПароль(ВнутренниеДанные, Форма.Пароль, СвойстваПароля, Форма.ЗапомнитьПароль, ДополнительныеПараметры, НовыйПароль); Элементы = Форма.Элементы; Если Элементы.Найти("Страницы") = Неопределено Или Элементы.Найти("СтраницаПояснениеУсиленногоПароля") = Неопределено Тогда Возврат; КонецЕсли; ТекущиеСвойства = Новый Структура("ВыполнятьВМоделиСервиса", Ложь); ЗаполнитьЗначенияСвойств(ТекущиеСвойства, Форма); ЭлементПароль = Элементы.Пароль; // ПолеФормы ЭлементЗапомнитьПароль = Элементы.ЗапомнитьПароль; Если ТекущиеСвойства.ВыполнятьВМоделиСервиса И ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда ЭлементПароль.Доступность = Ложь; ЭлементЗапомнитьПароль.Доступность = Ложь; Элементы.Страницы.Видимость = Истина; Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаПояснениеУсиленногоПароля; Элементы.ПояснениеУсиленногоПароля.Подсказка = НСтр("ru = 'Сервис вышлет одноразовый пароль по SMS или E-Mail, |который нужно будет ввести после получения.'"); ИначеЕсли ДополнительныеПараметры.ВводитьПарольВПрограммеЭлектроннойПодписи Тогда ЭлементПароль.Доступность = Ложь; ЭлементЗапомнитьПароль.Доступность = Ложь; Элементы.Страницы.Видимость = Истина; Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаПояснениеУсиленногоПароля; Элементы.ПояснениеУсиленногоПароля.Подсказка = НСтр("ru = 'Для выбранного сертификата указано ""Вводить пароль в программе электронной подписи"".'"); Иначе Если ДополнительныеПараметры.ПарольУстановленПрограммно Тогда Элементы.Страницы.Видимость = Истина; Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаПояснениеУстановленногоПароля; ПояснениеПароля = ДополнительныеПараметры.ПояснениеПароля; Элементы.ПояснениеУстановленногоПароля.Заголовок = ПояснениеПароля.ТекстПояснения; Элементы.ПояснениеУстановленногоПароля.Гиперссылка = ПояснениеПароля.ПояснениеГиперссылка; ЭлементПояснениеУстановленногоПароляРасширеннаяПодсказка = Элементы.ПояснениеУстановленногоПароляРасширеннаяПодсказка; // ПолеФормы ЭлементПояснениеУстановленногоПароляРасширеннаяПодсказка.Заголовок = ПояснениеПароля.ТекстПодсказки; СвойстваПароля.ОбработкаПоясненияПароля = ПояснениеПароля.ОбработкаДействия; ЭлементПароль.Доступность = Истина; ЭлементЗапомнитьПароль.Доступность = Истина; Иначе ЭлементПароль.Доступность = Не ДополнительныеПараметры.ПарольВПамяти; ЭлементЗапомнитьПароль.Доступность = Не ДополнительныеПараметры.ПарольВПамяти; Если Элементы.Найти("СтраницаЗапоминаниеПароля") = Неопределено Тогда Элементы.Страницы.Видимость = Ложь; Иначе Элементы.Страницы.Видимость = Истина; Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаЗапоминаниеПароля; КонецЕсли; КонецЕсли; КонецЕсли; ДополнительныеПараметры.Вставить("ПарольУказан", ДополнительныеПараметры.ПарольУстановленПрограммно Или ДополнительныеПараметры.ПарольВПамяти Или ДополнительныеПараметры.ПриУстановкеПароляИзДругойОперации); ЗначенияФормы = ПолучитьДанныеОблачнойПодписи(Форма, "ДанныеСертификата"); Если ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ДополнительныеПараметры, "ПриОткрытии", Ложь) И ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ЗначенияФормы, "Облачный", Ложь) Тогда УбратьПароль = ДополнительныеПараметры.ПарольВПамяти; Элементы.Страницы.Видимость = НЕ УбратьПароль; ЭлементПароль.Видимость = НЕ УбратьПароль; КонецЕсли; КонецПроцедуры // Только для внутреннего использования. Процедура ПояснениеУстановленногоПароляНажатие(Форма, Элемент, СвойстваПароля) Экспорт Если ТипЗнч(СвойстваПароля.ОбработкаПоясненияПароля) = Тип("ОписаниеОповещения") Тогда Результат = Новый Структура; Результат.Вставить("Сертификат", Форма.Сертификат); Результат.Вставить("Действие", "ПояснениеНажатие"); ВыполнитьОбработкуОповещения(СвойстваПароля.ОбработкаПоясненияПароля, Результат); КонецЕсли; КонецПроцедуры // Только для внутреннего использования. Процедура ПояснениеУстановленногоПароляОбработкаНавигационнойСсылки(Форма, Элемент, НавигационнаяСсылка, СтандартнаяОбработка, СвойстваПароля) Экспорт СтандартнаяОбработка = Ложь; Если ТипЗнч(СвойстваПароля.ОбработкаПоясненияПароля) = Тип("ОписаниеОповещения") Тогда Результат = Новый Структура; Результат.Вставить("Сертификат", Форма.Сертификат); Результат.Вставить("Действие", НавигационнаяСсылка); ВыполнитьОбработкуОповещения(СвойстваПароля.ОбработкаПоясненияПароля, Результат); КонецЕсли; КонецПроцедуры // Только для внутреннего использования. Процедура ПредставлениеДанныхНажатие(Форма, Элемент, СтандартнаяОбработка, ТекущийСписокПредставлений) Экспорт СтандартнаяОбработка = Ложь; Если ТекущийСписокПредставлений.Количество() > 1 Тогда СписокПредставленийДанных = Новый Массив; Для Каждого ЭлементСписка Из ТекущийСписокПредставлений Цикл СписокПредставленийДанных.Добавить(ЭлементСписка.Представление); КонецЦикла; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("СписокПредставленийДанных", СписокПредставленийДанных); ПараметрыФормы.Вставить("ПредставлениеДанных", Форма.ПредставлениеДанных); НоваяФорма = ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ПросмотрДанных", ПараметрыФормы, Элемент); Если НоваяФорма = Неопределено Тогда Возврат; КонецЕсли; НоваяФорма.УстановитьСписокПредставлений(ТекущийСписокПредставлений, Неопределено); Иначе Значение = ТекущийСписокПредставлений[0].Значение; Если ТипЗнч(Значение) = Тип("ОписаниеОповещения") Тогда ВыполнитьОбработкуОповещения(Значение); Иначе ПоказатьЗначение(, Значение); КонецЕсли; КонецЕсли; КонецПроцедуры // Только для внутреннего использования. // // Параметры: // Форма - ФормаКлиентскогоПриложения // Функция ПолноеПредставлениеДанных(Форма) Экспорт Элементы = Форма.Элементы; ЭлементПредставлениеДанных = Элементы.ПредставлениеДанных; // ПолеФормы Если Элементы.ПредставлениеДанных.ПоложениеЗаголовка <> ПоложениеЗаголовкаЭлементаФормы.Нет И ЗначениеЗаполнено(ЭлементПредставлениеДанных.Заголовок) Тогда Возврат ЭлементПредставлениеДанных.Заголовок + ": " + Форма.ПредставлениеДанных; Иначе Возврат Форма.ПредставлениеДанных; КонецЕсли; КонецФункции // Только для внутреннего использования. Процедура СертификатПодборИзСпискаВыбора(Форма, Текст, ДанныеВыбора, СтандартнаяОбработка) Экспорт Если Текст = "" И Форма.СертификатСписокВыбора.Количество() = 0 Тогда Возврат; КонецЕсли; СтандартнаяОбработка = Ложь; ДанныеВыбора = Новый СписокЗначений; Для каждого ЭлементСписка Из Форма.СертификатСписокВыбора Цикл Если СтрНайти(ВРег(ЭлементСписка.Представление), ВРег(Текст)) > 0 Тогда ДанныеВыбора.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление); КонецЕсли; КонецЦикла; КонецПроцедуры // Только для внутреннего использования. Асинх Процедура ВыполнитьНаСтороне(Оповещение, Операция, СторонаВыполнения, ПараметрыВыполнения) Экспорт Контекст = ВыполнитьНаСторонеНовыйКонтекст(); ЗаполнитьЗначенияСвойств(Контекст, ПараметрыВыполнения); СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(Контекст.ОписаниеДанных); ИспользоватьОблачнуюПодпись = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыВыполнения, "ИспользоватьОблачнуюПодпись", Истина); Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("Операция", Операция); // Подписание, Шифрование, Расшифровка. Контекст.Вставить("НаСторонеКлиента", СторонаВыполнения = "НаСторонеКлиента"); Контекст.Вставить("ОперацияНачалась", Ложь); Контекст.Вставить("ИспользоватьОблачнуюПодпись", ИспользоватьОблачнуюПодпись); Если Контекст.НаСторонеКлиента Тогда Если ЗначениеЗаполнено(СвойстваОблачнойПодписи.УчетнаяЗапись) Тогда Контекст.Вставить("МенеджерКриптографии", "ОблачнаяПодпись"); ВыполнитьНаСторонеОблачнойПодписи(Контекст); ИначеЕсли Контекст.Операция = "Шифрование" И ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда Контекст.Вставить("МенеджерКриптографии", "СервисКриптографии"); ВыполнитьНаСторонеВМоделиСервиса(Null, Контекст); ИначеЕсли (Контекст.Операция = "Расшифровка" Или Контекст.Операция = "Подписание") И ИспользоватьЭлектроннуюПодписьВМоделиСервиса() И Контекст.Форма.ВыполнятьВМоделиСервиса Тогда Контекст.Вставить("МенеджерКриптографии", "СервисКриптографии"); ВыполнитьНаСторонеВМоделиСервиса(Null, Контекст); Иначе Если ЗначениеЗаполнено(Контекст.Форма.СертификатПрограмма) Тогда Программа = Контекст.Форма.СертификатПрограмма; Иначе Если Операция = "Подписание" Или Операция = "Расшифровка" Тогда ТребуетсяЗакрытыйКлюч = Истина; Иначе ТребуетсяЗакрытыйКлюч = Неопределено; КонецЕсли; ПрограммаПоСертификатуРезультат = Ждать ПрограммаПоСертификату( ПараметрыВыполнения.СертификатАдрес, ТребуетсяЗакрытыйКлюч, Неопределено, Истина); Если ЗначениеЗаполнено(ПрограммаПоСертификатуРезультат.Программа) Тогда Программа = ПрограммаПоСертификатуРезультат.Программа; Иначе ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ПрограммаПоСертификатуРезультат.Ошибка); ОшибкаНаКлиенте.Вставить("Инструкция", Истина); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Возврат; КонецЕсли; КонецЕсли; ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Неопределено; ПараметрыСоздания.Программа = Программа; ПараметрыСоздания.ИнтерактивныйРежим = Контекст.Форма.СертификатВводитьПарольВПрограммеЭлектроннойПодписи; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "ВыполнитьНаСторонеПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), Операция, ПараметрыСоздания); КонецЕсли; Иначе ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") Тогда Если Контекст.Операция = "Шифрование" И ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Контекст, "ИспользоватьОблачнуюПодпись", Истина) = Истина И ШифроватьДанныеОблачнойПодписью() Тогда Контекст.Вставить("МенеджерКриптографии", "ОблачнаяПодпись"); ВыполнитьНаСторонеОблачнойПодписи(Контекст); Иначе ВыполнитьОбработкуОповещения(Контекст.Оповещение, Новый Структура("Ошибка", Результат)); Возврат; КонецЕсли; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", Результат); // Если личный сертификат шифрования не используется, тогда его не нужно искать. Если Контекст.Операция <> "Шифрование" Или ЗначениеЗаполнено(Контекст.Форма.СертификатОтпечаток) Тогда ПолучитьСертификатПоОтпечатку(Новый ОписаниеОповещения( "ВыполнитьНаСторонеПослеПоискаСертификата", ЭтотОбъект, Контекст), Контекст.Форма.СертификатОтпечаток, Истина, Неопределено, ?(ТипЗнч(Результат) <> Тип("МенеджерКриптографии"), Контекст.Форма.СертификатПрограмма, Результат)); Иначе ВыполнитьНаСторонеПослеПоискаСертификата(Null, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // Контекст - Структура: // * СертификатКриптографии - СертификатКриптографии // Процедура ВыполнитьНаСторонеПослеПоискаСертификата(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("СертификатКриптографии") И Результат <> Null Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Новый Структура("Ошибка", Результат)); Возврат; КонецЕсли; Контекст.Вставить("СертификатКриптографии", Результат); Если Контекст.Операция = "Подписание" Тогда Если Не ИспользуетсяИнтерактивныйРежимКриптографии(Контекст.МенеджерКриптографии) Тогда Контекст.МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = Контекст.ЗначениеПароля; КонецЕсли; Контекст.Удалить("ЗначениеПароля"); Контекст.СертификатКриптографии.НачатьВыгрузку(Новый ОписаниеОповещения( "ВыполнитьНаСторонеПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); ИначеЕсли Контекст.Операция = "Шифрование" Тогда СвойстваСертификатов = Контекст.ОписаниеДанных.СертификатыШифрования; Если ТипЗнч(СвойстваСертификатов) = Тип("Строка") Тогда СвойстваСертификатов = ПолучитьИзВременногоХранилища(СвойстваСертификатов); КонецЕсли; Контекст.Вставить("Индекс", -1); Контекст.Вставить("СвойстваСертификатов", СвойстваСертификатов); Контекст.Вставить("СертификатыШифрования", Новый Массив); ВыполнитьНаСторонеПодготовкаСертификатовЦиклНачало(Контекст); Возврат; Иначе Если Не ИспользуетсяИнтерактивныйРежимКриптографии(Контекст.МенеджерКриптографии) Тогда Контекст.МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = Контекст.ЗначениеПароля; КонецЕсли; Контекст.Удалить("ЗначениеПароля"); ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // Контекст - Структура // Процедура ВыполнитьНаСторонеПодготовкаСертификатовЦиклНачало(Контекст) Если Контекст.СвойстваСертификатов.Количество() <= Контекст.Индекс + 1 Тогда ВыполнитьНаСторонеЦиклЗапуск(Контекст); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; СертификатКриптографии = Новый СертификатКриптографии; СертификатКриптографии.НачатьИнициализацию(Новый ОписаниеОповещения( "ВыполнитьНаСторонеПодготовкаСертификатовПослеИнициализацииСертификата", ЭтотОбъект, Контекст), Контекст.СвойстваСертификатов[Контекст.Индекс].Сертификат); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // Контекст - Структура: // * СертификатыШифрования - Массив // Процедура ВыполнитьНаСторонеПодготовкаСертификатовПослеИнициализацииСертификата(СертификатКриптографии, Контекст) Экспорт Контекст.СертификатыШифрования.Добавить(СертификатКриптографии); ВыполнитьНаСторонеПодготовкаСертификатовЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Асинх Процедура ВыполнитьНаСторонеПослеВыгрузкиСертификата(ВыгруженныеДанные, Контекст) Экспорт Контекст.Вставить("СвойстваСертификата", Ждать СвойстваСертификата( Контекст.СертификатКриптографии)); Контекст.СвойстваСертификата.Вставить("ДвоичныеДанные", ВыгруженныеДанные); ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклЗапуск(Контекст) Если Контекст.ОписаниеДанных.Свойство("Данные") Тогда ЭлементыДанных = Новый Массив; ЭлементыДанных.Добавить(Контекст.ОписаниеДанных); Иначе ЭлементыДанных = Контекст.ОписаниеДанных.НаборДанных; КонецЕсли; Контекст.Вставить("ЭлементыДанных", ЭлементыДанных); Контекст.Вставить("Индекс", -1); ВыполнитьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклНачало(Контекст) Если Контекст.ЭлементыДанных.Количество() <= Контекст.Индекс + 1 Тогда ВыполнитьНаСторонеПослеЦикла(Неопределено, Контекст); Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклНачалоПродолжение", ЭтотОбъект, Контекст); СтандартныеПодсистемыКлиент.НачатьВыполнениеОбработкиОповещения(Оповещение); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // Результат - Число // Контекст - см. ВыполнитьНаСторонеНовыйКонтекст // Процедура ВыполнитьНаСторонеЦиклНачалоПродолжение(Результат, Контекст) Экспорт Контекст.Индекс = Контекст.Индекс + 1; Контекст.Вставить("ЭлементДанных", Контекст.ЭлементыДанных[Контекст.Индекс]); Если Не Контекст.ОписаниеДанных.Свойство("Данные") Тогда Контекст.ОписаниеДанных.Вставить("ТекущийЭлементНабораДанных", Контекст.ЭлементДанных); КонецЕсли; Если Контекст.Операция = "Подписание" И Контекст.ЭлементДанных.Свойство("СвойстваПодписи") Или Контекст.Операция = "Шифрование" И Контекст.ЭлементДанных.Свойство("ЗашифрованныеДанные") Или Контекст.Операция = "Расшифровка" И Контекст.ЭлементДанных.Свойство("РасшифрованныеДанные") Тогда ВыполнитьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; ПолучитьДанныеИзОписанияДанных(Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеПолученияДанных", ЭтотОбъект, Контекст), Контекст.Форма, Контекст.ОписаниеДанных, Контекст.ЭлементДанных.Данные, Контекст.НаСторонеКлиента); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеОперацииНаКлиентеXMLDSig(КонвертXML, Контекст) Экспорт Контекст.ОперацияНачалась = Истина; СвойстваПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваПодписи(КонвертXML, Контекст.СвойстваСертификата, Контекст.Форма.Комментарий, ПользователиКлиент.АвторизованныйПользователь()); Если Контекст.СертификатВерен <> Неопределено Тогда СвойстваПодписи.ДатаПодписи = ОбщегоНазначенияКлиент.ДатаСеанса(); СвойстваПодписи.ДатаПроверкиПодписи = СвойстваПодписи.ДатаПодписи; СвойстваПодписи.ПодписьВерна = Контекст.СертификатВерен; КонецЕсли; СвойстваПодписи.ТребуетсяПроверка = Контекст.ТребуетсяПроверка; ВыполнитьНаСторонеЦиклПослеПодписания(СвойстваПодписи, Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиентеXMLDSig(ТекстОшибки, Контекст) Экспорт ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ТекстОшибки); ОшибкаНаКлиенте.Вставить("Инструкция", Истина); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // Результат - ДвоичныеДанные // - Строка // - Структура // Контекст - см. ВыполнитьНаСторонеНовыйКонтекст // Процедура ВыполнитьНаСторонеЦиклПослеПолученияДанных(Результат, Контекст) Экспорт ТипРезультата = ТипЗнч(Результат); Если ТипРезультата <> Тип("Строка") И ТипРезультата <> Тип("ДвоичныеДанные") И ТипРезультата <> Тип("Структура") Тогда Ошибка = Новый Структура("ОписаниеОшибки", ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаголовокОшибкиПолученияДанных(Контекст.Операция) + Символы.ПС + НСтр("ru = 'Некорректный тип данных: %1'")); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; ЭтоXMLDSig = (ТипРезультата = Тип("Структура") И Результат.Свойство("ПараметрыXMLDSig")); ЭтоCMS = (ТипРезультата = Тип("Структура") И Результат.Свойство("ПараметрыCMS")); Если ЭтоXMLDSig И Не Результат.Свойство("КонвертXML") Тогда Результат = Новый Структура(Новый ФиксированнаяСтруктура(Результат)); Результат.Вставить("КонвертXML", Результат.КонвертSOAP); КонецЕсли; Если ТипРезультата = Тип("Структура") И Не ЭтоXMLDSig И Не ЭтоCMS Тогда Ошибка = Новый Структура("ОписаниеОшибки", ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаголовокОшибкиПолученияДанных(Контекст.Операция) + Символы.ПС + Результат.ОписаниеОшибки); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Данные = Результат; Если Контекст.НаСторонеКлиента Тогда МенеджерКриптографии = Контекст.МенеджерКриптографии; ПараметрыОперации = Новый Структура; ПараметрыОперации.Вставить("Операция", Контекст.ОписаниеДанных.Операция); ПараметрыОперации.Вставить("ЗаголовокДанных", Контекст.ОписаниеДанных.ЗаголовокДанных); Если ЭтоXMLDSig Тогда Если Контекст.Операция <> "Подписание" Тогда Ошибка = Новый Структура("ОписаниеОшибки", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Внешняя компонента %1 может использоваться только для подписания.'"), "ExtraCryptoAPI")); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; ОповещениеУспех = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОперацииНаКлиентеXMLDSig", ЭтотОбъект, Контекст); ОповещениеОшибка = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиентеXMLDSig", ЭтотОбъект, Контекст); Оповещения = Новый Структура; Оповещения.Вставить("Успех", ОповещениеУспех); Оповещения.Вставить("Ошибка", ОповещениеОшибка); НачатьВыгрузкуСертификатаКриптографииДляПодписанияXMLDSig(Оповещения, Результат.КонвертXML, Результат.ПараметрыXMLDSig, Контекст.СертификатКриптографии, Контекст.МенеджерКриптографии); ИначеЕсли ЭтоCMS Тогда Если Контекст.Операция <> "Подписание" Тогда Ошибка = Новый Структура("ОписаниеОшибки", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Внешняя компонента %1 может использоваться только для подписания.'"), "ExtraCryptoAPI")); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Если МенеджерКриптографии = "СервисКриптографии" Тогда Если Результат.ПараметрыCMS.ВключениеСертификатовВПодпись <> РежимВключенияСертификатовКриптографии.ВключатьСертификатСубъекта Тогда Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Подписание сертификатом с программой встроенного криптопровайдера недоступно. |Выберите другой сертификат из установленных на компьютере.'")); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Если ТипЗнч(Данные.Данные) = Тип("ДвоичныеДанные") Тогда ДанныеДляПодписания = Данные.Данные; Иначе ДанныеДляПодписания = ПолучитьДвоичныеДанныеИзСтроки(Данные.Данные); КонецЕсли; ПараметрыОперации.Вставить("ОтсоединеннаяПодпись", Результат.ПараметрыCMS.Открепленная); Оповещение = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОперацииНаКлиенте", ЭтотОбъект, Контекст, "ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте", ЭтотОбъект); СертификатДляПодписи = ПолучитьИзВременногоХранилища(Контекст.ОписаниеДанных.ВыбранныйСертификат.Данные); МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); МодульСервисКриптографииКлиент.Подписать(Оповещение, ДанныеДляПодписания, СертификатДляПодписи, , ПараметрыОперации); Иначе ОповещениеУспех = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОперацииНаКлиентеXMLDSig", ЭтотОбъект, Контекст); ОповещениеОшибка = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиентеXMLDSig", ЭтотОбъект, Контекст); Оповещения = Новый Структура; Оповещения.Вставить("Успех", ОповещениеУспех); Оповещения.Вставить("Ошибка", ОповещениеОшибка); НачатьВыгрузкуСертификатаКриптографииДляПодписанияCMS(Оповещения, Результат.Данные, Результат.ПараметрыCMS, Контекст.СертификатКриптографии, Контекст.МенеджерКриптографии); КонецЕсли; Иначе Оповещение = Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеОперацииНаКлиенте", ЭтотОбъект, Контекст, "ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте", ЭтотОбъект); Если МенеджерКриптографии = "ОблачнаяПодпись" Тогда ВыполнитьОперациюОблачнойПодписи(Оповещение, Контекст, Данные, ПараметрыОперации); ИначеЕсли Контекст.Операция = "Подписание" Тогда Если МенеджерКриптографии = "СервисКриптографии" Тогда СертификатДляПодписи = ПолучитьИзВременногоХранилища(Контекст.ОписаниеДанных.ВыбранныйСертификат.Данные); МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); МодульСервисКриптографииКлиент.Подписать(Оповещение, Данные, СертификатДляПодписи, , ПараметрыОперации); Иначе Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись Тогда Попытка НастройкиПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.НастройкиСозданияПодписи( Контекст.ОписаниеДанных.ТипПодписи, ЭлектроннаяПодписьКлиент.ОбщиеНастройки().АдресаСерверовМетокВремени); Исключение ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте(ИнформацияОбОшибке(), Ложь, Контекст); Возврат; КонецПопытки; Если ЗначениеЗаполнено(НастройкиПодписи.АдресаСерверовМетокВремени) Тогда МенеджерКриптографии.АдресаСерверовМетокВремени = НастройкиПодписи.АдресаСерверовМетокВремени; КонецЕсли; МенеджерКриптографии.НачатьПодписывание(Оповещение, Данные, Контекст.СертификатКриптографии, НастройкиПодписи.ТипПодписи); Иначе МенеджерКриптографии.НачатьПодписывание(Оповещение, Данные, Контекст.СертификатКриптографии); КонецЕсли; КонецЕсли; ИначеЕсли Контекст.Операция = "Шифрование" Тогда Если МенеджерКриптографии = "СервисКриптографии" Тогда МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); МодульСервисКриптографииКлиент.Зашифровать(Оповещение, Данные, Контекст.СертификатыШифрования, , ПараметрыОперации); Иначе МенеджерКриптографии.НачатьШифрование(Оповещение, Данные, Контекст.СертификатыШифрования); КонецЕсли; Иначе Если МенеджерКриптографии = "СервисКриптографии" Тогда МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); МодульСервисКриптографииКлиент.Расшифровать(Оповещение, Данные, , ПараметрыОперации); Иначе МенеджерКриптографии.НачатьРасшифровку(Оповещение, Данные); КонецЕсли; КонецЕсли; КонецЕсли; Возврат; КонецЕсли; ЭлементДанныхДляСервера = Новый Структура; ЭлементДанныхДляСервера.Вставить("Данные", Данные); ПараметрыДляСервера = Новый Структура; ПараметрыДляСервера.Вставить("Операция", Контекст.Операция); ПараметрыДляСервера.Вставить("ИдентификаторФормы", Контекст.ИдентификаторФормы); ПараметрыДляСервера.Вставить("СертификатВерен", Контекст.СертификатВерен); ПараметрыДляСервера.Вставить("ТребуетсяПроверка", Контекст.ТребуетсяПроверка); ПараметрыДляСервера.Вставить("СертификатПрограмма", Контекст.Форма.СертификатПрограмма); ПараметрыДляСервера.Вставить("СертификатОтпечаток", Контекст.Форма.СертификатОтпечаток); ПараметрыДляСервера.Вставить("ЭлементДанныхДляСервера", ЭлементДанныхДляСервера); ОшибкаНаСервере = Новый Структура; АдресРезультата = Неопределено; Если Не ЗначениеЗаполнено(ПараметрыДляСервера.СертификатПрограмма) Тогда ПараметрыДляСервера.Вставить("ДанныеДляСозданияМенеджераКриптографии", Контекст.СертификатАдрес); КонецЕсли; Если Контекст.Операция = "Подписание" Тогда ПараметрыДляСервера.Вставить("ТипПодписи", Контекст.ОписаниеДанных.ТипПодписи); ПараметрыДляСервера.Вставить("Комментарий", Контекст.Форма.Комментарий); ПараметрыДляСервера.Вставить("ЗначениеПароля", Контекст.ЗначениеПароля); ПараметрыДляСервера.Вставить("ВыбраннаяДоверенность", Контекст.ОписаниеДанных.ВыбраннаяДоверенность); ПараметрыДляСервера.Вставить("РезультатПроверкиМЧДДляПодписания", Контекст.ОписаниеДанных.РезультатПроверкиМЧДДляПодписания); Если Контекст.ЭлементДанных.Свойство("Объект") И Не ТипЗнч(Контекст.ЭлементДанных.Объект) = Тип("ОписаниеОповещения") Тогда ЭлементДанныхДляСервера.Вставить("Объект", Контекст.ЭлементДанных.Объект); Если Контекст.ЭлементДанных.Свойство("ВерсияОбъекта") Тогда ЭлементДанныхДляСервера.Свойство("ВерсияОбъекта", Контекст.ЭлементДанных.ВерсияОбъекта); КонецЕсли; КонецЕсли; ИначеЕсли Контекст.Операция = "Шифрование" Тогда ПараметрыДляСервера.Вставить("АдресСертификатов", Контекст.ОписаниеДанных.СертификатыШифрования); Иначе // Расшифровка. ПараметрыДляСервера.Вставить("ЗначениеПароля", Контекст.ЗначениеПароля); КонецЕсли; Успех = ЭлектроннаяПодписьСлужебныйВызовСервера.ВыполнитьНаСторонеСервера(ПараметрыДляСервера, АдресРезультата, Контекст.ОперацияНачалась, ОшибкаНаСервере); Если Не Успех Тогда ВыполнитьНаСторонеПослеЦикла(ОшибкаНаСервере, Контекст); ИначеЕсли Контекст.Операция = "Подписание" Тогда ВыполнитьНаСторонеЦиклПослеПодписания(АдресРезультата, Контекст); ИначеЕсли Контекст.Операция = "Шифрование" Тогда ВыполнитьНаСторонеЦиклПослеШифрования(АдресРезультата, Контекст); Иначе // Расшифровка. ВыполнитьНаСторонеЦиклПослеРасшифровки(АдресРезультата, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); ОшибкаНаКлиенте.Вставить("Инструкция", Истина); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // ДвоичныеДанные - Структура: // * ИнформацияОбОшибке - Структура: // ** Описание - Строка // Контекст - Структура // Асинх Процедура ВыполнитьНаСторонеЦиклПослеОперацииНаКлиенте(ДвоичныеДанные, Контекст) Экспорт Если Контекст.Свойство("МенеджерКриптографии") И Контекст.МенеджерКриптографии = "СервисКриптографии" Тогда Если Не ДвоичныеДанные.Выполнено Тогда ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ДвоичныеДанные.ИнформацияОбОшибке.Описание); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Возврат; КонецЕсли; Если Контекст.Операция = "Подписание" Тогда ДвоичныеДанные = ДвоичныеДанные.Подпись; ИначеЕсли Контекст.Операция = "Шифрование" Тогда ДвоичныеДанные = ДвоичныеДанные.ЗашифрованныеДанные; Иначе ДвоичныеДанные = ДвоичныеДанные.РасшифрованныеДанные; КонецЕсли; ИначеЕсли Контекст.Свойство("МенеджерКриптографии") И Контекст.МенеджерКриптографии = "ОблачнаяПодпись" Тогда Если Не ДвоичныеДанные.Выполнено Тогда Если ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Контекст, "ИспользоватьОблачнуюПодпись", Ложь) Тогда Контекст.Вставить("ИспользоватьОблачнуюПодпись", Ложь); ВыполнитьНаСтороне(Контекст.Оповещение, Контекст.Операция, "НаСторонеКлиента", Контекст); Иначе ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ТекстОшибкиОблачнаяПодпись(Контекст.Операция, ДвоичныеДанные)); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); КонецЕсли; Возврат; КонецЕсли; ДвоичныеДанные = ДвоичныеДанные.Результат; КонецЕсли; ОписаниеОшибки = ""; Если Контекст.Операция = "Подписание" И ЭлектроннаяПодписьСлужебныйКлиентСервер.ПустыеДанныеПодписи(ДвоичныеДанные, ОписаниеОшибки) Или Контекст.Операция = "Шифрование" И ЭлектроннаяПодписьСлужебныйКлиентСервер.ПустыеЗашифрованныеДанные(ДвоичныеДанные, ОписаниеОшибки) Тогда ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ОписаниеОшибки); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Возврат; КонецЕсли; Контекст.ОперацияНачалась = Истина; Если Контекст.Операция = "Подписание" Тогда Если ТипЗнч(ДвоичныеДанные) = Тип("Массив") Тогда ВыполнитьНаСторонеЦиклПослеПодписанияПакета(ДвоичныеДанные, Контекст); Иначе Если Контекст.Свойство("МенеджерКриптографии") И ТипЗнч(Контекст.МенеджерКриптографии) = Тип( "МенеджерКриптографии") И ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись Тогда СвойстваПодписи = Ждать СвойстваПодписиЧтениеМенеджеромКриптографии(ДвоичныеДанные, Контекст.МенеджерКриптографии, Ложь); Иначе СвойстваПодписи = Ждать СвойстваПодписиИзДвоичныхДанных(ДвоичныеДанные, Ложь); КонецЕсли; Если СвойстваПодписи.Успех = Ложь Тогда ДанныеПодписи = Base64Строка(ДвоичныеДанные); ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='%1. |Результат подписи: %2'"), СвойстваПодписи.ТекстОшибки, ДанныеПодписи); ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ОписаниеОшибки); ОшибкаНаКлиенте.Вставить("Инструкция", Истина); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Возврат; КонецЕсли; СвойстваПодписи = ПолучитьСвойстваПодписиПослеПодписания(ДвоичныеДанные, Контекст, СвойстваПодписи); ВыполнитьНаСторонеЦиклПослеПодписания(СвойстваПодписи, Контекст); КонецЕсли; ИначеЕсли Контекст.Операция = "Шифрование" Тогда ВыполнитьНаСторонеЦиклПослеШифрования(ДвоичныеДанные, Контекст); Иначе ВыполнитьНаСторонеЦиклПослеРасшифровки(ДвоичныеДанные, Контекст); КонецЕсли; КонецПроцедуры Функция ПолучитьСвойстваПодписиПослеПодписания(ДвоичныеДанные, Контекст, ПараметрыПодписи = Неопределено) СвойстваПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваПодписи(ДвоичныеДанные, Контекст.СвойстваСертификата, Контекст.Форма.Комментарий, ПользователиКлиент.АвторизованныйПользователь(),, ПараметрыПодписи); СвойстваПодписи.ДатаПодписи = ?(ЗначениеЗаполнено(СвойстваПодписи.НеподтвержденнаяДатаПодписи), СвойстваПодписи.НеподтвержденнаяДатаПодписи, ОбщегоНазначенияКлиент.ДатаСеанса()); Если Контекст.СертификатВерен <> Неопределено Тогда СвойстваПодписи.ДатаПроверкиПодписи = СвойстваПодписи.ДатаПодписи; СвойстваПодписи.ПодписьВерна = Контекст.СертификатВерен; КонецЕсли; СвойстваПодписи.ТребуетсяПроверка = Контекст.ТребуетсяПроверка; Возврат СвойстваПодписи; КонецФункции // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеПодписания(СвойстваПодписи, Контекст) ЭлементДанных = Контекст.ЭлементДанных; ЭлементДанных.Вставить("СвойстваПодписи", СвойстваПодписи); Если Не ЭлементДанных.Свойство("Объект") Тогда ЭлектроннаяПодписьСлужебныйВызовСервера.ЗарегистрироватьПодписаниеДанныхВЖурнале( СвойстваТекущегоЭлементаДанных(Контекст, СвойстваПодписи)); ВыполнитьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; Если ТипЗнч(ЭлементДанных.Объект) <> Тип("ОписаниеОповещения") Тогда Если Контекст.НаСторонеКлиента Тогда ВерсияОбъекта = Неопределено; ЭлементДанных.Свойство("ВерсияОбъекта", ВерсияОбъекта); СвойстваПодписи.Вставить("ИдентификаторПодписи", Строка(Новый УникальныйИдентификатор)); // Локализация Если ЗначениеЗаполнено(Контекст.ОписаниеДанных.РезультатПроверкиМЧДДляПодписания) И ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности") Тогда МодульМашиночитаемыеДоверенностиФНССлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль( "МашиночитаемыеДоверенностиФНССлужебныйКлиент"); РезультатПроверкиПодписиПоМЧД = МодульМашиночитаемыеДоверенностиФНССлужебныйКлиент.РезультатПроверкиПодписиПоМЧД( Контекст.ОписаниеДанных.ВыбраннаяДоверенность, ЭлементДанных.Объект, СвойстваПодписи.Сертификат, Неопределено, Контекст.ОписаниеДанных.РезультатПроверкиМЧДДляПодписания); Если ЗначениеЗаполнено(РезультатПроверкиПодписиПоМЧД) Тогда СвойстваПодписи.Вставить("РезультатПроверкиПодписиПоМЧД", РезультатПроверкиПодписиПоМЧД); КонецЕсли; КонецЕсли; // Конец Локализация ПредставлениеОшибки = ЭлектроннаяПодписьСлужебныйВызовСервера.ДобавитьПодпись( ЭлементДанных.Объект, СвойстваПодписи, Контекст.ИдентификаторФормы, ВерсияОбъекта); Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ЭлементДанных.Удалить("СвойстваПодписи"); ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ПредставлениеОшибки); ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Возврат; КонецЕсли; КонецЕсли; ОповеститьОбИзменении(ЭлементДанных.Объект); ВыполнитьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; ЭлектроннаяПодписьСлужебныйВызовСервера.ЗарегистрироватьПодписаниеДанныхВЖурнале( СвойстваТекущегоЭлементаДанных(Контекст, СвойстваПодписи)); ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", Контекст.ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеЗаписиПодписи", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(ЭлементДанных.Объект, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ВыполнитьНаСторонеЦиклПослеЗаписиПодписи(Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)), Контекст); КонецПопытки; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеЗаписиПодписи(Результат, Контекст) Экспорт Если Результат.Свойство("ОписаниеОшибки") Тогда Контекст.ЭлементДанных.Удалить("СвойстваПодписи"); Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'При записи подписи возникла ошибка:'") + Символы.ПС + Результат.ОписаниеОшибки); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; ВыполнитьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеШифрования(ЗашифрованныеДанные, Контекст) ЭлементДанных = Контекст.ЭлементДанных; ЭлементДанных.Вставить("ЗашифрованныеДанные", ЗашифрованныеДанные); Если Не ЭлементДанных.Свойство("РазмещениеРезультата") Или ТипЗнч(ЭлементДанных.РазмещениеРезультата) <> Тип("ОписаниеОповещения") Тогда ВыполнитьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", Контекст.ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеЗаписиЗашифрованныхДанных", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(ЭлементДанных.РазмещениеРезультата, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ВыполнитьНаСторонеЦиклПослеЗаписиЗашифрованныхДанных(Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)), Контекст); КонецПопытки; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеЗаписиЗашифрованныхДанных(Результат, Контекст) Экспорт Если Результат.Свойство("ОписаниеОшибки") Тогда Контекст.ЭлементДанных.Удалить("ЗашифрованныеДанные"); Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Не удалось записать зашифрованные данные по причине:'") + Символы.ПС + Результат.ОписаниеОшибки); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; ВыполнитьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеРасшифровки(РасшифрованныеДанные, Контекст) ЭлементДанных = Контекст.ЭлементДанных; ЭлементДанных.Вставить("РасшифрованныеДанные", РасшифрованныеДанные); Если Не ЭлементДанных.Свойство("РазмещениеРезультата") Или ТипЗнч(ЭлементДанных.РазмещениеРезультата) <> Тип("ОписаниеОповещения") Тогда ВыполнитьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", Контекст.ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеЗаписиРасшифрованныхДанных", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(ЭлементДанных.РазмещениеРезультата, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ВыполнитьНаСторонеЦиклПослеЗаписиЗашифрованныхДанных(Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)), Контекст); КонецПопытки; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеЗаписиРасшифрованныхДанных(Результат, Контекст) Экспорт Если Результат.Свойство("ОписаниеОшибки") Тогда Контекст.ЭлементДанных.Удалить("РасшифрованныеДанные"); Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Не удалось записать расшифрованные данные по причине:'") + Символы.ПС + Результат.ОписаниеОшибки); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; ВыполнитьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст) Результат = Новый Структура; Если Ошибка <> Неопределено Тогда Результат.Вставить("Ошибка", Ошибка); КонецЕсли; Если Контекст.ОперацияНачалась Тогда Результат.Вставить("ОперацияНачалась"); Если Не Результат.Свойство("Ошибка") И Контекст.Индекс > 0 Тогда Результат.Вставить("ЕстьОбработанныеЭлементыДанных"); КонецЕсли; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры // Возвращаемое значение: // Структура: // * Оповещение - ОписаниеОповещения // * Операция - Строка // * НаСторонеКлиента - Булево // * ОперацияНачалась - Булево // * ОписаниеДанных - Структура // * Форма - ФормаКлиентскогоПриложения // * ИдентификаторФормы - УникальныйИдентификатор // * ЗначениеПароля - Строка // * СертификатВерен - Неопределено // - Булево // * ТребуетсяПроверка - Неопределено // - Булево // * СертификатАдрес - Строка // * ТекущийСписокПредставлений - СписокЗначений // - Массив // * ПолноеПредставлениеДанных - Строка // * МенеджерКриптографии - МенеджерКриптографии // - Строка // * СертификатКриптографии - СертификатКриптографии // * Индекс - Число // * СвойстваСертификатов - Структура // * СертификатыШифрования - Массив // Функция ВыполнитьНаСторонеНовыйКонтекст() Возврат Новый Структура("ОписаниеДанных, Форма, ИдентификаторФормы, ЗначениеПароля, |СертификатВерен, ТребуетсяПроверка, СертификатАдрес, ТекущийСписокПредставлений, ПолноеПредставлениеДанных"); КонецФункции // Только для внутреннего использования. Функция СвойстваТекущегоЭлементаДанных(ПараметрыВыполнения, СвойстваПодписи = Неопределено) Экспорт Если ПараметрыВыполнения.ОписаниеДанных.Свойство("Данные") Или Не ПараметрыВыполнения.ОписаниеДанных.Свойство("ТекущийЭлементНабораДанных") Тогда ПредставлениеЭлементаДанных = ПараметрыВыполнения.ТекущийСписокПредставлений[0].Значение; Иначе ПредставлениеЭлементаДанных = ПараметрыВыполнения.ТекущийСписокПредставлений[ ПараметрыВыполнения.ОписаниеДанных.НаборДанных.Найти( ПараметрыВыполнения.ОписаниеДанных.ТекущийЭлементНабораДанных)].Значение; КонецЕсли; Если ТипЗнч(ПредставлениеЭлементаДанных) = Тип("ОписаниеОповещения") Тогда ПредставлениеЭлементаДанных = ПараметрыВыполнения.ПолноеПредставлениеДанных; КонецЕсли; Если СвойстваПодписи = Неопределено Тогда СвойстваПодписи = Новый Структура; СвойстваПодписи.Вставить("Сертификат", ПараметрыВыполнения.СертификатАдрес); СвойстваПодписи.Вставить("ДатаПодписи", '00010101'); КонецЕсли; СвойстваЭлементаДанных = Новый Структура; СвойстваЭлементаДанных.Вставить("СвойстваПодписи", СвойстваПодписи); СвойстваЭлементаДанных.Вставить("ПредставлениеДанных", ПредставлениеЭлементаДанных); Возврат СвойстваЭлементаДанных; КонецФункции // Только для внутреннего использования. Процедура ПолучитьДанныеИзОписанияДанных(Оповещение, Форма, ОписаниеДанных, ИсточникДанных, ДляСтороныКлиента) Экспорт Контекст = Новый Структура; Контекст.Вставить("Форма", Форма); Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ДляСтороныКлиента", ДляСтороныКлиента); Если ТипЗнч(ИсточникДанных) = Тип("ОписаниеОповещения") Тогда ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "ПолучитьДанныеИзОписанияДанныхПродолжение", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(ИсточникДанных, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); Результат = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); ПолучитьДанныеИзОписанияДанныхПродолжение(Результат, Контекст); КонецПопытки; Иначе ПолучитьДанныеИзОписанияДанныхПродолжение(Новый Структура("Данные", ИсточникДанных), Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПолучитьДанныеИзОписанияДанных. Процедура ПолучитьДанныеИзОписанияДанныхПродолжение(Результат, Контекст) Экспорт ЭтоXMLDSig = (ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("Данные") И ТипЗнч(Результат.Данные) = Тип("Структура") И Результат.Данные.Свойство("ПараметрыXMLDSig")); Если ЭтоXMLDSig И Не Результат.Данные.Свойство("КонвертXML") Тогда Результат.Данные = Новый Структура(Новый ФиксированнаяСтруктура(Результат.Данные)); Результат.Данные.Вставить("КонвертXML", Результат.Данные.КонвертSOAP); КонецЕсли; ЭтоCMS = (ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("Данные") И ТипЗнч(Результат.Данные) = Тип("Структура") И Результат.Данные.Свойство("ПараметрыCMS")); Если ТипЗнч(Результат) <> Тип("Структура") Или Не Результат.Свойство("Данные") Или ТипЗнч(Результат.Данные) <> Тип("ДвоичныеДанные") И ТипЗнч(Результат.Данные) <> Тип("Строка") И Не ЭтоXMLDSig И Не ЭтоCMS Тогда Если ТипЗнч(Результат) <> Тип("Структура") Или Не Результат.Свойство("ОписаниеОшибки") Тогда Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Некорректный тип данных.'")); Иначе Ошибка = Новый Структура("ОписаниеОшибки", Результат.ОписаниеОшибки); КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Ошибка); Возврат; КонецЕсли; Данные = Результат.Данные; Если Контекст.ДляСтороныКлиента Тогда // Для стороны клиента требуются двоичные данные или путь к файлу. Если ТипЗнч(Данные) = Тип("ДвоичныеДанные") Или ЭтоXMLDSig Или ЭтоCMS Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Данные); ИначеЕсли ЭтоАдресВременногоХранилища(Данные) Тогда Попытка ТекущийРезультат = ПолучитьИзВременногоХранилища(Данные); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ТекущийРезультат = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); КонецПопытки; ВыполнитьОбработкуОповещения(Контекст.Оповещение, ТекущийРезультат); Иначе // Путь к файлу ВыполнитьОбработкуОповещения(Контекст.Оповещение, Данные); КонецЕсли; Иначе // Для стороны сервера требуется адрес двоичных данных во временном хранилище. Если ТипЗнч(Данные) = Тип("ДвоичныеДанные") Или ЭтоXMLDSig Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, ПоместитьВоВременноеХранилище(Данные, Контекст.Форма.УникальныйИдентификатор)); ИначеЕсли ЭтоCMS Тогда Данные.ПараметрыCMS.ВключениеСертификатовВПодпись = ВключениеСертификатовВПодписьСтрокой( Данные.ПараметрыCMS.ВключениеСертификатовВПодпись); ВыполнитьОбработкуОповещения(Контекст.Оповещение, ПоместитьВоВременноеХранилище(Данные, Контекст.Форма.УникальныйИдентификатор)); ИначеЕсли ЭтоАдресВременногоХранилища(Данные) Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Данные); Иначе // Путь к файлу Попытка ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла(); ПараметрыЗагрузки.ИдентификаторФормы = Контекст.Форма.УникальныйИдентификатор; ПараметрыЗагрузки.Интерактивно = Ложь; ФайловаяСистемаКлиент.ЗагрузитьФайл(Новый ОписаниеОповещения( "ПолучитьДанныеИзОписанияДанныхЗавершение", ЭтотОбъект, Контекст, "ПолучитьДанныеИзОписанияДанныхЗавершениеПоОшибке", ЭтотОбъект), ПараметрыЗагрузки, Данные); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ТекущийРезультат = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); ВыполнитьОбработкуОповещения(Контекст.Оповещение, ТекущийРезультат); КонецПопытки; КонецЕсли; КонецЕсли; КонецПроцедуры // Продолжение процедуры ПолучитьДанныеИзОписанияДанных. Процедура ПолучитьДанныеИзОписанияДанныхЗавершениеПоОшибке(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; Результат = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры // Продолжение процедуры ПолучитьДанныеИзОписанияДанных. Процедура ПолучитьДанныеИзОписанияДанныхЗавершение(ПомещенныеФайлы, Контекст) Экспорт Если ПомещенныеФайлы = Неопределено Или ПомещенныеФайлы.Количество() = 0 Тогда Результат = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Передача данных отменена пользователем.'")); Иначе Результат = ПомещенныеФайлы[0].Хранение; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры // Только для внутреннего использования. Процедура ПродлитьХранениеКонтекстаОперации(ОписаниеДанных) Экспорт ФормаПередачаПараметров().ПродлитьХранениеКонтекстаОперации(ОписаниеДанных.КонтекстОперации); КонецПроцедуры #Область УсовершенствоватьПодпись Процедура УсовершенствоватьПодпись(Контекст) Экспорт Если Не ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись Тогда ВызватьИсключение НСтр("ru='Усовершенствование подписи недоступно на текущей версии платформы.'"); КонецЕсли; Если Не ЗначениеЗаполнено(Контекст.ПараметрыВыполнения.ОписаниеДанных.Подпись) Тогда ВызватьИсключение НСтр("ru='Переданные параметры не содержат данных подписи.'"); КонецЕсли; Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ЭтоМодельСервисаСДоступнымУсовершенствованием И Контекст.ПараметрыВыполнения.ОписаниеДанных.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.СМеткойДоверенногоВремениCAdEST") Тогда НастройкиПодключенияСервиса = ЭлектроннаяПодписьСлужебныйВызовСервера.НастройкиСлужебнойУчетнойЗаписиДляУсовершенствованияПодписей( Контекст.ПараметрыВыполнения.ИдентификаторФормы); Если ЗначениеЗаполнено(НастройкиПодключенияСервиса.Ошибка) Тогда ОписаниеОповещения = Новый ОписаниеОповещения("ПродолжитьУсовершенствованиеПослеОтветаНаВопрос", ЭтотОбъект, Контекст); ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='Ошибка при попытке усовершенствования через приложение в Интернете: |%1 |Продолжить усовершенствование с помощью программ, установленных на компьютере?'"), НастройкиПодключенияСервиса.Ошибка); ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60); Возврат; КонецЕсли; Контекст.ПараметрыВыполнения.Вставить("ЭтоМодельСервисаСДоступнымУсовершенствованием", Истина); Контекст.ПараметрыВыполнения.Вставить("СлужебнаяУчетнаяЗаписьDSS", НастройкиПодключенияСервиса.СлужебнаяУчетнаяЗаписьDSS); Контекст.ПараметрыВыполнения.Вставить("ПараметрыПодписиCAdEST", НастройкиПодключенияСервиса.ПараметрыПодписиCAdEST); УсовершенствоватьНаСтороне(Новый ОписаниеОповещения( "УсовершенствоватьПослеВыполненияНаСторонеСервера", ЭлектроннаяПодписьСлужебныйКлиент, Контекст), "НаСторонеСервера", Контекст.ПараметрыВыполнения); ИначеЕсли ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере() Тогда УсовершенствоватьНаСтороне(Новый ОписаниеОповещения( "УсовершенствоватьПослеВыполненияНаСторонеСервера", ЭлектроннаяПодписьСлужебныйКлиент, Контекст), "НаСторонеСервера", Контекст.ПараметрыВыполнения); Иначе УсовершенствоватьПослеВыполненияНаСторонеСервера(Неопределено, Контекст); КонецЕсли; КонецПроцедуры Процедура ПродолжитьУсовершенствованиеПослеОтветаНаВопрос(РезультатВопроса, Контекст) Экспорт Если РезультатВопроса = КодВозвратаДиалога.Да Тогда УсовершенствоватьПослеВыполненияНаСторонеСервера(Неопределено, Контекст); Иначе Результат = Новый Структура; Результат.Вставить("Ошибка", Истина); Результат.Вставить("ТекстОшибки", НСтр("ru='Ошибка при попытке усовершенствования через приложение в Интернете'")); УсовершенствоватьПослеВыполненияНаСторонеКлиента(Результат, Контекст); КонецЕсли; КонецПроцедуры Процедура УсовершенствоватьНаСтороне(Оповещение, СторонаВыполнения, ПараметрыВыполнения) Контекст = Новый Структура("ОписаниеДанных, ИдентификаторФормы"); Контекст.Вставить("ПрерыватьОбработкуМассиваПриОшибке", Истина); Контекст.Вставить("ИгнорироватьСрокДействияСертификата", Ложь); ЗаполнитьЗначенияСвойств(Контекст, ПараметрыВыполнения); Если ПараметрыВыполнения.Свойство("ЭтоМодельСервисаСДоступнымУсовершенствованием") Тогда Контекст.Вставить("ЭтоМодельСервисаСДоступнымУсовершенствованием", Истина); Контекст.Вставить("СлужебнаяУчетнаяЗаписьDSS", ПараметрыВыполнения.СлужебнаяУчетнаяЗаписьDSS); Контекст.Вставить("ПараметрыПодписиCAdEST", ПараметрыВыполнения.ПараметрыПодписиCAdEST); Иначе Контекст.Вставить("ЭтоМодельСервисаСДоступнымУсовершенствованием", Ложь); КонецЕсли; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("НаСторонеКлиента", СторонаВыполнения = "НаСторонеКлиента"); Контекст.Вставить("ОперацияНачалась", Ложь); Контекст.Вставить("ЕстьОшибки", Ложь); Контекст.Вставить("ОшибкиСозданияМенеджераКриптографии", Новый Массив); Если ПараметрыВыполнения.Свойство("ЭлементыДанных") Тогда Контекст.Вставить("ЭлементыДанных", ПараметрыВыполнения.ЭлементыДанных); Иначе Если ТипЗнч(Контекст.ОписаниеДанных.Подпись) = Тип("Массив") Тогда Подписи = Контекст.ОписаниеДанных.Подпись; Иначе Подписи = Новый Массив; Подписи.Добавить(Контекст.ОписаниеДанных.Подпись); КонецЕсли; ТипЭлементовДанных = ТипЗнч(Подписи[0]); // Все должны быть однотипными. Если ТипЭлементовДанных = Тип("Структура") Тогда ЭлементыДанных = ЭлектроннаяПодписьСлужебныйВызовСервера.ПреобразоватьПодписиВМассив(Подписи, Контекст.ИдентификаторФормы); Иначе ЭлементыДанных = Новый Массив; Для Каждого ТекущийЭлемент Из Подписи Цикл ЭлементыДанных.Добавить(Новый Структура("Подпись, ТипПодписи, СрокДействияПоследнейМеткиВремени", ТекущийЭлемент)); КонецЦикла; КонецЕсли; Контекст.Вставить("ЭлементыДанных", ЭлементыДанных); КонецЕсли; Контекст.Вставить("Индекс", -1); УсовершенствоватьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. // // Параметры: // Контекст - Структура: // * Индекс - Число // Процедура УсовершенствоватьНаСторонеЦиклНачало(Контекст) Если Контекст.ЭлементыДанных.Количество() <= Контекст.Индекс + 1 Тогда УсовершенствоватьНаСторонеПослеЦикла(Контекст); Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения( "УсовершенствоватьНаСторонеЦиклНачалоПродолжение", ЭтотОбъект, Контекст); СтандартныеПодсистемыКлиент.НачатьВыполнениеОбработкиОповещения(Оповещение); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. // // Параметры: // Контекст - Структура: // * Индекс - Число // Процедура УсовершенствоватьНаСторонеЦиклНачалоПродолжение(Результат, Контекст) Экспорт Контекст.Индекс = Контекст.Индекс + 1; ЭлементДанных = Контекст.ЭлементыДанных[Контекст.Индекс]; Если ЭлементДанных.Свойство("СвойстваПодписи") Тогда УсовершенствоватьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; Контекст.Вставить("ЭлементДанных", ЭлементДанных); Подпись = ЭлементДанных.Подпись; Если Контекст.НаСторонеКлиента Тогда // Для стороны клиента требуются двоичные данные. Если ТипЗнч(Подпись) = Тип("Строка") Тогда Попытка Подпись = ПолучитьИзВременногоХранилища(Подпись); Исключение Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); Возврат; КонецПопытки; КонецЕсли; ЭлементДанных.Подпись = Подпись; ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Неопределено; Если ЭлементДанных.Свойство("АлгоритмПодписи") Тогда ПараметрыСоздания.АлгоритмПодписи = ЭлементДанных.АлгоритмПодписи; Иначе ПараметрыСоздания.АлгоритмПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.АлгоритмСформированнойПодписи(Подпись); Контекст.ЭлементыДанных[Контекст.Индекс].Вставить("АлгоритмПодписи", ПараметрыСоздания.АлгоритмПодписи); КонецЕсли; СоздатьМенеджерКриптографии(Новый ОписаниеОповещения( "УсовершенствоватьНаСторонеПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст), "ПродлениеСрокаДействияПодписи", ПараметрыСоздания); Возврат; КонецЕсли; УсовершенствоватьНаСервере(ЭлементДанных, Контекст); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСервере(ЭлементДанных, Контекст) Подпись = Контекст.ЭлементДанных.Подпись; ПараметрыДляСервера = Новый Структура; ПараметрыДляСервера.Вставить("ЭтоМодельСервисаСДоступнымУсовершенствованием", Контекст.ЭтоМодельСервисаСДоступнымУсовершенствованием); ПараметрыДляСервера.Вставить("ИдентификаторФормы", Контекст.ИдентификаторФормы); ПараметрыДляСервера.Вставить("ЭлементДанныхДляСервера", ЭлементДанных); ПараметрыДляСервера.Вставить("ТипПодписи", Контекст.ОписаниеДанных.ТипПодписи); ПараметрыДляСервера.Вставить("ДобавитьАрхивнуюМеткуВремени", Контекст.ОписаниеДанных.ДобавитьАрхивнуюМеткуВремени); ПараметрыДляСервера.Вставить("ОперацияНачалась", Контекст.ОперацияНачалась); ПараметрыДляСервера.Вставить("ИгнорироватьСрокДействияСертификата", Контекст.ИгнорироватьСрокДействияСертификата); Если ПараметрыДляСервера.ЭтоМодельСервисаСДоступнымУсовершенствованием Тогда ПараметрыДляСервера.ЭлементДанныхДляСервера.Подпись = Подпись; ПараметрыДляСервера.Вставить("ПараметрыПодписиCAdEST", Контекст.ПараметрыПодписиCAdEST); ПараметрыДляСервера.Вставить("СлужебнаяУчетнаяЗаписьDSS", Контекст.СлужебнаяУчетнаяЗаписьDSS); ДлительнаяОперация = ЭлектроннаяПодписьСлужебныйВызовСервера.НачатьУсовершенствованиеНаСервере( ПараметрыДляСервера); Если Не ДлительнаяОперация.Свойство("АдресРезультата") Тогда ПродолжитьПослеУсовершенствованияНаСервере(ДлительнаяОперация, Контекст); Возврат; КонецЕсли; ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(Неопределено); ПараметрыОжидания.ВыводитьОкноОжидания = Истина; ОповещениеОЗавершении = Новый ОписаниеОповещения("ПродолжитьПослеОперацииУсовершенствованияНаСервере", ЭтотОбъект, Контекст); ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания); Иначе // Для стороны сервера требуется адрес двоичных данных во временном хранилище. Если ТипЗнч(Подпись) = Тип("ДвоичныеДанные") Тогда ПараметрыДляСервера.ЭлементДанныхДляСервера.Подпись = ПоместитьВоВременноеХранилище(Подпись, Контекст.ИдентификаторФормы); КонецЕсли; Результат = ЭлектроннаяПодписьСлужебныйВызовСервера.УсовершенствоватьНаСторонеСервера(ПараметрыДляСервера); ПродолжитьПослеУсовершенствованияНаСервере(Результат, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. // // Параметры: // РезультатВыполнения - Структура - результат выполнения длительной операции. // Контекст - Структура // Процедура ПродолжитьПослеОперацииУсовершенствованияНаСервере(РезультатВыполнения, Контекст) Экспорт Если РезультатВыполнения = Неопределено Тогда ОшибкаНаСервере = ОписаниеОшибкиПриУсовершенствовании(Ложь); ОшибкаНаСервере.Текст = НСтр("ru='Усовершенствование подписи фоновым заданием не было завершено штатно'"); УсовершенствоватьНаСторонеПослеОшибки(ОшибкаНаСервере, Контекст); Возврат; КонецЕсли; Если РезультатВыполнения.Статус = "Ошибка" Тогда ОшибкаНаСервере = ОписаниеОшибкиПриУсовершенствовании(Ложь); ОшибкаНаСервере.Текст = РезультатВыполнения.КраткоеПредставлениеОшибки; УсовершенствоватьНаСторонеПослеОшибки(ОшибкаНаСервере, Контекст); Возврат; КонецЕсли; // Результат выполнения фонового задания. Попытка Результат = ПолучитьИзВременногоХранилища(РезультатВыполнения.АдресРезультата); Если Не ЗначениеЗаполнено(Результат) Тогда ТекстОшибки = НСтр("ru = 'Фоновое задание не вернуло результат'"); ВызватьИсключение ТекстОшибки; КонецЕсли; Исключение ОшибкаНаСервере = ОписаниеОшибкиПриУсовершенствовании(Ложь); ОшибкаНаСервере.Текст = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); УсовершенствоватьНаСторонеПослеОшибки(ОшибкаНаСервере, Контекст); Возврат; КонецПопытки; УдалитьИзВременногоХранилища(РезультатВыполнения.АдресРезультата); ПродолжитьПослеУсовершенствованияНаСервере(Результат, Контекст); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. // // Параметры: // РезультатВыполнения - Структура: // * Успех // * ТекстОшибки // * СвойстваПодписи // * АлгоритмПодписи // * ОшибкаПриСозданииМенеджераКриптографии // * ОперацияНачалась // Контекст - Структура // Процедура ПродолжитьПослеУсовершенствованияНаСервере(Результат, Контекст) Контекст.ОперацияНачалась = Результат.ОперацияНачалась; Если Результат.Свойство("АлгоритмПодписи") И ЗначениеЗаполнено(Результат.АлгоритмПодписи) Тогда Контекст.ЭлементыДанных[Контекст.Индекс].Вставить("АлгоритмПодписи", Результат.АлгоритмПодписи); КонецЕсли; Если Не Результат.Успех Тогда ОшибкаНаСервере = ОписаниеОшибкиПриУсовершенствовании(Ложь); ОшибкаНаСервере.Текст = Результат.ТекстОшибки; Если Результат.ОшибкаПриСозданииМенеджераКриптографии = Истина Тогда ОшибкаНаСервере.ОшибкаПриСозданииМенеджераКриптографии = Истина; КонецЕсли; УсовершенствоватьНаСторонеПослеОшибки(ОшибкаНаСервере, Контекст); Иначе ВыполнитьНаСторонеЦиклПослеУсовершенствования(Результат.СвойстваПодписи, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСторонеПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст) Экспорт Если ТипЗнч(МенеджерКриптографии) <> Тип("МенеджерКриптографии") Тогда Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = МенеджерКриптографии.ОписаниеОшибки; Ошибка.ОшибкаСозданияМенеджераКриптографии = Истина; УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); Возврат; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Подпись = Контекст.ЭлементДанных.Подпись; Оповещение = Новый ОписаниеОповещения("УсовершенствоватьНаСторонеПослеПолученияКонтейнераПодписи", ЭтотОбъект, Контекст, "УсовершенствоватьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте", ЭтотОбъект); МенеджерКриптографии.НачатьПолучениеКонтейнераПодписейКриптографии(Оповещение, Подпись); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Асинх Процедура УсовершенствоватьНаСторонеПослеПолученияКонтейнераПодписи(КонтейнерПодписи, Контекст) Экспорт ДатаСеанса = ОбщегоНазначенияКлиент.ДатаСеанса(); ДобавкаВремени = ДатаСеанса - ОбщегоНазначенияКлиент.ДатаУниверсальная(); ПараметрыПодписи = Ждать ПараметрыПодписиКриптографии( КонтейнерПодписи, ДобавкаВремени, ДатаСеанса); Контекст.ЭлементДанных.Вставить("ПараметрыПодписи", ПараметрыПодписи); Если ПараметрыПодписи.СертификатПоследнейМеткиВремени = Неопределено Тогда ОписаниеОшибки = НСтр("ru='Не удалось получить сертификат подписи'"); Контекст.ЭлементДанных.Вставить("Ошибка", ОписаниеОшибки); УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте(ПараметрыПодписи, Контекст); Возврат; КонецЕсли; Если Не Контекст.ИгнорироватьСрокДействияСертификата И ЗначениеЗаполнено(ПараметрыПодписи.СрокДействияПоследнейМеткиВремени) И ПараметрыПодписи.СрокДействияПоследнейМеткиВремени < ДатаСеанса Тогда ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='Истек срок действия сертификата подписи: %1'"), СвойстваСертификатаСтрокой(ПараметрыПодписи.СертификатПоследнейМеткиВремени)); Контекст.ЭлементДанных.Вставить("Ошибка", ОписаниеОшибки); УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте(ПараметрыПодписи, Контекст); Возврат; КонецЕсли; Если ПараметрыПодписи.СертификатПоследнейМеткиВремени <> Неопределено Тогда Оповещение = Новый ОписаниеОповещения("УсовершенствоватьНаСторонеПослеПроверкиСертификатаПодписи", ЭтотОбъект, Контекст); ПроверитьСертификат(Оповещение, ПараметрыПодписи.СертификатПоследнейМеткиВремени, Контекст.МенеджерКриптографии); Иначе УсовершенствоватьНаСторонеПослеПроверкиСертификатаПодписи(Истина, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСторонеПослеПроверкиСертификатаПодписи(Результат, Контекст) Экспорт ПараметрыПодписи = Контекст.ЭлементДанных.ПараметрыПодписи; Если Результат <> Истина Тогда Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='При проверке сертификата подписи до усовершенствования: %1 |%2'"), Результат, СвойстваСертификатаСтрокой(ПараметрыПодписи.СертификатПоследнейМеткиВремени)); УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); Возврат; КонецЕсли; Оповещение = Новый ОписаниеОповещения( "УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте", ЭтотОбъект, Контекст, "УсовершенствоватьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте", ЭтотОбъект); МенеджерКриптографии = Контекст.МенеджерКриптографии; МенеджерКриптографии.АдресаСерверовМетокВремени = ЭлектроннаяПодписьКлиент.ОбщиеНастройки().АдресаСерверовМетокВремени; Подпись = Контекст.ЭлементДанных.Подпись; Если ПараметрыПодписи.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.АрхивнаяCAdESAv3") Или ПараметрыПодписи.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.CAdESAv2") Тогда Если Контекст.ОписаниеДанных.ДобавитьАрхивнуюМеткуВремени Тогда МенеджерКриптографии.НачатьДобавлениеАрхивнойМеткиВремени(Оповещение, Подпись); Иначе УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте(ПараметрыПодписи, Контекст); Возврат; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(Контекст.ОписаниеДанных.ТипПодписи) И ЭлектроннаяПодписьСлужебныйКлиентСервер.ПодлежитУсовершенствованию(ПараметрыПодписи.ТипПодписи, Контекст.ОписаниеДанных.ТипПодписи) Тогда МенеджерКриптографии.НачатьУсовершенствованиеПодписи(Оповещение, Подпись, ЭлектроннаяПодписьСлужебныйКлиентСервер.ТипПодписиКриптографии(Контекст.ОписаниеДанных.ТипПодписи)); Иначе УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте(ПараметрыПодписи, Контекст); Возврат; КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. // // Параметры: // ДвоичныеДанные - ДвоичныеДанные // - Структура - параметры подписи, не подлежащей усовершенствованию. // Контекст - Структура // Процедура УсовершенствоватьНаСторонеЦиклПослеОперацииНаКлиенте(ДвоичныеДанные, Контекст) Экспорт Если ТипЗнч(ДвоичныеДанные) = Тип("Структура") Тогда // Подпись не продлевалась, возможно, нужно записать параметры переданной подписи. Контекст.ЭлементДанных.Вставить("НеТребуетсяПродление", Истина); ВыполнитьНаСторонеЦиклПослеУсовершенствования(ДвоичныеДанные, Контекст); Возврат; КонецЕсли; ОписаниеОшибки = ""; Если ЭлектроннаяПодписьСлужебныйКлиентСервер.ПустыеДанныеПодписи(ДвоичныеДанные, ОписаниеОшибки) Тогда Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = ОписаниеОшибки; УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); Возврат; КонецЕсли; Контекст.ОперацияНачалась = Истина; Контекст.ЭлементДанных.Вставить("СвойстваПодписи", Новый Структура("Подпись", ДвоичныеДанные)); Оповещение = Новый ОписаниеОповещения("ВыполнитьПослеПолученияКонтейнераУсовершенствованнойПодписи", ЭтотОбъект, Контекст, "УсовершенствоватьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте", ЭтотОбъект); Контекст.МенеджерКриптографии.НачатьПолучениеКонтейнераПодписейКриптографии(Оповещение, ДвоичныеДанные); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Асинх Процедура ВыполнитьПослеПолученияКонтейнераУсовершенствованнойПодписи(КонтейнерПодписи, Контекст) Экспорт ДатаСеанса = ОбщегоНазначенияКлиент.ДатаСеанса(); ДобавкаВремени = ДатаСеанса - ОбщегоНазначенияКлиент.ДатаУниверсальная(); ПараметрыПодписи = Ждать ПараметрыПодписиКриптографии( КонтейнерПодписи, ДобавкаВремени, ДатаСеанса); Контекст.ЭлементДанных.Вставить("ПараметрыПодписи", ПараметрыПодписи); Если ПараметрыПодписи.СертификатПоследнейМеткиВремени <> Неопределено Тогда Оповещение = Новый ОписаниеОповещения("ВыполнитьНаСторонеПослеУсовершенствованияИПроверкиСертификата", ЭтотОбъект, Контекст); ПроверитьСертификат(Оповещение, ПараметрыПодписи.СертификатПоследнейМеткиВремени, Контекст.МенеджерКриптографии); Иначе СвойстваПодписи = Новый Структура; СвойстваПодписи.Вставить("Подпись", Контекст.ЭлементДанных.СвойстваПодписи.Подпись); СвойстваПодписи.Вставить("ТипПодписи", ПараметрыПодписи.ТипПодписи); СвойстваПодписи.Вставить("СрокДействияПоследнейМеткиВремени", ПараметрыПодписи.СрокДействияПоследнейМеткиВремени); ВыполнитьНаСторонеЦиклПослеУсовершенствования(СвойстваПодписи, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура ВыполнитьНаСторонеПослеУсовершенствованияИПроверкиСертификата(Результат, Контекст) Экспорт ПараметрыПодписи = Контекст.ЭлементДанных.ПараметрыПодписи; СвойстваПодписи = Новый Структура; СвойстваПодписи.Вставить("Подпись", Контекст.ЭлементДанных.СвойстваПодписи.Подпись); СвойстваПодписи.Вставить("ТипПодписи", ПараметрыПодписи.ТипПодписи); СвойстваПодписи.Вставить("СрокДействияПоследнейМеткиВремени", ПараметрыПодписи.СрокДействияПоследнейМеткиВремени); Если Результат = Истина Тогда ВыполнитьНаСторонеЦиклПослеУсовершенствования(СвойстваПодписи, Контекст); Иначе Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='При проверке сертификата подписи после усовершенствования: %1 |%2'"), Результат, СвойстваСертификатаСтрокой(ПараметрыПодписи.СертификатПоследнейМеткиВремени)); УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСторонеЦиклПослеОшибкиОперацииНаКлиенте(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура ВыполнитьНаСторонеЦиклПослеУсовершенствования(СвойстваПодписи, Контекст) ЭлементДанных = Контекст.ЭлементыДанных[Контекст.Индекс]; Если Контекст.НаСторонеКлиента Тогда НовыеСвойстваПодписи = ЭлектроннаяПодписьКлиентСервер.НовыеСвойстваПодписи(); ОбновитьПодпись = Ложь; Если Контекст.ЭлементДанных.Свойство("НеТребуетсяПродление") Тогда Если ЭлементДанных.ТипПодписи <> СвойстваПодписи.ТипПодписи Тогда ЭлементДанных.ТипПодписи = СвойстваПодписи.ТипПодписи; НовыеСвойстваПодписи.ТипПодписи = СвойстваПодписи.ТипПодписи; ОбновитьПодпись = Истина; КонецЕсли; Если ЭлементДанных.СрокДействияПоследнейМеткиВремени <> СвойстваПодписи.СрокДействияПоследнейМеткиВремени Тогда ЭлементДанных.СрокДействияПоследнейМеткиВремени = СвойстваПодписи.СрокДействияПоследнейМеткиВремени; НовыеСвойстваПодписи.СрокДействияПоследнейМеткиВремени = СвойстваПодписи.СрокДействияПоследнейМеткиВремени; ОбновитьПодпись = Истина; КонецЕсли; Иначе НовыеСвойстваПодписи.Подпись = СвойстваПодписи.Подпись; НовыеСвойстваПодписи.ТипПодписи = СвойстваПодписи.ТипПодписи; НовыеСвойстваПодписи.СрокДействияПоследнейМеткиВремени = СвойстваПодписи.СрокДействияПоследнейМеткиВремени; ОбновитьПодпись = Истина; КонецЕсли; ЭлементДанных.Вставить("СвойстваПодписи", НовыеСвойстваПодписи); Если Не ЭлементДанных.Свойство("ПодписанныйОбъект") Тогда УсовершенствоватьНаСторонеЦиклНачало(Контекст); Возврат; КонецЕсли; Если ОбновитьПодпись Тогда ЭлементДанных.СвойстваПодписи.ПодписанныйОбъект = ЭлементДанных.ПодписанныйОбъект; ЭлементДанных.СвойстваПодписи.ПорядковыйНомер = ЭлементДанных.ПорядковыйНомер; ПредставлениеОшибки = ЭлектроннаяПодписьСлужебныйВызовСервера.ОбновитьУсовершенствованнуюПодпись( ЭлементДанных.СвойстваПодписи); Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ЭлементДанных.Удалить("СвойстваПодписи"); Ошибка = ОписаниеОшибкиПриУсовершенствовании(); Ошибка.Текст = ПредставлениеОшибки; УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст); Возврат; КонецЕсли; Если ЗначениеЗаполнено(ЭлементДанных.СвойстваПодписи.Подпись) Тогда ЭлектроннаяПодписьСлужебныйВызовСервера.ЗарегистрироватьУсовершенствованиеПодписиВЖурнале( ЭлементДанных.СвойстваПодписи); КонецЕсли; КонецЕсли; Иначе ЭлементДанных.Вставить("СвойстваПодписи", СвойстваПодписи); КонецЕсли; ОповеститьОбИзменении(ЭлементДанных.ПодписанныйОбъект); УсовершенствоватьНаСторонеЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСторонеПослеОшибки(Ошибка, Контекст) Контекст.ЕстьОшибки = Истина; ЭлементДанных = Контекст.ЭлементыДанных[Контекст.Индекс]; Если Не ЭлементДанных.Свойство("Ошибка") Тогда ЭлементДанных.Вставить("Ошибка", ""); КонецЕсли; ТекстОшибки = Ошибка.Текст; Если Не Контекст.ПрерыватьОбработкуМассиваПриОшибке Тогда Если Ошибка.ОшибкаСозданияМенеджераКриптографии Тогда ОшибкиСозданияМенеджераКриптографии = Контекст.ОшибкиСозданияМенеджераКриптографии; Если ОшибкиСозданияМенеджераКриптографии.Найти(ТекстОшибки) = Неопределено Тогда ОшибкиСозданияМенеджераКриптографии.Добавить(ТекстОшибки); КонецЕсли; КонецЕсли; ЭлементДанных.Ошибка = ЭлементДанных.Ошибка + ?(ЭлементДанных.Ошибка <> "", Символы.ПС, "") + ?(Ошибка.НаКлиенте, НСтр("ru='На компьютере:'"), НСтр("ru='На сервере:'")) + " " + Ошибка.Текст; Иначе ЭлементДанных.Ошибка = ЭлементДанных.Ошибка + ?(ЭлементДанных.Ошибка <> "", Символы.ПС, "") + ?(Ошибка.НаКлиенте, НСтр("ru='На компьютере:'"), НСтр("ru='На сервере:'")) + " " + Ошибка.Текст; КонецЕсли; Если Контекст.ПрерыватьОбработкуМассиваПриОшибке Тогда УсовершенствоватьНаСторонеПослеЦикла(Контекст, ТекстОшибки); Иначе УсовершенствоватьНаСторонеЦиклНачало(Контекст); КонецЕсли; КонецПроцедуры // Для процедуры УсовершенствоватьНаСтороне. Функция ОписаниеОшибкиПриУсовершенствовании(ОшибкаНаКлиенте = Истина) Возврат Новый Структура("НаКлиенте, Текст, ОшибкаСозданияМенеджераКриптографии", ОшибкаНаКлиенте, "", Ложь); КонецФункции // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьНаСторонеПослеЦикла(Контекст, ТекстОшибки = Неопределено) Результат = Новый Структура; Если Контекст.ЕстьОшибки Или Не Контекст.ОперацияНачалась Тогда Результат.Вставить("Ошибка", Истина); Если Контекст.ЭлементыДанных.Количество() = 0 Тогда Результат.Вставить("ТекстОшибки", НСтр("ru='Нет подписей для обработки.'")); Иначе НетПодписейДляОбработки = Истина; Для Каждого ЭлементДанных Из Контекст.ЭлементыДанных Цикл Если Не ЭлементДанных.Свойство("НеТребуетсяПродление") Тогда НетПодписейДляОбработки = Ложь; Прервать; КонецЕсли; КонецЦикла; НачалоОшибки = ?(Контекст.НаСторонеКлиента, НСтр("ru='На компьютере:'"), НСтр("ru='На сервере:'")); Если Контекст.ОшибкиСозданияМенеджераКриптографии.Количество() > 0 Тогда Результат.Вставить("ТекстОшибки", НачалоОшибки + Символы.ПС + СтрСоединить(Контекст.ОшибкиСозданияМенеджераКриптографии, Символы.ПС)); ИначеЕсли НетПодписейДляОбработки Тогда Результат.Вставить("ТекстОшибки", НСтр("ru='Нет подписей для обработки.'")); Иначе Результат.Вставить("ТекстОшибки", НачалоОшибки + Символы.ПС + НСтр("ru='Есть ошибки при продлении подписей'")); КонецЕсли; КонецЕсли; КонецЕсли; Результат.Вставить("ЭлементыДанных", Контекст.ЭлементыДанных); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьПослеВыполненияНаСторонеСервера(Результат, Контекст) Экспорт Если Результат <> Неопределено И Не Результат.Свойство("Ошибка") Тогда УсовершенствоватьПослеВыполненияНаСторонеКлиента(Результат, Контекст); Иначе Если Результат <> Неопределено Тогда Контекст.ПараметрыВыполнения.Вставить("ЭлементыДанных", Результат.ЭлементыДанных); Контекст.ПараметрыВыполнения.Вставить("ТекстОшибки", Результат.ТекстОшибки); КонецЕсли; УсовершенствоватьНаСтороне(Новый ОписаниеОповещения( "УсовершенствоватьПослеВыполненияНаСторонеКлиента", ЭтотОбъект, Контекст), "НаСторонеКлиента", Контекст.ПараметрыВыполнения); КонецЕсли; КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Процедура УсовершенствоватьПослеВыполненияНаСторонеКлиента(Результат, Контекст) Экспорт РезультатОбработки = Новый Структура("Успех, ТекстОшибки, СвойстваПодписей"); Если Результат.Свойство("Ошибка") Тогда РезультатОбработки.Успех = Ложь; РезультатОбработки.ТекстОшибки = Результат.ТекстОшибки; Иначе РезультатОбработки.Успех = Истина; КонецЕсли; Если Контекст.ОбработкаРезультата = Неопределено Тогда Возврат; КонецЕсли; Если Результат.Свойство("ЭлементыДанных") Тогда РезультатОбработки.СвойстваПодписей = Результат.ЭлементыДанных; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.ОбработкаРезультата, РезультатОбработки); КонецПроцедуры // Продолжение процедуры УсовершенствоватьНаСтороне. Функция СвойстваСертификатаСтрокой(Сертификат) Если Сертификат = Неопределено Тогда Возврат ""; КонецЕсли; СвойстваСертификата = ЭлектроннаяПодписьКлиент.СвойстваСертификата(Сертификат); СведенияОСертификате = ЭлектроннаяПодписьСлужебныйКлиентСервер.СведенияОСертификатеСтрокой(СвойстваСертификата); Возврат СведенияОСертификате; КонецФункции #КонецОбласти //////////////////////////////////////////////////////////////////////////////// // Работа с XMLDSig // Начинает подписание XML сообщения. // // Параметры: // ОповещенияПриЗавершении - Структура: // * Успех - ОписаниеОповещения - процедура, которая будет вызвана после подписания. // * Ошибка - ОписаниеОповещения - процедура, которая будет вызвана при ошибке подписания. // КонвертXML - см. ЭлектроннаяПодписьКлиент.КонвертXML // ПараметрыXMLDSig - см. ЭлектроннаяПодписьКлиент.ПараметрыXMLDSig // СертификатКриптографии - СертификатКриптографии // МенеджерКриптографии - МенеджерКриптографии // Процедура НачатьВыгрузкуСертификатаКриптографииДляПодписанияXMLDSig(ОповещенияПриЗавершении, КонвертXML, ПараметрыXMLDSig, СертификатКриптографии, МенеджерКриптографии) СвойстваКонвертаXML = ЭлектроннаяПодписьСлужебныйВызовСервера.СвойстваКонвертаXML(КонвертXML, ПараметрыXMLDSig, Ложь); ДанныеАлгоритмаПодписания = Новый Структура(Новый ФиксированнаяСтруктура(ПараметрыXMLDSig)); Контекст = Новый Структура; Контекст.Вставить("Режим", "РежимПодписание"); Контекст.Вставить("ТипПодписи", "XMLDSig"); Контекст.Вставить("ОповещенияПриЗавершении", ОповещенияПриЗавершении); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("КонвертXML", КонвертXML); Контекст.Вставить("СвойстваКонвертаXML", СвойстваКонвертаXML); Контекст.Вставить("ДанныеАлгоритмаПодписания", ДанныеАлгоритмаПодписания); Контекст.Вставить("СертификатКриптографии", СертификатКриптографии); Контекст.Вставить("СертификатКриптографииBase64", Неопределено); Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Контекст.Вставить("ТипКриптопровайдера", Неопределено); Контекст.Вставить("ИмяКриптопровайдера", Неопределено); Контекст.Вставить("ПутьКриптопровайдера", Неопределено); Если СвойстваКонвертаXML <> Неопределено И ЗначениеЗаполнено(СвойстваКонвертаXML.ТекстОшибки) Тогда ЗавершитьОперациюСОшибкой(Контекст, СвойстваКонвертаXML.ТекстОшибки); Возврат; КонецЕсли; СертификатКриптографии.НачатьВыгрузку( Новый ОписаниеОповещения("НачатьПодписание_ПослеВыгрузкиСертификатаКриптографии", ЭтотОбъект, Контекст)); КонецПроцедуры // Начинает проверку подписи XML сообщения. // // Параметры: // ОповещенияПриЗавершении - Структура: // * Успех - ОписаниеОповещения - процедура, которая будет вызвана после проверки подписи. // * Ошибка - ОписаниеОповещения - процедура, которая будет вызвана при ошибке проверки подписи. // КонвертXML - см. ЭлектроннаяПодписьКлиент.КонвертXML // ПараметрыXMLDSig - см. ЭлектроннаяПодписьКлиент.ПараметрыXMLDSig // СвойстваКонвертаXML - см. ЭлектроннаяПодписьСлужебный.СвойстваКонвертаXML // МенеджерКриптографии - МенеджерКриптографии // Процедура НачатьИнициализациюСертификатаКриптографииДляПроверкиПодписиXMLDSig(ОповещенияПриЗавершении, КонвертXML, ПараметрыXMLDSig, СвойстваКонвертаXML, МенеджерКриптографии) Если СвойстваКонвертаXML = Неопределено Тогда СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатИзКонвертаSOAP(КонвертXML); Иначе СертификатКриптографииBase64 = СвойстваКонвертаXML.Сертификат.ЗначениеСертификата; КонецЕсли; ДвоичныеДанные = Base64Значение(СертификатКриптографииBase64); ДанныеАлгоритмаПодписания = Новый Структура(Новый ФиксированнаяСтруктура(ПараметрыXMLDSig)); Контекст = Новый Структура; Контекст.Вставить("Режим", "РежимПроверка"); Контекст.Вставить("ТипПодписи", "XMLDSig"); Контекст.Вставить("ОповещенияПриЗавершении", ОповещенияПриЗавершении); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("КонвертXML", КонвертXML); Контекст.Вставить("СвойстваКонвертаXML", СвойстваКонвертаXML); Контекст.Вставить("ДанныеАлгоритмаПодписания", ДанныеАлгоритмаПодписания); Контекст.Вставить("СертификатКриптографии", Новый СертификатКриптографии); Контекст.Вставить("СертификатКриптографииBase64", СертификатКриптографииBase64); Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Контекст.Вставить("ТипКриптопровайдера", Неопределено); Контекст.Вставить("ИмяКриптопровайдера", Неопределено); Контекст.Вставить("ПутьКриптопровайдера", Неопределено); Контекст.СертификатКриптографии.НачатьИнициализацию(Новый ОписаниеОповещения( "НачатьПроверкуПодписиПослеИнициализацииСертификата", ЭтотОбъект, Контекст), ДвоичныеДанные); КонецПроцедуры // Начинает подписание CMS сообщения. Процедура НачатьВыгрузкуСертификатаКриптографииДляПодписанияCMS(ОповещенияПриЗавершении, Данные, ПараметрыCMS, СертификатКриптографии, МенеджерКриптографии) Контекст = Новый Структура; Контекст.Вставить("Режим", "РежимПодписание"); Контекст.Вставить("ТипПодписи", "CMS"); Контекст.Вставить("ОповещенияПриЗавершении", ОповещенияПриЗавершении); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("Данные", Данные); Контекст.Вставить("ПараметрыCMS", ПараметрыCMS); Контекст.Вставить("СертификатКриптографии", СертификатКриптографии); Контекст.Вставить("СертификатКриптографииBase64", Неопределено); Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Контекст.Вставить("ТипКриптопровайдера", Неопределено); Контекст.Вставить("ИмяКриптопровайдера", Неопределено); Контекст.Вставить("ПутьКриптопровайдера", Неопределено); СертификатКриптографии.НачатьВыгрузку( Новый ОписаниеОповещения("НачатьПодписаниеCMS_ПослеВыгрузкиСертификатаКриптографии", ЭтотОбъект, Контекст)); КонецПроцедуры // Начинает проверку подписи CMS сообщения. Процедура НачатьИнициализациюСертификатаКриптографииДляПроверкиПодписиCMS(ОповещенияПриЗавершении, Подпись, Данные, ПараметрыCMS, МенеджерКриптографии) Контекст = Новый Структура; Контекст.Вставить("Режим", "РежимПроверка"); Контекст.Вставить("ТипПодписи", "CMS"); Контекст.Вставить("ОповещенияПриЗавершении", ОповещенияПриЗавершении); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("Данные", Данные); Контекст.Вставить("Подпись", Подпись); Контекст.Вставить("ПараметрыCMS", ПараметрыCMS); Контекст.Вставить("СертификатКриптографии", Неопределено); Контекст.Вставить("МенеджерКриптографии", МенеджерКриптографии); Контекст.Вставить("ТипКриптопровайдера", Неопределено); Контекст.Вставить("ИмяКриптопровайдера", Неопределено); Контекст.Вставить("ПутьКриптопровайдера", Неопределено); НачатьПроверкуПодписиПослеИнициализацииСертификата(Неопределено, Контекст); КонецПроцедуры Процедура НачатьПроверкуПодписиПослеИнициализацииСертификата(СертификатКриптографии, Контекст) Экспорт Контекст.СертификатКриптографии = СертификатКриптографии; ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для проверки подписи %1 необходима установка компоненты %2'"), ?(Контекст.ТипПодписи = "CMS", "CMS", "XML"), "ExtraCryptoAPI"); ПодключитьКомпоненту(Контекст, ТекстПояснения); КонецПроцедуры Процедура ПодключитьКомпоненту(Контекст, ТекстПояснения) ПараметрыПодключения = ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты(); ПараметрыПодключения.ТекстПояснения = ТекстПояснения; ПараметрыПодключения.ПредложитьЗагрузить = Истина; ОписаниеКомпоненты = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеКомпоненты(); ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета( Новый ОписаниеОповещения("ПослеПодключенияКомпоненты", ЭтотОбъект, Контекст), ОписаниеКомпоненты.ИмяОбъекта, ОписаниеКомпоненты.ПолноеИмяМакета, ПараметрыПодключения); КонецПроцедуры Процедура ПослеПодключенияКомпоненты(Результат, Контекст) Экспорт Если Результат.Подключено Тогда Контекст.Вставить("ОбъектКомпоненты", Результат.ПодключаемыйМодуль); ПослеПодключенияКомпонентыНастроитьКомпоненту(Контекст); Иначе Если ПустаяСтрока(Результат.ОписаниеОшибки) Тогда // Пользователь отказался от установки. ЗавершитьОперациюСОшибкой( Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Операция невозможна. Требуется установка компоненты %1.'"), "ExtraCryptoAPI")); Иначе // Установка не удалась, описание ошибки в Результат.ОписаниеОшибки. ЗавершитьОперациюСОшибкой( Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Операция невозможна. %1'"), Результат.ОписаниеОшибки)); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ПослеПодключенияКомпонентыНастроитьКомпоненту(Контекст) Оповещение = Новый ОписаниеОповещения( "ПослеПодключенияКомпонентыПослеУстановкиСоответствиеOID", ЭтотОбъект, Контекст, "ПослеПодключенияКомпонентыПослеОшибкиУстановкиСоответствиеOID", ЭтотОбъект); Контекст.ОбъектКомпоненты.НачатьУстановкуСоответствиеOID(Оповещение, ЭлектроннаяПодписьСлужебныйКлиентСервер.ИдентификаторыАлгоритмовХешированияИОткрытогоКлюча()); КонецПроцедуры Процедура ПослеПодключенияКомпонентыПослеУстановкиСоответствиеOID(Контекст) Экспорт Контекст.МенеджерКриптографии.НачатьПолучениеИнформацииМодуляКриптографии( Новый ОписаниеОповещения("ПослеПолученияИнформацииМодуляКриптографии", ЭтотОбъект, Контекст)); КонецПроцедуры Процедура ПослеПодключенияКомпонентыПослеОшибкиУстановкиСоответствиеOID(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить свойство %1 компоненты %2 по причине: |%3'"), "СоответствиеOID", "ExtraCryptoAPI", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке))); КонецПроцедуры // Параметры: // ИнформацияМодуляКриптографии - ИнформацияМодуляКриптографии // Контекст - Структура // Асинх Процедура ПослеПолученияИнформацииМодуляКриптографии(ИнформацияМодуляКриптографии, Контекст) Экспорт ИмяКриптопровайдера = ИнформацияМодуляКриптографии.Имя; ОписаниеОшибки = ""; КриптопровайдерыРезультат = Ждать УстановленныеКриптопровайдерыИзКэша(); ПрограммыАвто = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатПоискаКриптопровайдеров(КриптопровайдерыРезультат); Если ТипЗнч(ПрограммыАвто) = Тип("Строка") Тогда ОписаниеОшибки = ПрограммыАвто; ПрограммыАвто = Неопределено; КонецЕсли; ОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеПрограммыПоИмениКриптопровайдера( ИмяКриптопровайдера, ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ОписанияПрограмм, ПрограммыАвто); // см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы Если ОписаниеПрограммы = Неопределено Тогда Если Не ПустаяСтрока(ОписаниеОшибки) Тогда ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось определить тип криптопровайдера %1. %2'"), ИнформацияМодуляКриптографии.Имя, ОписаниеОшибки)); Иначе ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось определить тип криптопровайдера %1'"), ИнформацияМодуляКриптографии.Имя)); КонецЕсли; Возврат; КонецЕсли; Контекст.ТипКриптопровайдера = ОписаниеПрограммы.ТипПрограммы; Контекст.ИмяКриптопровайдера = ИмяКриптопровайдера; Если ОписаниеПрограммы.Свойство("Автоопределение") Тогда ОписаниеПути = Новый Структура("ПутьКПрограмме, Существует", ОписаниеПрограммы.ПутьКПрограммеАвто, Истина); ПослеПолученияПутиКПрограмме(ОписаниеПути, Контекст); Возврат; КонецЕсли; ПолучитьПутьКПрограмме(Новый ОписаниеОповещения("ПослеПолученияПутиКПрограмме", ЭтотОбъект, Контекст), ОписаниеПрограммы.Ссылка); КонецПроцедуры Процедура ПослеПолученияПутиКПрограмме(ОписаниеПути, Контекст) Экспорт Контекст.ПутьКриптопровайдера = ОписаниеПути.ПутьКПрограмме; Оповещение = Новый ОписаниеОповещения( "ПослеУстановкиСвойстваКомпонентыПутьККриптопровайдеру", ЭтотОбъект, Контекст); Контекст.ОбъектКомпоненты.НачатьУстановкуПутьККриптопровайдеру(Оповещение, Контекст.ПутьКриптопровайдера); КонецПроцедуры Процедура ПослеУстановкиСвойстваКомпонентыПутьККриптопровайдеру(Контекст) Экспорт Если Не ТребуетсяПутьКПрограмме() Тогда Оповещение = Новый ОписаниеОповещения( "ПослеУстановкиСвойстваЗапретитьПользовательскийИнтерфейс", ЭтотОбъект, Контекст); Контекст.ОбъектКомпоненты.НачатьУстановкуЗапретитьПользовательскийИнтерфейс(Оповещение, Не ИспользуетсяИнтерактивныйРежимКриптографии(Контекст.МенеджерКриптографии)); Иначе ПослеУстановкиСвойстваЗапретитьПользовательскийИнтерфейс(Контекст); КонецЕсли; КонецПроцедуры Процедура ПослеУстановкиСвойстваЗапретитьПользовательскийИнтерфейс(Контекст) Экспорт Если Контекст.ТипПодписи = "XMLDSig" Тогда Если Контекст.Режим = "РежимПроверка" Тогда НачатьПроверкуПодписиXMLDSig(Контекст); ИначеЕсли Контекст.Режим = "РежимПодписание" Тогда НачатьПодписаниеXMLDSig(Контекст); Иначе ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не установлен режим работы компоненты %1.'"), "ExtraCryptoAPI")); КонецЕсли; ИначеЕсли Контекст.ТипПодписи = "CMS" Тогда Если Контекст.Режим = "РежимПроверка" Тогда НачатьПроверкуПодписиCMS(Контекст); ИначеЕсли Контекст.Режим = "РежимПодписание" Тогда НачатьПодписаниеCMS(Контекст); Иначе ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не установлен режим работы компоненты %1.'"), "ExtraCryptoAPI")); КонецЕсли; Иначе ЗавершитьОперациюСОшибкой(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не установлен тип подписи компоненты %1.'"), "ExtraCryptoAPI")); КонецЕсли; КонецПроцедуры Процедура НачатьПодписание_ПослеВыгрузкиСертификатаКриптографии(ДвоичныеДанныеСертификата, Контекст) Экспорт Контекст.СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатКриптографииBase64( ДвоичныеДанныеСертификата); ПодключитьКомпоненту(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для подписания XML необходима установка компоненты %1'"), "ExtraCryptoAPI")); КонецПроцедуры Процедура НачатьПодписаниеCMS_ПослеВыгрузкиСертификатаКриптографии(ДвоичныеДанныеСертификата, Контекст) Экспорт Контекст.СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатКриптографииBase64( ДвоичныеДанныеСертификата); ПодключитьКомпоненту(Контекст, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для подписания CMS необходима установка компоненты %1'"), "ExtraCryptoAPI")); КонецПроцедуры Процедура НачатьПодписаниеCMS(Контекст) ПараметрыCMSSign = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПараметрыКомпонентыCMSSign( Контекст.ПараметрыCMS, Контекст.Данные); Оповещение = Новый ОписаниеОповещения( "Подписание_ПослеВыполненияCMSSign", ЭтотОбъект, Контекст, "Подписание_ПослеВыполненияCMSSign_Ошибка", ЭтотОбъект); Попытка Контекст.ОбъектКомпоненты.НачатьВызовCMSSign(Оповещение, ПараметрыCMSSign.Данные, Контекст.СертификатКриптографииBase64, Контекст.МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу, ПараметрыCMSSign.ТипПодписи, ПараметрыCMSSign.Открепленная, ПараметрыCMSSign.ВключениеСертификатовВПодпись); Исключение ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("CMSSign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); КонецПопытки; КонецПроцедуры Процедура Подписание_ПослеВыполненияCMSSign_Ошибка(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("CMSSign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке))); КонецПроцедуры Процедура Подписание_ПослеВыполненияCMSSign(АтрибутSignatureValue, Параметры, Контекст) Экспорт Если Не ЗначениеЗаполнено(АтрибутSignatureValue) Тогда НачатьПолучениеТекстаОшибки(НачалоОписанияТекстаОшибки("CMSSign"), Контекст); Возврат; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.ОповещенияПриЗавершении.Успех, АтрибутSignatureValue); КонецПроцедуры Процедура НачатьПроверкуПодписиCMS(Контекст) ПараметрыCMSSign = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПараметрыКомпонентыCMSSign( Контекст.ПараметрыCMS, Контекст.Данные); Оповещение = Новый ОписаниеОповещения( "Проверка_ПослеВыполненияCMSVerifySign", ЭтотОбъект, Контекст, "Проверка_ПослеВыполненияCMSVerifySign_Ошибка", ЭтотОбъект); Попытка Контекст.ОбъектКомпоненты.НачатьВызовCMSVerifySign(Оповещение, Контекст.Подпись, ПараметрыCMSSign.Открепленная, Контекст.Данные, Контекст.ТипКриптопровайдера, Null); Исключение ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("CMSVerifySign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); КонецПопытки; КонецПроцедуры Процедура Проверка_ПослеВыполненияCMSVerifySign_Ошибка(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("CMSVerifySign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке))); КонецПроцедуры Процедура Проверка_ПослеВыполненияCMSVerifySign(ПодписьВерна, Параметры, Контекст) Экспорт Если ПодписьВерна <> Истина Тогда НачатьПолучениеТекстаОшибки(НачалоОписанияТекстаОшибки("CMSVerifySign"), Контекст); Возврат; КонецЕсли; Если ТипЗнч(Параметры[4]) = Тип("ДвоичныеДанные") Тогда Контекст.СертификатКриптографии = Параметры[4]; Иначе ЗавершитьОперациюСОшибкой(Контекст, НСтр("ru = 'Подпись верна, но не содержит данных сертификата.'")); Возврат; КонецЕсли; ЭлектроннаяПодписьКлиент.ДатаПодписания( Новый ОписаниеОповещения("Проверка_ПослеВыполненияHash_ПодписываемыйТегПослеПолученияДатыПодписания", ЭтотОбъект, Контекст), Контекст.Подпись); КонецПроцедуры Асинх Процедура НачатьПодписаниеXMLDSig(Контекст) Попытка КонвертXML = Ждать ПодписатьXMLDSig(Контекст); ВыполнитьОбработкуОповещения(Контекст.ОповещенияПриЗавершении.Успех, КонвертXML); Исключение ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); ЗавершитьОперациюСОшибкой(Контекст, ТекстОшибки); КонецПопытки; КонецПроцедуры Асинх Функция ПодписатьXMLDSig(Контекст) Пароль = Контекст.МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу; ОбъектКомпоненты = Контекст.ОбъектКомпоненты; КонвертXML = Контекст.КонвертXML; СвойстваКонвертаXML = Контекст.СвойстваКонвертаXML; Если СвойстваКонвертаXML <> Неопределено И ЗначениеЗаполнено(СвойстваКонвертаXML.ТекстОшибки) Тогда ВызватьИсключение СвойстваКонвертаXML.ТекстОшибки; КонецЕсли; СертификатКриптографииBase64 = Контекст.СертификатКриптографииBase64; ДанныеАлгоритмаПодписания = Контекст.ДанныеАлгоритмаПодписания; ЭлектроннаяПодписьСлужебныйКлиентСервер.ПроверитьВыбратьАлгоритмПодписи( СертификатКриптографииBase64, ДанныеАлгоритмаПодписания, Истина, СвойстваКонвертаXML); КонвертXML = СтрЗаменить(КонвертXML, "%BinarySecurityToken%", СертификатКриптографииBase64); КонвертXML = СтрЗаменить(КонвертXML, "%SignatureMethod%", ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмПодписи); КонвертXML = СтрЗаменить(КонвертXML, "%DigestMethod%", ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмХеширования); Если СвойстваКонвертаXML <> Неопределено Тогда Для Индекс = 0 По СвойстваКонвертаXML.ХешируемыеОбласти.ВГраница() Цикл ХешируемаяОбласть = СвойстваКонвертаXML.ХешируемыеОбласти[Индекс]; КанонизированныйТекстXMLBody = Ждать КанонизированныйТекстXML(ОбъектКомпоненты, СвойстваКонвертаXML.ОбластиBody[Индекс], ХешируемаяОбласть.АлгоритмыТрансформации); АтрибутDigestValue = Ждать РезультатHash(ОбъектКомпоненты, КанонизированныйТекстXMLBody, ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования, Контекст.ТипКриптопровайдера); КонвертXML = СтрЗаменить(КонвертXML, ХешируемаяОбласть.ЗначениеХеша, АтрибутDigestValue); КонецЦикла; Иначе КанонизированныйТекстXMLBody = Ждать C14NАсинх(ОбъектКомпоненты, КонвертXML, ДанныеАлгоритмаПодписания.XPathПодписываемыйТег); АтрибутDigestValue = Ждать РезультатHash(ОбъектКомпоненты, КанонизированныйТекстXMLBody, ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования, Контекст.ТипКриптопровайдера); КонвертXML = СтрЗаменить(КонвертXML, "%DigestValue%", АтрибутDigestValue); КонецЕсли; Если СвойстваКонвертаXML = Неопределено Тогда КанонизированныйТекстXMLSignedInfo = Ждать C14NАсинх(ОбъектКомпоненты, КонвертXML, ДанныеАлгоритмаПодписания.XPathSignedInfo); Иначе ОбластьSignedInfo = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбластьXML(КонвертXML, СвойстваКонвертаXML.ОбластьSignedInfo.ИмяЭлемента); ОбластьSignedInfo.ПространстваИменДоУзла = СвойстваКонвертаXML.ОбластьSignedInfo.ПространстваИменДоУзла; Если ЗначениеЗаполнено(ОбластьSignedInfo.ТекстОшибки) Тогда ВызватьИсключение ОбластьSignedInfo.ТекстОшибки; КонецЕсли; КанонизированныйТекстXMLSignedInfo = Ждать КанонизированныйТекстXML(ОбъектКомпоненты, ОбластьSignedInfo, ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(СвойстваКонвертаXML.АлгоритмКанонизации)); КонецЕсли; АтрибутSignatureValue = Ждать РезультатSign(ОбъектКомпоненты, КанонизированныйТекстXMLSignedInfo, Контекст.СертификатКриптографии, Пароль); КонвертXML = СтрЗаменить(КонвертXML, "%SignatureValue%", АтрибутSignatureValue); Возврат КонвертXML; КонецФункции Асинх Функция РезультатHash(ОбъектКомпоненты, КанонизированныйТекстXMLBody, OIDАлгоритмаХеширования, ТипКриптопровайдера) Попытка Результат = Ждать ОбъектКомпоненты.HashАсинх( КанонизированныйТекстXMLBody, OIDАлгоритмаХеширования, ТипКриптопровайдера); АтрибутDigestValue = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("Hash", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если АтрибутDigestValue = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("Hash", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат АтрибутDigestValue; КонецФункции Асинх Функция РезультатSign(ОбъектКомпоненты, КанонизированныйТекстXMLSignedInfo, СертификатКриптографии, ПарольДоступаКЗакрытомуКлючу) СертификатКриптографииBase64 = Ждать СертификатКриптографии.ВыгрузитьАсинх(); СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатКриптографииBase64( СертификатКриптографииBase64); Попытка Результат = Ждать ОбъектКомпоненты.SignАсинх( КанонизированныйТекстXMLSignedInfo, СертификатКриптографииBase64, ПарольДоступаКЗакрытомуКлючу); АтрибутSignatureValue = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("Sign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если АтрибутSignatureValue = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("Sign", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат АтрибутSignatureValue; КонецФункции Асинх Процедура НачатьПроверкуПодписиXMLDSig(Контекст) ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПроверитьВыбратьАлгоритмПодписи( Контекст.СертификатКриптографииBase64, Контекст.ДанныеАлгоритмаПодписания, , Контекст.СвойстваКонвертаXML); Если ЗначениеЗаполнено(ТекстОшибки) Тогда ЗавершитьОперациюСОшибкой(Контекст, ТекстОшибки); Возврат; КонецЕсли; Попытка Результат = Ждать ПроверитьПодписьXMLDSig(Контекст); ВыполнитьОбработкуОповещения(Контекст.ОповещенияПриЗавершении.Успех, Результат); Исключение ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); ЗавершитьОперациюСОшибкой(Контекст, ТекстОшибки); КонецПопытки; КонецПроцедуры Асинх Функция ПроверитьПодписьXMLDSig(Контекст) ОбъектКомпоненты = Контекст.ОбъектКомпоненты; ДанныеАлгоритмаПодписания = Контекст.ДанныеАлгоритмаПодписания; КонвертXML = Контекст.КонвертXML; СвойстваКонвертаXML = Контекст.СвойстваКонвертаXML; Если СвойстваКонвертаXML = Неопределено Тогда КанонизированныйТекстXMLSignedInfo = Ждать C14NАсинх(ОбъектКомпоненты, КонвертXML, ДанныеАлгоритмаПодписания.XPathSignedInfo); КанонизированныйТекстXMLBody = Ждать C14NАсинх(ОбъектКомпоненты, КонвертXML, ДанныеАлгоритмаПодписания.XPathПодписываемыйТег); СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатИзКонвертаSOAP(КонвертXML); ЗначениеПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.НайтиВXML(КонвертXML, "SignatureValue"); ЗначениеХеша = ЭлектроннаяПодписьСлужебныйКлиентСервер.НайтиВXML(КонвертXML, "DigestValue"); Иначе КанонизированныйТекстXMLSignedInfo = Ждать КанонизированныйТекстXML(ОбъектКомпоненты, СвойстваКонвертаXML.ОбластьSignedInfo, ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(СвойстваКонвертаXML.АлгоритмКанонизации)); ЗначениеПодписи = СвойстваКонвертаXML.ЗначениеПодписи; СертификатКриптографииBase64 = СвойстваКонвертаXML.Сертификат.ЗначениеСертификата; ЭлектроннаяПодписьСлужебныйКлиентСервер.ПроверитьВыбратьАлгоритмПодписи( СертификатКриптографииBase64, ДанныеАлгоритмаПодписания, Истина, СвойстваКонвертаXML); КонецЕсли; ПодписьВерна = Ждать РезультатVerifySign(ОбъектКомпоненты, КанонизированныйТекстXMLSignedInfo, ЗначениеПодписи, СертификатКриптографииBase64, Контекст.ТипКриптопровайдера); Если СвойстваКонвертаXML <> Неопределено Тогда Счетчик = 1; Для Каждого ХешируемаяОбласть Из СвойстваКонвертаXML.ХешируемыеОбласти Цикл КанонизированныйТекстXMLBody = Ждать КанонизированныйТекстXML(ОбъектКомпоненты, СвойстваКонвертаXML.ОбластиBody[Счетчик-1], ХешируемаяОбласть.АлгоритмыТрансформации); ЗначениеХеша = ХешируемаяОбласть.ЗначениеХеша; АтрибутDigestValue = Ждать РезультатHash(ОбъектКомпоненты, КанонизированныйТекстXMLBody, ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования, Контекст.ТипКриптопровайдера); ХешСовпадает = (АтрибутDigestValue = ЗначениеХеша); Если Не ХешСовпадает Или Не ПодписьВерна Тогда ВызватьИсключение ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиПроверкиПодписиXML(ПодписьВерна, ХешСовпадает); КонецЕсли; Счетчик = Счетчик + 1; КонецЦикла; Возврат Ждать РезультатПроверкиПодписиXML(СертификатКриптографииBase64); КонецЕсли; АтрибутDigestValue = Ждать РезультатHash(ОбъектКомпоненты, КанонизированныйТекстXMLBody, ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования, Контекст.ТипКриптопровайдера); ХешСовпадает = (АтрибутDigestValue = ЗначениеХеша); Если ХешСовпадает И ПодписьВерна Тогда Возврат Ждать РезультатПроверкиПодписиXML(СертификатКриптографииBase64); Иначе ВызватьИсключение ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиПроверкиПодписиXML(ПодписьВерна, ХешСовпадает); КонецЕсли; КонецФункции Асинх Функция РезультатПроверкиПодписиXML(СертификатКриптографииBase64) ДвоичныеДанные = Base64Значение(СертификатКриптографииBase64); СертификатКриптографии = Новый СертификатКриптографии; Ждать СертификатКриптографии.ИнициализироватьАсинх(ДвоичныеДанные); Результат = Новый Структура; Результат.Вставить("Сертификат", СертификатКриптографии); Результат.Вставить("ДатаПодписания", Неопределено); Возврат Результат; КонецФункции Асинх Функция РезультатVerifySign(ОбъектКомпоненты, КанонизированныйТекстXMLSignedInfo, АтрибутSignatureValue, СертификатКриптографииBase64, ТипКриптопровайдера) Попытка Результат = Ждать ОбъектКомпоненты.VerifySignАсинх( КанонизированныйТекстXMLSignedInfo, АтрибутSignatureValue, СертификатКриптографииBase64, ТипКриптопровайдера); ПодписьВерна = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("VerifySign", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если ПодписьВерна = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("VerifySign", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат ПодписьВерна; КонецФункции Процедура Проверка_ПослеВыполненияHash_ПодписываемыйТегПослеПолученияДатыПодписания(ДатаПодписания, Контекст) Экспорт Если Не ЗначениеЗаполнено(ДатаПодписания) Тогда ДатаПодписания = Неопределено; КонецЕсли; ВозвращаемоеЗначение = Новый Структура; ВозвращаемоеЗначение.Вставить("Сертификат", Контекст.СертификатКриптографии); ВозвращаемоеЗначение.Вставить("ДатаПодписания", ДатаПодписания); ВыполнитьОбработкуОповещения(Контекст.ОповещенияПриЗавершении.Успех, ВозвращаемоеЗначение); КонецПроцедуры Асинх Функция C14NАсинх(ОбъектКомпоненты, КонвертXML, XPath) Попытка Результат = Ждать ОбъектКомпоненты.C14NАсинх(КонвертXML, XPath); КанонизированныйТекстXML = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("C14N", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если КанонизированныйТекстXML = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("C14N", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат КанонизированныйТекстXML; КонецФункции Асинх Функция КанонизированныйТекстXML(ОбъектКомпоненты, ОбластьXML, Алгоритмы) Результат = Неопределено; ВышестоящиеПространстваИменДобавлены = Ложь; Для Каждого Алгоритм Из Алгоритмы Цикл Если Алгоритм.Вид = "envsig" Тогда Продолжить; ИначеЕсли Алгоритм.Вид = "c14n" Или Алгоритм.Вид = "smev" Тогда Если Не ВышестоящиеПространстваИменДобавлены Тогда ОписаниеНачалаОбласти = ЭлектроннаяПодписьСлужебныйКлиентСервер.РасширенноеНачалоОбластиXML( ОбластьXML, Алгоритм, Результат); Если ЗначениеЗаполнено(ОписаниеНачалаОбласти.ТекстОшибки) Тогда ВызватьИсключение ОписаниеНачалаОбласти.ТекстОшибки; КонецЕсли; ТекстXML = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОбластиXML(ОбластьXML, ОписаниеНачалаОбласти.Начало); ВышестоящиеПространстваИменДобавлены = Истина; ИначеЕсли Результат = Неопределено Тогда ТекстXML = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОбластиXML(ОбластьXML); Иначе ТекстXML = Результат; КонецЕсли; Если Алгоритм.Вид = "c14n" Тогда Результат = Ждать C14N_body(ОбъектКомпоненты, ТекстXML, Алгоритм); Иначе Результат = Ждать КанонизацияСМЭВ(ОбъектКомпоненты, ТекстXML); КонецЕсли; КонецЕсли; КонецЦикла; Если Результат = Неопределено Тогда Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОбластиXML(ОбластьXML); КонецЕсли; Возврат Результат; КонецФункции Асинх Функция C14N_body(ОбъектКомпоненты, ТекстXML, Алгоритм) Попытка Результат = Ждать ОбъектКомпоненты.c14n_bodyАсинх(ТекстXML, Алгоритм.Версия, Алгоритм.СКомментариями); КанонизированныйТекстXML = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("C14N_body", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если КанонизированныйТекстXML = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("C14N_body", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат КанонизированныйТекстXML; КонецФункции Асинх Функция КанонизацияСМЭВ(ОбъектКомпоненты, ТекстXML) Попытка Результат = Ждать ОбъектКомпоненты.TransformSMEVАсинх(ТекстXML); КанонизированныйТекстXML = Результат.Значение; Исключение ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("TransformSMEV", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВызватьИсключение ТекстОшибки; КонецПопытки; Если КанонизированныйТекстXML = Неопределено Тогда РезультатОшибка = Ждать ОбъектКомпоненты.ПолучитьОшибкуАсинх(); ТекстОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("TransformSMEV", РезультатОшибка.Значение); ВызватьИсключение ТекстОшибки; КонецЕсли; Возврат КанонизированныйТекстXML; КонецФункции Процедура НачатьПолучениеТекстаОшибки(НачалоОписанияТекстаОшибки, Контекст) Контекст.Вставить("НачалоОписанияТекстаОшибки", НачалоОписанияТекстаОшибки); Оповещение = Новый ОписаниеОповещения( "ПослеВыполненияПолучитьОшибку", ЭтотОбъект, Контекст, "ПослеВыполненияПолучитьОшибку_Ошибка", ЭтотОбъект); Попытка Контекст.ОбъектКомпоненты.НачатьВызовПолучитьОшибку(Оповещение); Исключение ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("ПолучитьОшибку", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); КонецПопытки; КонецПроцедуры Процедура ПослеВыполненияПолучитьОшибку_Ошибка(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЗавершитьОперациюСОшибкой(Контекст, ЭлектроннаяПодписьСлужебныйКлиентСервер.ОшибкаВызоваМетодаКомпоненты("ПолучитьОшибку", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке))); КонецПроцедуры Процедура ПослеВыполненияПолучитьОшибку(ТекстОшибки, Параметры, Контекст) Экспорт ЗавершитьОперациюСОшибкой(Контекст, Контекст.НачалоОписанияТекстаОшибки + Символы.ПС + ТекстОшибки); КонецПроцедуры Процедура ЗавершитьОперациюСОшибкой(Контекст, ТекстОшибки) ВыполнитьОбработкуОповещения(Контекст.ОповещенияПриЗавершении.Ошибка, ТекстОшибки); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // Вспомогательные процедуры и функции. // Для процедур УстановитьПарольСертификата, ОткрытьНовуюФорму, ВыборСертификатаДляПодписанияИлиРасшифровки, // ПроверитьСертификатСправочника. // Функция ФормаПередачаПараметров() ИмяПараметра = "СтандартныеПодсистемы.ПараметрыЭлектроннойПодписиИШифрования"; Если ПараметрыПриложения[ИмяПараметра] = Неопределено Тогда ПараметрыПриложения.Вставить(ИмяПараметра, Новый Соответствие); КонецЕсли; Форма = ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыЭлектроннойПодписиИШифрования"].Получить("ФормаПередачаПараметров"); Если Форма = Неопределено Тогда Форма = ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.ПередачаПараметров"); ПараметрыПриложения["СтандартныеПодсистемы.ПараметрыЭлектроннойПодписиИШифрования"].Вставить("ФормаПередачаПараметров", Форма); КонецЕсли; Возврат Форма; КонецФункции // Для процедуры ОбработатьПарольВФорме. Процедура ОбработатьПароль(ВнутренниеДанные, РеквизитПароль, СвойстваПароля, РеквизитЗапомнитьПароль, ДополнительныеПараметры, НовыйПароль = Null) Сертификат = ДополнительныеПараметры.Сертификат; ХранилищеПаролей = ВнутренниеДанные.Получить("ХранилищеПаролей"); Если ХранилищеПаролей = Неопределено Тогда ХранилищеПаролей = Новый Соответствие; ВнутренниеДанные.Вставить("ХранилищеПаролей", ХранилищеПаролей); КонецЕсли; УстановленныеПароли = ВнутренниеДанные.Получить("УстановленныеПароли"); Если УстановленныеПароли = Неопределено Тогда УстановленныеПароли = Новый Соответствие; ВнутренниеДанные.Вставить("УстановленныеПароли", УстановленныеПароли); ВнутренниеДанные.Вставить("ПоясненияУстановленныхПаролей", Новый Соответствие); КонецЕсли; УстановленныйПароль = УстановленныеПароли.Получить(Сертификат); ДополнительныеПараметры.Вставить("ПарольУстановленПрограммно", УстановленныйПароль <> Неопределено); Если УстановленныйПароль <> Неопределено Тогда ДополнительныеПараметры.Вставить("ПояснениеПароля", ВнутренниеДанные.Получить("ПоясненияУстановленныхПаролей").Получить(Сертификат)); КонецЕсли; Если ДополнительныеПараметры.ВводитьПарольВПрограммеЭлектроннойПодписи Тогда СвойстваПароля.Значение = ""; СвойстваПароля.ПарольПроверен = Ложь; РеквизитПароль = ""; Значение = ХранилищеПаролей.Получить(Сертификат); Если Значение <> Неопределено Тогда ХранилищеПаролей.Удалить(Сертификат); Значение = Неопределено; КонецЕсли; ДополнительныеПараметры.Вставить("ПарольВПамяти", Ложь); Возврат; КонецЕсли; Пароль = ХранилищеПаролей.Получить(Сертификат); ДополнительныеПараметры.Вставить("ПарольВПамяти", Пароль <> Неопределено); Если ДополнительныеПараметры.ПриУстановкеПароляИзДругойОперации Тогда РеквизитПароль = ?(СвойстваПароля.Значение <> "", "****************", ""); РеквизитЗапомнитьПароль = ДополнительныеПараметры.ПарольВПамяти; Возврат; КонецЕсли; Если ДополнительныеПараметры.ПриИзмененииРеквизитаПароль Тогда Если РеквизитПароль = "****************" Тогда Возврат; КонецЕсли; СвойстваПароля.Значение = РеквизитПароль; СвойстваПароля.ПарольПроверен = Ложь; РеквизитПароль = ?(СвойстваПароля.Значение <> "", "****************", ""); Возврат; КонецЕсли; Если ДополнительныеПараметры.ПриИзмененииРеквизитаЗапомнитьПароль Тогда Если Не РеквизитЗапомнитьПароль Тогда Значение = ХранилищеПаролей.Получить(Сертификат); Если Значение <> Неопределено Тогда ХранилищеПаролей.Удалить(Сертификат); Значение = Неопределено; КонецЕсли; ДополнительныеПараметры.Вставить("ПарольВПамяти", Ложь); ИначеЕсли СвойстваПароля.ПарольПроверен Тогда ХранилищеПаролей.Вставить(Сертификат, СвойстваПароля.Значение); ДополнительныеПараметры.Вставить("ПарольВПамяти", Истина); КонецЕсли; Возврат; КонецЕсли; Если ДополнительныеПараметры.ПриУспешномВыполненииОперации Тогда Если РеквизитЗапомнитьПароль И НЕ ДополнительныеПараметры.ПарольУстановленПрограммно Тогда ХранилищеПаролей.Вставить(Сертификат, СвойстваПароля.Значение); ДополнительныеПараметры.Вставить("ПарольВПамяти", Истина); СвойстваПароля.ПарольПроверен = Истина; КонецЕсли; Возврат; КонецЕсли; Если ДополнительныеПараметры.ПарольУстановленПрограммно Тогда Если НовыйПароль <> Null Тогда СвойстваПароля.Значение = Строка(НовыйПароль); Иначе СвойстваПароля.Значение = Строка(УстановленныйПароль); КонецЕсли; СвойстваПароля.ПарольПроверен = Ложь; РеквизитПароль = ?(СвойстваПароля.Значение <> "", "****************", ""); Возврат; КонецЕсли; Если НовыйПароль <> Null Тогда // Установка нового пароля к новому сертификату. Если НовыйПароль <> Неопределено Тогда СвойстваПароля.Значение = Строка(НовыйПароль); СвойстваПароля.ПарольПроверен = Истина; НовыйПароль = ""; Если ХранилищеПаролей.Получить(Сертификат) <> Неопределено Или РеквизитЗапомнитьПароль Тогда ХранилищеПаролей.Вставить(Сертификат, СвойстваПароля.Значение); ДополнительныеПараметры.Вставить("ПарольВПамяти", Истина); КонецЕсли; ИначеЕсли ХранилищеПаролей.Получить(Сертификат) <> Неопределено Тогда // Удаление сохраненного пароля из хранилища. РеквизитЗапомнитьПароль = Ложь; ХранилищеПаролей.Удалить(Сертификат); ДополнительныеПараметры.Вставить("ПарольВПамяти", Ложь); КонецЕсли; РеквизитПароль = ?(СвойстваПароля.Значение <> "", "****************", ""); Возврат; КонецЕсли; Если ДополнительныеПараметры.ПриИзмененииСвойствСертификата Тогда Возврат; КонецЕсли; // Получение пароля из хранилища. Значение = ХранилищеПаролей.Получить(Сертификат); ДополнительныеПараметры.Вставить("ПарольВПамяти", Значение <> Неопределено); РеквизитЗапомнитьПароль = ДополнительныеПараметры.ПарольВПамяти; СвойстваПароля.Значение = Строка(Значение); СвойстваПароля.ПарольПроверен = ДополнительныеПараметры.ПарольВПамяти; Значение = Неопределено; РеквизитПароль = ?(СвойстваПароля.Значение <> "", "****************", ""); КонецПроцедуры // Для процедуры НастроитьПредставлениеДанных. Процедура ЗаполнитьСписокПредставлений(СписокПредставлений, ЭлементДанных) ЭлементСписка = Новый Структура("Значение, Представление", Неопределено, ""); СписокПредставлений.Добавить(ЭлементСписка); Если ЭлементДанных.Свойство("Представление") И ТипЗнч(ЭлементДанных.Представление) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ЭлементСписка, ЭлементДанных.Представление); Возврат; КонецЕсли; Если ЭлементДанных.Свойство("Представление") И ТипЗнч(ЭлементДанных.Представление) <> Тип("Строка") Тогда ЭлементСписка.Значение = ЭлементДанных.Представление; ИначеЕсли ЭлементДанных.Свойство("Объект") И ТипЗнч(ЭлементДанных.Объект) <> Тип("ОписаниеОповещения") Тогда ЭлементСписка.Значение = ЭлементДанных.Объект; КонецЕсли; Если ЭлементДанных.Свойство("Представление") Тогда ЭлементСписка.Представление = ЭлементДанных.Представление; КонецЕсли; КонецПроцедуры // Для процедур ПроверитьПодписьПослеСозданияМенеджераКриптографии, // ПолучитьДанныеИзОписанияДанныхПродолжение. // Функция ВключениеСертификатовВПодписьСтрокой(ВключениеСертификатовВПодпись) Если ТипЗнч(ВключениеСертификатовВПодпись) <> Тип("РежимВключенияСертификатовКриптографии") Тогда Возврат ВключениеСертификатовВПодпись; КонецЕсли; Если ВключениеСертификатовВПодпись = РежимВключенияСертификатовКриптографии.НеВключать Тогда Возврат "НеВключать"; ИначеЕсли ВключениеСертификатовВПодпись = РежимВключенияСертификатовКриптографии.ВключатьСертификатСубъекта Тогда Возврат "ВключатьСертификатСубъекта"; Иначе Возврат "ВключатьПолнуюЦепочку"; КонецЕсли; КонецФункции // Для процедур СохранитьСертификатПродолжение, СохранитьЗапросНаСертификатПослеУстановкиРасширения. // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьВМоделиСервиса(Контекст) Если Не ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() Тогда Контекст.Вставить("ПроверитьСертификатНаКлиенте"); ПроверитьПодписьНаКлиентеВМоделиСервиса(Контекст); Возврат; КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеВМоделиСервиса(Контекст) Подпись = Контекст.Подпись; Если ТипЗнч(Подпись) = Тип("Строка") И ЭтоАдресВременногоХранилища(Подпись) Тогда Подпись = ПолучитьИзВременногоХранилища(Подпись); КонецЕсли; Контекст.Вставить("ДанныеПодписи", Подпись); Контекст.Вставить("МенеджерКриптографии", "СервисКриптографии"); МодульСервисКриптографииКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииКлиент"); МодульСервисКриптографииКлиент.ПроверитьПодпись(Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеПроверкиПодписиВМоделиСервиса", ЭтотОбъект, Контекст, "ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи", ЭтотОбъект), Контекст.ДанныеПодписи, Контекст.ИсходныеДанные); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Асинх Процедура ПроверитьПодписьНаКлиентеПослеПроверкиПодписиВМоделиСервиса(Результат, Контекст) Экспорт Если Не Результат.Выполнено Тогда Если ТипЗнч(Контекст.РезультатПроверки) = Тип("Структура") Тогда Контекст.РезультатПроверки.ТребуетсяПроверка = Истина; КонецЕсли; ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи(Результат.ИнформацияОбОшибке, Ложь, Контекст); Возврат; КонецЕсли; Если Не Результат.ПодписьДействительна Тогда ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи( ЭлектроннаяПодписьСлужебныйКлиентСервер.ТекстОшибкиСервисаПодписьНедействительна(), Ложь, Контекст); Возврат; КонецЕсли; ПроверитьПодписьНаКлиентеПослеПроверкиПодписи(Неопределено, Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеВМоделиСервиса(Результат, Контекст) Контекст.Вставить("СертификатКриптографии", Результат); Если Контекст.Операция = "Подписание" Тогда Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись И ЗначениеЗаполнено(Контекст.ОписаниеДанных.ТипПодписи) Тогда Если Контекст.ОписаниеДанных.ТипПодписи <> ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.БазоваяCAdESBES") И Контекст.ОписаниеДанных.ТипПодписи <> ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.ОбычнаяCMS") Тогда Ошибка = Новый Структура("ОписаниеОшибки", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='Недоступно подписание типом подписи %1 с помощью встроенного криптопровайдера.'"), Контекст.ОписаниеДанных.ТипПодписи)); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; КонецЕсли; СертификатПодписи = Новый Структура("Отпечаток", Base64Значение(Контекст.ОписаниеДанных.ВыбранныйСертификат.Отпечаток)); МодульХранилищеСертификатовКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ХранилищеСертификатовКлиент"); МодульХранилищеСертификатовКлиент.НайтиСертификат(Новый ОписаниеОповещения( "ВыполнитьНаСторонеПослеВыгрузкиСертификатаВМоделиСервиса", ЭтотОбъект, Контекст), СертификатПодписи); ИначеЕсли Контекст.Операция = "Шифрование" Тогда СвойстваСертификатов = Контекст.ОписаниеДанных.СертификатыШифрования; Если ТипЗнч(СвойстваСертификатов) = Тип("Строка") Тогда СвойстваСертификатов = ПолучитьИзВременногоХранилища(СвойстваСертификатов); КонецЕсли; Контекст.Вставить("Индекс", -1); Контекст.Вставить("СвойстваСертификатов", СвойстваСертификатов); Контекст.Вставить("СертификатыШифрования", Новый Массив); ВыполнитьНаСторонеПодготовкаСертификатовВМоделиСервисаЦиклНачало(Контекст); Возврат; Иначе ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеПодготовкаСертификатовВМоделиСервисаЦиклНачало(Контекст) Если Контекст.СвойстваСертификатов.Количество() <= Контекст.Индекс + 1 Тогда ВыполнитьНаСторонеЦиклЗапуск(Контекст); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; ВыполнитьНаСторонеПодготовкаСертификатовПослеИнициализацииСертификатаВМоделиСервиса( Контекст.СвойстваСертификатов[Контекст.Индекс].Сертификат, Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. Процедура ВыполнитьНаСторонеПодготовкаСертификатовПослеИнициализацииСертификатаВМоделиСервиса(СертификатКриптографии, Контекст) Контекст.СертификатыШифрования.Добавить(СертификатКриптографии); ВыполнитьНаСторонеПодготовкаСертификатовВМоделиСервисаЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ВыполнитьНаСтороне. // // Параметры: // РезультатПоиска - Структура: // * ОписаниеОшибки - ИнформацияОбОшибке // Контекст - Структура // Асинх Процедура ВыполнитьНаСторонеПослеВыгрузкиСертификатаВМоделиСервиса(РезультатПоиска, Контекст) Экспорт Если Не РезультатПоиска.Выполнено Тогда Ошибка = Новый Структура("ОписаниеОшибки", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось найти сертификат в сервисе по причине: |%1'"), РезультатПоиска.ОписаниеОшибки.Описание)); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(РезультатПоиска.Сертификат) Тогда Ошибка = Новый Структура("ОписаниеОшибки", НСтр("ru = 'Сертификат отсутствует в сервисе (возможно удален).'")); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Контекст.Вставить("СвойстваСертификата", Ждать СвойстваСертификата( РезультатПоиска.Сертификат)); Контекст.СвойстваСертификата.Вставить("ДвоичныеДанные", РезультатПоиска.Сертификат.Сертификат); ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецПроцедуры Функция ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Экспорт Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("ТехнологияСервиса.ЭлектроннаяПодписьВМоделиСервиса") Тогда МодульЭлектроннаяПодписьВМоделиСервисаКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ЭлектроннаяПодписьВМоделиСервисаКлиент"); Возврат МодульЭлектроннаяПодписьВМоделиСервисаКлиент.ИспользованиеВозможно(); КонецЕсли; Возврат Ложь; КонецФункции Функция ИспользованиеИнтерактивногоРежимаКриптографииИспользовать() Возврат Вычислить("ИспользованиеИнтерактивногоРежимаКриптографии.Использовать"); КонецФункции Функция НачалоОписанияТекстаОшибки(ИмяМетода) Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Метод %1 не выполнен по причине:'"), ИмяМетода); КонецФункции #Область ДобавлениеСертификата // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. Процедура ДобавитьСертификатПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") И Результат.Общая Тогда Результат.ЗаголовокОшибки = Контекст.ЗаголовокОшибкиПрограммы; Контекст.Вставить("ОшибкаНаКлиенте", Результат); ВыполнитьОбработкуОповещения(Контекст.ОбработчикЗавершения, Неопределено); СообщитьОбОшибкеДобавленияСертификата(Контекст); Возврат; КонецЕсли; СертификатКриптографии = Новый СертификатКриптографии; СертификатКриптографии.НачатьИнициализацию(Новый ОписаниеОповещения( "ДобавитьСертификатПослеИнициализацииСертификата", ЭтотОбъект, Контекст), Контекст.ДанныеСертификата); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. Асинх Процедура ДобавитьСертификатПослеИнициализацииСертификата(СертификатКриптографии, Контекст) Экспорт Контекст.Вставить("СертификатКриптографии", СертификатКриптографии); Контекст.Вставить("ОшибкаНаКлиенте", ЭлектроннаяПодписьСлужебныйКлиентСервер.НовоеОписаниеОшибок()); Если Не Контекст.Свойство("АлгоритмПодписи") Тогда Контекст.Вставить("АлгоритмПодписи", ""); КонецЕсли; Контекст.Вставить("ЭтоПолноправныйПользователь", ПользователиКлиент.ЭтоПолноправныйПользователь()); ОписанияПрограмм = ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ОписанияПрограмм; ПрограммаПоСертификатуРезультат = Ждать ПрограммаПоСертификату(СертификатКриптографии, Истина, Неопределено, Истина); Если ЗначениеЗаполнено(ПрограммаПоСертификатуРезультат.Программа) Тогда ОписанияПрограмм = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииОписанияПрограмм( ПрограммаПоСертификатуРезультат.Программа, Контекст.ОшибкаНаКлиенте.Ошибки, ОписанияПрограмм); Иначе СвойстваОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеСвойстваОшибки(); СвойстваОшибки.Описание = ПрограммаПоСертификатуРезультат.Ошибка; Контекст.ОшибкаНаКлиенте.Ошибки.Добавить(СвойстваОшибки); КонецЕсли; Контекст.Вставить("ОписанияПрограмм", ОписанияПрограмм); Контекст.Вставить("ОписаниеПрограммы", Неопределено); Контекст.Вставить("Индекс", -1); ДобавитьСертификатЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. // // Параметры: // Контекст - Структура: // * ОшибкаНаКлиенте - Структура: // ** Ошибки - Массив - ИнформацияОбОшибке // * ОписаниеПрограмм - см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы // Процедура ДобавитьСертификатЦиклНачало(Контекст) Если Контекст.ОписанияПрограмм.Количество() <= Контекст.Индекс + 1 Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработчикЗавершения, Неопределено); СообщитьОбОшибкеДобавленияСертификата(Контекст); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; ОписаниеПрограммы = Контекст.ОписанияПрограмм[Контекст.Индекс]; // см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы Контекст.ОписаниеПрограммы = ОписаниеПрограммы; ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Неопределено; ПараметрыСоздания.Программа = ОписаниеПрограммы; ПараметрыСоздания.ИнтерактивныйРежим = Контекст.ДополнительныеПараметры.ВводитьПарольВПрограммеЭлектроннойПодписи; ПараметрыСоздания.АлгоритмПодписи = Контекст.АлгоритмПодписи; СоздатьМенеджерКриптографии( Новый ОписаниеОповещения("ДобавитьСертификатЦиклПослеСозданияМенеджераКриптографии",ЭтотОбъект, Контекст), "", ПараметрыСоздания); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. // // Параметры: // Контекст - Структура: // * ОшибкаНаКлиенте - Структура: // ** Ошибки - Массив // Процедура ДобавитьСертификатЦиклПослеСозданияМенеджераКриптографии(Результат, Контекст) Экспорт Если ТипЗнч(Результат) <> Тип("МенеджерКриптографии") Тогда Если Результат.Ошибки.Количество() > 0 И Не (ЗначениеЗаполнено(Контекст.АлгоритмПодписи) И Результат.Ошибки[0].НетАлгоритма) Тогда Результат.Ошибки[0].ЗаголовокОшибки = Контекст.ЗаголовокОшибкиПрограммы; Контекст.ОшибкаНаКлиенте.Ошибки.Добавить(Результат.Ошибки[0]); КонецЕсли; ДобавитьСертификатЦиклНачало(Контекст); Возврат; КонецЕсли; Контекст.Вставить("МенеджерКриптографии", Результат); Если Не ИспользуетсяИнтерактивныйРежимКриптографии(Контекст.МенеджерКриптографии) Тогда Контекст.МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = Контекст.ПарольСертификата; КонецЕсли; Если Контекст.ДляШифрования = Истина Тогда Контекст.МенеджерКриптографии.НачатьШифрование(Новый ОписаниеОповещения( "ДобавитьСертификатЦиклПослеШифрования", ЭтотОбъект, Контекст, "ДобавитьСертификатЦиклПослеОшибкиШифрования", ЭтотОбъект), Контекст.ДанныеСертификата, Контекст.СертификатКриптографии); Иначе Контекст.МенеджерКриптографии.НачатьПодписывание(Новый ОписаниеОповещения( "ДобавитьСертификатЦиклПослеПодписания", ЭтотОбъект, Контекст, "ДобавитьСертификатЦиклПослеОшибкиПодписания", ЭтотОбъект), Контекст.ДанныеСертификата, Контекст.СертификатКриптографии); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. Процедура ДобавитьСертификатЦиклПослеШифрования(ЗашифрованныеДанные, Контекст) Экспорт Контекст.МенеджерКриптографии.НачатьРасшифровку(Новый ОписаниеОповещения( "ДобавитьСертификатЦиклПослеРасшифровки", ЭтотОбъект, Контекст, "ДобавитьСертификатЦиклПослеОшибкиРасшифровки", ЭтотОбъект), ЗашифрованныеДанные); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. // // Параметры: // Контекст - Структура: // * ОшибкаНаКлиенте - Структура: // ** Ошибки - Массив // * ОписаниеПрограмм - см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы // Процедура ДобавитьСертификатЦиклПослеОшибкиШифрования(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаполнитьОшибкуДобавленияСертификата( Контекст.ОшибкаНаКлиенте, Контекст.ОписаниеПрограммы, "Шифрование", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке), Контекст.ЭтоПолноправныйПользователь); ДобавитьСертификатЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. // // Параметры: // Контекст - Структура: // * ОписаниеОшибки - см. ЭлектроннаяПодписьСлужебныйПовтИсп.ОписаниеПрограммы // Процедура ДобавитьСертификатЦиклПослеПодписания(ДанныеПодписи, Контекст) Экспорт ИнформацияОбОшибке = Неопределено; ПредставлениеОшибки = ""; Попытка ЭлектроннаяПодписьСлужебныйКлиентСервер.ПустыеДанныеПодписи(ДанныеПодписи, ПредставлениеОшибки); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); КонецПопытки; Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаполнитьОшибкуДобавленияСертификата( Контекст.ОшибкаНаКлиенте, Контекст.ОписаниеПрограммы, "Подписание", ПредставлениеОшибки, Контекст.ЭтоПолноправныйПользователь, ИнформацияОбОшибке = Неопределено); ДобавитьСертификатЦиклНачало(Контекст); Возврат; КонецЕсли; Сертификат = ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаписатьСертификатВСправочник(Контекст, Контекст.ОшибкаНаКлиенте); Если Сертификат = Неопределено Тогда СообщитьОбОшибкеДобавленияСертификата(Контекст); Иначе ВыполнитьОбработкуОповещения(Контекст.ОбработчикЗавершения, Сертификат); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. Процедура ДобавитьСертификатЦиклПослеОшибкиПодписания(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаполнитьОшибкуДобавленияСертификата( Контекст.ОшибкаНаКлиенте, Контекст.ОписаниеПрограммы, "Подписание", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке), Контекст.ЭтоПолноправныйПользователь); ДобавитьСертификатЦиклНачало(Контекст); КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. // // Параметры: // Контекст - Структура // Процедура ДобавитьСертификатЦиклПослеРасшифровки(РасшифрованныеДанные, Контекст) Экспорт ИнформацияОбОшибке = Неопределено; ПредставлениеОшибки = ""; Попытка ЭлектроннаяПодписьСлужебныйКлиентСервер.ПустыеРасшифрованныеДанные(РасшифрованныеДанные, ПредставлениеОшибки); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ПредставлениеОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке); КонецПопытки; Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаполнитьОшибкуДобавленияСертификата( Контекст.ОшибкаНаКлиенте, Контекст.ОписаниеПрограммы, "Расшифровка", ПредставлениеОшибки, Контекст.ЭтоПолноправныйПользователь, ИнформацияОбОшибке = Неопределено); ДобавитьСертификатЦиклНачало(Контекст); Возврат; КонецЕсли; Сертификат = ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаписатьСертификатВСправочник(Контекст, Контекст.ОшибкаНаКлиенте); Если Сертификат = Неопределено Тогда СообщитьОбОшибкеДобавленияСертификата(Контекст); Иначе ВыполнитьОбработкуОповещения(Контекст.ОбработчикЗавершения, Сертификат); КонецЕсли; КонецПроцедуры // Продолжение процедуры ЭлектроннаяПодписьКлиент.ДобавитьСертификат. Процедура ДобавитьСертификатЦиклПослеОшибкиРасшифровки(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт СтандартнаяОбработка = Ложь; ЭлектроннаяПодписьСлужебныйКлиентСервер.ЗаполнитьОшибкуДобавленияСертификата( Контекст.ОшибкаНаКлиенте, Контекст.ОписаниеПрограммы, "Расшифровка", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке), Контекст.ЭтоПолноправныйПользователь); ДобавитьСертификатЦиклНачало(Контекст); КонецПроцедуры Процедура СообщитьОбОшибкеДобавленияСертификата(КонтекстДобавления) ОшибкаНаКлиенте = ?(КонтекстДобавления.Свойство("ОшибкаНаКлиенте"), КонтекстДобавления.ОшибкаНаКлиенте, Новый Структура); ОшибкаНаСервере = ?(КонтекстДобавления.Свойство("ОшибкаНаСервере"), КонтекстДобавления.ОшибкаНаСервере, Новый Структура); ДополнительныеПараметры = Новый Структура("Сертификат", КонтекстДобавления.ДанныеСертификата); Если ЗначениеЗаполнено(ОшибкаНаКлиенте) И ОшибкаНаКлиенте.Ошибки.Количество() > 0 И ОшибкаНаКлиенте.Ошибки[0].Описание = ТекстОшибкиНеУдалосьОпределитьПрограммуПоЗакрытомуКлючуСертификата() Тогда ПараметрыОшибки = Новый Структура; ПараметрыОшибки.Вставить("ЗаголовокПредупреждения", КонтекстДобавления.ЗаголовокФормы); ПараметрыОшибки.Вставить("ТекстОшибкиКлиент", ОшибкаНаКлиенте.Ошибки[0].Описание); Если ЗначениеЗаполнено(ОшибкаНаСервере) И ОшибкаНаСервере.Ошибки.Количество() > 0 Тогда ПараметрыОшибки.Вставить("ТекстОшибкиСервер", ОшибкаНаСервере.Ошибки[0].Описание); КонецЕсли; ПараметрыОшибки.Вставить("ДополнительныеДанные", ДополнительныеПараметры); ОткрытьФорму("ОбщаяФорма.РасширенноеПредставлениеОшибки", ПараметрыОшибки, ЭтотОбъект); Иначе ПоказатьОшибкуОбращенияКПрограмме(КонтекстДобавления.ЗаголовокФормы, "", ОшибкаНаКлиенте, ОшибкаНаСервере, ДополнительныеПараметры); КонецЕсли; КонецПроцедуры #КонецОбласти #Область ОперацииСОблачнойПодписью Процедура ВыполнитьНаСторонеОблачнойПодписи(Контекст) ОписаниеДанных = Контекст.ОписаниеДанных; Контекст.Вставить("СертификатКриптографии", Null); Если Контекст.Операция = "Подписание" Тогда МодульСервисКриптографииDSSКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиентСервер"); ВыбранныйСертификат = ОписаниеДанных.ВыбранныйСертификат; Отпечаток = Новый Структура(); Отпечаток.Вставить("Отпечаток", МодульСервисКриптографииDSSКлиентСервер.ТрансформироватьОтпечаток(ВыбранныйСертификат.Отпечаток)); Отпечаток.Вставить("ДвоичныеДанные", ПолучитьИзВременногоХранилища(ВыбранныйСертификат.Данные)); СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(ОписаниеДанных); НашлиСертификат = МодульСервисКриптографииDSSКлиентСервер.НайтиСертификат(СвойстваОблачнойПодписи.УчетнаяЗапись, Отпечаток); Если НашлиСертификат.Идентификатор = -1 Тогда Ошибка = Новый Структура("ОписаниеОшибки", ТекстОшибкиОблачнаяПодпись("ПоискСертификата")); Контекст.Вставить("ОперацияНачалась", Ложь); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; НашлиСертификат.Вставить("ДвоичныеДанные", Отпечаток.ДвоичныеДанные); Контекст.Вставить("СвойстваСертификата", НашлиСертификат); ИначеЕсли Контекст.Операция = "Шифрование" Тогда СвойстваСертификатов = ОписаниеДанных.СертификатыШифрования; Если ТипЗнч(СвойстваСертификатов) = Тип("Строка") Тогда СвойстваСертификатов = ПолучитьИзВременногоХранилища(СвойстваСертификатов); КонецЕсли; СертификатыШифрования = Новый Массив; Для каждого СтрокаМассива Из СвойстваСертификатов Цикл СертификатыШифрования.Добавить(СтрокаМассива); КонецЦикла; Контекст.Вставить("Индекс", СертификатыШифрования.Количество()); Контекст.Вставить("СвойстваСертификатов", СвойстваСертификатов); Контекст.Вставить("СертификатыШифрования", СертификатыШифрования); КонецЕсли; ВыполнитьНаСторонеЦиклЗапуск(Контекст); КонецПроцедуры Процедура ВыполнитьОперациюОблачнойПодписи(Оповещение, Контекст, Данные, ПараметрыОперации) ОписаниеДанных = Контекст.ОписаниеДанных; ИндексДанных = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Контекст, "Индекс", 0); ВыполнитьСразу = Истина; ТипРезультата = Неопределено; ИдентификаторТранзакции = Неопределено; СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(ОписаниеДанных); ДанныеПодтверждения = СвойстваОблачнойПодписи.ДанныеПодтверждения; Если ДанныеПодтверждения <> Неопределено Тогда ИдентификаторТранзакции = ?(ЗначениеЗаполнено(ДанныеПодтверждения.ИдентификаторТранзакции), ДанныеПодтверждения.ИдентификаторТранзакции, ДанныеПодтверждения.ИдентификаторОперации); КонецЕсли; Если Контекст.Операция = "Подписание" Тогда МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); ЗначениеПинКода = ?(ЗначениеЗаполнено(Контекст.ЗначениеПароля), Контекст.ЗначениеПароля, Неопределено); ПинКод = МодульСервисКриптографииDSSКлиент.ПодготовитьОбъектПароля(ЗначениеПинКода); ПараметрыОперации.Вставить("ПинКод", ПинКод); Если ДанныеПодтверждения <> Неопределено Тогда ПакетнаяОперация = ДанныеПодтверждения.ПараметрыВариантаВстроенного.ПакетнаяОперация; ТипРезультата = ДанныеПодтверждения.ПараметрыВариантаВстроенного.ТипРезультата; Если ЗначениеЗаполнено(ИдентификаторТранзакции) И ИндексДанных > 0 И НЕ ПакетнаяОперация Тогда ВыполнитьСразу = Ложь; КонецЕсли; ПараметрыОперации.Вставить("ИдентификаторТранзакции", ИдентификаторТранзакции); ПараметрыОперации.Вставить("ПакетнаяПодпись", ПакетнаяОперация); КонецЕсли; Если ВыполнитьСразу Тогда Если ЗначениеЗаполнено(ИдентификаторТранзакции) Тогда ПодписатьОблачнаяПодпись(Оповещение, Контекст, Неопределено, ПараметрыОперации, ТипРезультата); ИначеЕсли СвойстваОблачнойПодписи.ДанныеПакета = Неопределено Тогда ПодписатьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата); Иначе ПодписатьОблачнаяПодпись(Оповещение, Контекст, СвойстваОблачнойПодписи.ДанныеПакета, ПараметрыОперации, ТипРезультата); КонецЕсли; КонецЕсли; ИначеЕсли Контекст.Операция = "Шифрование" Тогда ШифроватьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата); ИначеЕсли Контекст.Операция = "Расшифровка" Тогда ТипРезультата = Неопределено; МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); ЗначениеПинКода = ?(ЗначениеЗаполнено(Контекст.ЗначениеПароля), Контекст.ЗначениеПароля, Неопределено); ПинКод = МодульСервисКриптографииDSSКлиент.ПодготовитьОбъектПароля(Контекст.ЗначениеПароля); ПараметрыОперации.Вставить("ПинКод", ПинКод); Если ДанныеПодтверждения <> Неопределено Тогда ТипРезультата = ДанныеПодтверждения.ПараметрыВариантаВстроенного.ТипРезультата; Если ЗначениеЗаполнено(ИдентификаторТранзакции) И ИндексДанных > 0 Тогда ВыполнитьСразу = Ложь; КонецЕсли; ПараметрыОперации.Вставить("ИдентификаторТранзакции", ИдентификаторТранзакции); КонецЕсли; Если ВыполнитьСразу Тогда РасшифроватьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата); КонецЕсли; КонецЕсли; Если НЕ ВыполнитьСразу Тогда ПараметрыПодтверждения = Новый Структура(); ПараметрыПодтверждения.Вставить("Оповещение", Оповещение); ПараметрыПодтверждения.Вставить("Контекст", Контекст); ПараметрыПодтверждения.Вставить("Данные", Данные); ПараметрыПодтверждения.Вставить("ПараметрыОперации", ПараметрыОперации); ПараметрыПодтверждения.Вставить("ТипРезультата", ТипРезультата); ОповещениеПриВыполнении = Новый ОписаниеОповещения("ВыполнитьОперациюОблачнойПодписиПослеПодтверждения", ЭтотОбъект, ПараметрыПодтверждения); УстановитьСвойстваОблачнойПодписи(Контекст.ОписаниеДанных, Новый Структура("ОповещениеПриПодтверждении", ОповещениеПриВыполнении)); МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент"); МодульСервисКриптографииDSSПодтверждениеКлиент.ВыполнитьНачальнуюОперациюСервиса( Контекст.Форма, Контекст.ОписаниеДанных, Контекст.ЗначениеПароля, ИндексДанных); КонецЕсли; КонецПроцедуры Процедура ВыполнитьОперациюОблачнойПодписиПослеПодтверждения(РезультатВыполнения, ВходящийКонтекст) Экспорт Контекст = ВходящийКонтекст.Контекст; Если Контекст.Операция = "Подписание" Тогда ПодписатьОблачнаяПодпись(ВходящийКонтекст.Оповещение, ВходящийКонтекст.Контекст, ВходящийКонтекст.Данные, ВходящийКонтекст.ПараметрыОперации, ВходящийКонтекст.ТипРезультата); ИначеЕсли Контекст.Операция = "Расшифровка" Тогда РасшифроватьОблачнаяПодпись(ВходящийКонтекст.Оповещение, ВходящийКонтекст.Контекст, ВходящийКонтекст.Данные, ВходящийКонтекст.ПараметрыОперации, ВходящийКонтекст.ТипРезультата); КонецЕсли; КонецПроцедуры Процедура ПодписатьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата = Неопределено) МодульСервисКриптографииDSSКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиентСервер"); МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); Если ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаУсовершенствованнаяПодпись И ЗначениеЗаполнено(Контекст.ОписаниеДанных.ТипПодписи) Тогда Если Контекст.ОписаниеДанных.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.БазоваяCAdESBES") Тогда СвойствоПодписи = МодульСервисКриптографииDSSКлиентСервер.ПолучитьСвойствоПодписиCAdES("BES", Истина, Ложь, "Подпись"); ИначеЕсли Контекст.ОписаниеДанных.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.СМеткойДоверенногоВремениCAdEST") Тогда СвойствоПодписи = МодульСервисКриптографииDSSКлиентСервер.ПолучитьСвойствоПодписиCAdES("T", Истина, Ложь, "Подпись"); ИначеЕсли Контекст.ОписаниеДанных.ТипПодписи = ПредопределенноеЗначение("Перечисление.ТипыПодписиКриптографии.ОбычнаяCMS") Тогда СвойствоПодписи = МодульСервисКриптографииDSSКлиентСервер.ПолучитьСвойствоПодписиCMS(Истина, Ложь); Иначе Ошибка = Новый Структура("ОписаниеОшибки", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='Недоступно подписание типом подписи %1 с помощью учетной записи DSS.'"), Контекст.ОписаниеДанных.ТипПодписи)); ВыполнитьНаСторонеПослеЦикла(Ошибка, Контекст); Возврат; КонецЕсли; Иначе СвойствоПодписи = МодульСервисКриптографииDSSКлиентСервер.ПолучитьСвойствоПодписиCMS(Истина, Ложь); КонецЕсли; Если ТипРезультата <> Неопределено Тогда ПараметрыОперации.Вставить("ТрансформироватьРезультат", Новый Структура("ТипРезультата", ТипРезультата)); КонецЕсли; СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(Контекст.ОписаниеДанных); МодульСервисКриптографииDSSКлиент.Подписать( Оповещение, СвойстваОблачнойПодписи.УчетнаяЗапись, Данные, СвойствоПодписи, Контекст.СвойстваСертификата, ПараметрыОперации); КонецПроцедуры Процедура ШифроватьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата = Неопределено) Если ТипРезультата <> Неопределено Тогда ПараметрыОперации.Вставить("ТрансформироватьРезультат", Новый Структура("ТипРезультата", ТипРезультата)); КонецЕсли; СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(Контекст.ОписаниеДанных); МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); МодульСервисКриптографииDSSКлиент.Зашифровать( Оповещение, СвойстваОблачнойПодписи.УчетнаяЗапись, Данные, Контекст.СертификатыШифрования, "CMS", ПараметрыОперации); КонецПроцедуры Процедура РасшифроватьОблачнаяПодпись(Оповещение, Контекст, Данные, ПараметрыОперации, ТипРезультата = Неопределено) МодульСервисКриптографииDSSКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиентСервер"); МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); Если ТипРезультата <> Неопределено Тогда ПараметрыОперации.Вставить("ТрансформироватьРезультат", Новый Структура("ТипРезультата", ТипРезультата)); КонецЕсли; Сертификат = Новый Структура("Отпечаток", МодульСервисКриптографииDSSКлиентСервер.ТрансформироватьОтпечаток(Контекст.ОписаниеДанных.ВыбранныйСертификат.Отпечаток)); СвойстваОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(Контекст.ОписаниеДанных); МодульСервисКриптографииDSSКлиент.Расшифровать( Оповещение, СвойстваОблачнойПодписи.УчетнаяЗапись, Данные, "CMS", Сертификат, ПараметрыОперации); КонецПроцедуры Асинх Процедура ВыполнитьНаСторонеЦиклПослеПодписанияПакета(МассивПодписей, Контекст) ОшибкаНаКлиенте = Неопределено; Для Счетчик = 0 По МассивПодписей.Количество() - 1 Цикл ДвоичныеДанные = МассивПодписей[Счетчик]; СвойстваПодписи = Ждать СвойстваПодписиИзДвоичныхДанных(ДвоичныеДанные, Ложь); СвойстваПодписи = ПолучитьСвойстваПодписиПослеПодписания(ДвоичныеДанные, Контекст, СвойстваПодписи); ЭлементДанных = Контекст.ОписаниеДанных.НаборДанных[Счетчик]; ЭлементДанных.Вставить("СвойстваПодписи", СвойстваПодписи); Если Не ЭлементДанных.Свойство("Объект") Тогда ЭлектроннаяПодписьСлужебныйВызовСервера.ЗарегистрироватьПодписаниеДанныхВЖурнале( СвойстваТекущегоЭлементаДанных(Контекст, СвойстваПодписи)); Продолжить; КонецЕсли; Если ТипЗнч(ЭлементДанных.Объект) <> Тип("ОписаниеОповещения") Тогда ВерсияОбъекта = Неопределено; ЭлементДанных.Свойство("ВерсияОбъекта", ВерсияОбъекта); СвойстваПодписи.Вставить("ИдентификаторПодписи", Строка(Новый УникальныйИдентификатор)); ПредставлениеОшибки = ЭлектроннаяПодписьСлужебныйВызовСервера.ДобавитьПодпись( ЭлементДанных.Объект, СвойстваПодписи, Контекст.ИдентификаторФормы, ВерсияОбъекта); Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ПредставлениеОшибки); ЭлементДанных.Удалить("СвойстваПодписи"); Продолжить; КонецЕсли; ОповеститьОбИзменении(ЭлементДанных.Объект); Иначе // сделать отдельную ветку для возврата в цикл по счетчику ЭлектроннаяПодписьСлужебныйВызовСервера.ЗарегистрироватьПодписаниеДанныхВЖурнале( СвойстваТекущегоЭлементаДанных(Контекст, СвойстваПодписи)); ПараметрыВыполнения = Новый Структура; ПараметрыВыполнения.Вставить("ОписаниеДанных", Контекст.ОписаниеДанных); ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения( "ВыполнитьНаСторонеЦиклПослеЗаписиПодписи", ЭтотОбъект, Контекст)); Попытка ВыполнитьОбработкуОповещения(ЭлементДанных.Объект, ПараметрыВыполнения); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ОшибкаНаКлиенте = Новый Структура("ОписаниеОшибки", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке)); КонецПопытки; КонецЕсли; КонецЦикла; Если ОшибкаНаКлиенте <> Неопределено Тогда ВыполнитьНаСторонеПослеЦикла(ОшибкаНаКлиенте, Контекст); Иначе Контекст.Индекс = 0; ВыполнитьНаСторонеПослеЦикла(Неопределено, Контекст); КонецЕсли; КонецПроцедуры Функция ПроверятьСертификатыОблачнойПодписью() Результат = ИспользоватьСервисОблачнойПодписи() И ЭлектроннаяПодписьСлужебныйВызовСервера.НастроенСервисОблачнойПодписи(); Возврат Результат; КонецФункции Функция ШифроватьДанныеОблачнойПодписью() Результат = ИспользоватьСервисОблачнойПодписи() И ЭлектроннаяПодписьСлужебныйВызовСервера.НастроенСервисОблачнойПодписи(); Результат = Ложь; Возврат Результат; КонецФункции // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатОблачнаяПодпись(Контекст, РегистрироватьОшибки = Истина) Контекст.Вставить("РегистрироватьОшибкиОблачногоСервиса", РегистрироватьОшибки); Если ТипЗнч(Контекст.Сертификат) = Тип("СертификатКриптографии") Тогда Контекст.Сертификат.НачатьВыгрузку(Новый ОписаниеОповещения( "ПроверитьСертификатОблачнаяПодписьПослеВыгрузкиСертификата", ЭтотОбъект, Контекст)); ИначеЕсли ТипЗнч(Контекст.Сертификат) = Тип("Структура") Тогда ПроверитьСертификатОблачнаяПодписьПослеВыгрузкиСертификата(Контекст.Сертификат.Сертификат, Контекст); Иначе ПроверитьСертификатОблачнаяПодписьПослеВыгрузкиСертификата(Контекст.Сертификат, Контекст); КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатОблачнаяПодписьПослеВыгрузкиСертификата(Сертификат, Контекст) Экспорт Если ТипЗнч(Сертификат) = Тип("ДвоичныеДанные") Тогда ДанныеСертификата = Сертификат; Иначе ДанныеСертификата = ПолучитьИзВременногоХранилища(Сертификат); КонецЕсли; Если Не Контекст.РегистрироватьОшибкиОблачногоСервиса Тогда ПараметрыОперации = Новый Структура("РегистрироватьОшибку", Ложь); Иначе ПараметрыОперации = Неопределено; КонецЕсли; МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); МодульСервисКриптографииDSSКлиент.ПроверитьСертификат( Новый ОписаниеОповещения("ПроверитьСертификатПослеПроверкиОблачнаяПодпись", ЭтотОбъект, Контекст), Неопределено, ДанныеСертификата, ПараметрыОперации); КонецПроцедуры // Продолжение процедуры ПроверитьСертификат. Процедура ПроверитьСертификатПослеПроверкиОблачнаяПодпись(РезультатВызова, Контекст) Экспорт Если Не РезультатВызова.Выполнено Тогда Контекст.ОписаниеОшибкиНаСервере = ТекстОшибкиОблачнаяПодпись("ПроверкаСертификата", РезультатВызова, Истина); ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; Если Не РезультатВызова.Результат Тогда Контекст.ОписаниеОшибкиНаСервере = ТекстОшибкиОблачнаяПодпись("ПроверкаСертификата", РезультатВызова, Ложь); ОбработатьОшибкуПоКлассификатору(Контекст.ОписаниеОшибкиНаСервере, Контекст.ТребуетПроверкиНаСервере, Контекст); ПроверитьСертификатПослеНеуспешнойПроверки(Контекст); Возврат; КонецЕсли; ДополнительнаяПроверкаСертификата(Контекст.СертификатКриптографии, Истина, Контекст); КонецПроцедуры Процедура ОбработатьОшибкуПоКлассификатору(ТекстОшибки, ТребуетПроверки, Контекст, ОшибкаПоКлассификатору = Неопределено) Если ОшибкаПоКлассификатору = Неопределено Тогда ОшибкаПоКлассификатору = ЭлектроннаяПодписьСлужебныйКлиентПовтИсп.ОшибкаПоКлассификатору(ТекстОшибки); КонецЕсли; Если ОшибкаПоКлассификатору = Неопределено Тогда Возврат; КонецЕсли; Если ОшибкаПоКлассификатору.СертификатОтозван Тогда Контекст.СертификатОтозван = Истина; Попытка СсылкаНаСертификат = ЭлектроннаяПодписьСлужебныйВызовСервера.ЗаписатьОтметкуОбОтзывеСертификата( Base64Строка(Контекст.СертификатКриптографии.Отпечаток)); Если ЗначениеЗаполнено(СсылкаНаСертификат) Тогда ДополнительныеПараметры = ПараметрыОповещенияПриЗаписиСертификата(); ДополнительныеПараметры.Отозван = Истина; Оповестить("Запись_СертификатыКлючейЭлектроннойПодписиИШифрования", ДополнительныеПараметры, СсылкаНаСертификат); КонецЕсли; Исключение Ошибка = Ошибка + Символы.ПС + ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); КонецПопытки; Иначе ТребуетПроверки = ОшибкаПоКлассификатору.ТребуетПроверки; КонецЕсли; КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьОблачнаяПодпись(Контекст) Если ТипЗнч(Контекст.ИсходныеДанные) = Тип("Строка") И ЭтоАдресВременногоХранилища(Контекст.ИсходныеДанные) Тогда Контекст.ИсходныеДанные = ПолучитьИзВременногоХранилища(Контекст.ИсходныеДанные); КонецЕсли; Контекст.Вставить("МенеджерКриптографии", "ОблачнаяПодпись"); Контекст.Вставить("ПроверитьСертификатНаКлиенте"); ПроверитьПодписьНаКлиентеОблачнаяПодпись(Контекст); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеОблачнаяПодпись(Контекст) Подпись = Контекст.Подпись; ИсходныеДанные = Контекст.ИсходныеДанные; Если ТипЗнч(Подпись) = Тип("Строка") И ЭтоАдресВременногоХранилища(Подпись) Тогда Подпись = ПолучитьИзВременногоХранилища(Подпись); КонецЕсли; Если ТипЗнч(ИсходныеДанные) = Тип("Строка") И ЭтоАдресВременногоХранилища(ИсходныеДанные) Тогда ИсходныеДанные = ПолучитьИзВременногоХранилища(ИсходныеДанные); КонецЕсли; Контекст.Вставить("ДанныеПодписи", Подпись); Контекст.Вставить("МенеджерКриптографии", "ОблачнаяПодпись"); ОбработчикСледующий = Новый ОписаниеОповещения( "ПроверитьПодписьНаКлиентеПослеПроверкиПодписиОблачнаяПодпись", ЭтотОбъект, Контекст, "ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи", ЭтотОбъект); МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); МодульСервисКриптографииDSSКлиент.ПроверитьПодпись( ОбработчикСледующий, Неопределено, Контекст.ДанныеПодписи, ИсходныеДанные, "CMS"); КонецПроцедуры // Продолжение процедуры ПроверитьПодпись. Процедура ПроверитьПодписьНаКлиентеПослеПроверкиПодписиОблачнаяПодпись(РезультатВызова, Контекст) Экспорт Если Не РезультатВызова.Выполнено Тогда ТекстОшибки = ТекстОшибкиОблачнаяПодпись("ПроверкаПодписи", РезультатВызова, Истина); ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи(ТекстОшибки, Ложь, Контекст); Возврат; КонецЕсли; Если Не РезультатВызова.Результат Тогда ТекстОшибки = ТекстОшибкиОблачнаяПодпись("ПроверкаПодписи", РезультатВызова, Ложь); ПроверитьПодписьНаКлиентеПослеОшибкиПроверкиПодписи(ТекстОшибки, Ложь, Контекст); Возврат; КонецЕсли; ПроверитьПодписьНаКлиентеПослеПроверкиПодписи(Неопределено, Контекст); КонецПроцедуры Функция ИспользоватьСервисОблачнойПодписи() Экспорт Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ЭлектроннаяПодписьСервисаDSS") Тогда МодульСервисКриптографииDSSКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиент"); Возврат МодульСервисКриптографииDSSКлиент.ИспользоватьСервисОблачнойПодписи(); КонецЕсли; Возврат Ложь; КонецФункции Функция ТипПрограммыСервисаПодписи() Экспорт Результат = Неопределено; Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.ЭлектроннаяПодписьСервисаDSS") Тогда МодульСервисКриптографииDSSКлиентСервер = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSКлиентСервер"); Результат = МодульСервисКриптографииDSSКлиентСервер.ПолучитьТипОблачнойПодписи(); КонецЕсли; Возврат Результат; КонецФункции Функция ЭтоОперацияОблачнойПодписи(КонтекстФормы) Экспорт Результат = Ложь; Если ИспользоватьСервисОблачнойПодписи() Тогда ТекущиеДанные = ПолучитьДанныеОблачнойПодписи(КонтекстФормы, "ДанныеСертификата"); Если ТипЗнч(ТекущиеДанные) = Тип("Структура") Тогда Результат = ТекущиеДанные.Облачный; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура СброситьПарольВПамяти(СертификатСсылка) Экспорт ФормаПередачаПараметров().СброситьПарольСертификата(СертификатСсылка); КонецПроцедуры Функция УстановитьСвойстваОблачнойПодписи(ОписаниеДанных, НовыеЗначения) Экспорт ДанныеОблачнойПодписи = ПолучитьСвойстваОблачнойПодписи(ОписаниеДанных); ЗаполнитьЗначенияСвойств(ДанныеОблачнойПодписи, НовыеЗначения); Возврат ДанныеОблачнойПодписи; КонецФункции Функция ПолучитьСвойстваОблачнойПодписи(ОписаниеДанных) Экспорт ИмяКлюча = "СвойстваОблачнойПодписи"; ДанныеОблачнойПодписи = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ОписаниеДанных, ИмяКлюча); Если ДанныеОблачнойПодписи = Неопределено Тогда Результат = Новый Структура(); Результат.Вставить("УчетнаяЗапись", Неопределено); Результат.Вставить("ОповещениеПриПодтверждении", Неопределено); Результат.Вставить("ДанныеПакета", Неопределено); Результат.Вставить("ДанныеПодтверждения", Неопределено); ОписаниеДанных.Вставить(ИмяКлюча, Результат); Иначе Результат = ДанныеОблачнойПодписи; КонецЕсли; Возврат Результат; КонецФункции Процедура ПолучитьДанныеДляОблачнойПодписи(Оповещение, Форма, ОписаниеДанных, ИсточникДанных, ДляСтороныКлиента) Экспорт ПолучитьДанныеИзОписанияДанных(Оповещение, Форма, ОписаниеДанных, ИсточникДанных, ДляСтороныКлиента); КонецПроцедуры Функция ПолучитьДанныеОблачнойПодписи(КонтекстФормы, ИмяРеквизита) Экспорт Результат = Неопределено; Если ИспользоватьСервисОблачнойПодписи() Тогда МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент"); РеестрИмен = МодульСервисКриптографииDSSПодтверждениеКлиент.БазовыйРеестрРеквизитов(КонтекстФормы, Истина); Если РеестрИмен <> Неопределено Тогда РеквизитыФормы = Новый Структура(РеестрИмен[ИмяРеквизита], Неопределено); ЗаполнитьЗначенияСвойств(РеквизитыФормы, КонтекстФормы); Результат = РеквизитыФормы[РеестрИмен[ИмяРеквизита]]; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Возвращает адаптированный текст ошибки при операции в сервисе DSS. // // Параметры: // Операция - Строка - "ПроверкаПодписи", "ПроверкаСертификата", "ПоискСертификата", // "Подписание", "Шифрование","Расшифровка" // РезультатВызова - Неопределено, Структура // ЭтоОшибкаВыполнения - Булево - это ошибка выполнения // // Возвращаемое значение: // Строка - текст ошибки облачной подписи // Функция ТекстОшибкиОблачнаяПодпись(Операция, РезультатВызова = Неопределено, ЭтоОшибкаВыполнения = Ложь) Экспорт АдресСервера = ""; ИсходныйТекст = ""; Если ТипЗнч(РезультатВызова) = Тип("Структура") Тогда Если РезультатВызова.Свойство("НастройкиПользователя") Тогда АдресСервера = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(РезультатВызова.НастройкиПользователя, "Сервер", ""); КонецЕсли; Если РезультатВызова.Свойство("СтатусОшибки") Тогда ИсходныйТекст = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(РезультатВызова.СтатусОшибки, "ИсходныйТекст", ""); КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ИсходныйТекст) Тогда ТекстОшибки = ИсходныйТекст; Если ЭтоОшибкаВыполнения И ЗначениеЗаполнено(АдресСервера) Тогда ТекстОшибки = ТекстОшибки + " " + НСтр("ru = 'на сервере'") + " " + СокрЛП(АдресСервера); КонецЕсли; ИначеЕсли Операция = "ПроверкаПодписи" Тогда Если ЭтоОшибкаВыполнения Тогда ТекстОшибки = НСтр("ru = 'Не удалось проверить подпись.'"); Иначе ТекстОшибки = НСтр("ru = 'Подпись недействительна.'"); КонецЕсли; ИначеЕсли Операция = "ПроверкаСертификата" Тогда Если ЭтоОшибкаВыполнения Тогда ТекстОшибки = НСтр("ru = 'Не удалось проверить сертификат.'"); Иначе ТекстОшибки = НСтр("ru = 'Сертификат недействителен.'"); КонецЕсли; ИначеЕсли Операция = "ПоискСертификата" Тогда ТекстОшибки = НСтр("ru = 'Не удалось найти сертификат (возможно удален).'"); ИначеЕсли Операция = "Подписание" Тогда ТекстОшибки = НСтр("ru = 'Не удалось создать подпись.'"); ИначеЕсли Операция = "Шифрование" Тогда ТекстОшибки = НСтр("ru = 'Не удалось зашифровать данные.'"); ИначеЕсли Операция = "Расшифровка" Тогда ТекстОшибки = НСтр("ru = 'Не удалось расшифровать данные.'"); Иначе ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Неизвестная операция ""%1"".'"), Операция); КонецЕсли; Возврат НСтр("ru = 'Сервис DSS'") + ": " + ТекстОшибки; КонецФункции #КонецОбласти #Область ДиагностикаЭлектроннойПодписи // Формирует архив, содержащий техническую информацию, и предлагает сохранить его на компьютер. // // Параметры: // Причина - Строка - причина сбора технической информации. // ОбработчикЗавершения - Неопределено // - ОписаниеОповещения - содержит описание процедуры, которая будет вызвана // после сохранения архива на компьютер со следующими параметрами: // АрхивСохранен - Булево - результат сохранения архива на компьютер. // ДополнительныеПараметры - Произвольный - значение, которое было указано // при создании объекта ОписаниеОповещения. // ДополнительныеФайлы - Структура - дополнительные данные, которые необходимо поместить в архив: // * Имя - Строка - имя файла с расширением. // * Данные - ДвоичныеДанные // - Строка - данные файла или адрес данных во временном хранилище. // - Массив - массив указанных выше структур. // Процедура СформироватьТехническуюИнформацию(Причина, ОбработчикЗавершения = Неопределено, ДополнительныеФайлы = Неопределено) Экспорт СопроводительныйТекст = СокрЛ(СокрП(Причина) + Символы.ПС + Символы.ПС) + НСтр("ru = 'Информация о компьютере:'") + Символы.ПС + Символы.ПС + ДиагностическаяИнформацияОКомпьютере() + Символы.ПС; Контекст = Новый Структура; Контекст.Вставить("ДополнительныеФайлы", ДополнительныеФайлы); Контекст.Вставить("ОбработчикЗавершения", ОбработчикЗавершения); Контекст.Вставить("СопроводительныйТекст", СопроводительныйТекст); ПолучитьВерсиюКомпоненты( Новый ОписаниеОповещения("ПослеСбораТехническойИнформацииОКомпоненте", ЭтотОбъект, Контекст)); КонецПроцедуры Функция ДиагностическаяИнформацияОКомпьютере() Возврат НСтр("ru = 'Клиент:'") + Символы.ПС + ЭлектроннаяПодписьСлужебныйКлиентСервер.ДиагностическаяИнформацияОКомпьютере(Истина); КонецФункции Асинх Процедура ДиагностическаяИнформацияОПрограммахОпределенныхАвтоматически(Оповещение) ИспользуемыеПрограммыРезультат = Ждать УстановленныеКриптопровайдеры(, Ложь); Если Не ИспользуемыеПрограммыРезультат.ПроверкаВыполнена Тогда ВыполнитьОбработкуОповещения(Оповещение, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось автоматически определить программы на клиенте: %1'"), ИспользуемыеПрограммыРезультат.Ошибка)); Возврат; КонецЕсли; Если ИспользуемыеПрограммыРезультат.Криптопровайдеры.Количество() = 0 Тогда ВыполнитьОбработкуОповещения(Оповещение, НСтр("ru = 'Нет программ на клиенте, определенных автоматически'")); Возврат; КонецЕсли; Заголовок = Символы.ПС + НСтр("ru = 'Автоматически определенные программы на клиенте:'") + Символы.ПС; Контекст = Новый Структура; Контекст.Вставить("Индекс", 0); Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ИспользуемыеПрограммы", ИспользуемыеПрограммыРезультат.Криптопровайдеры); Контекст.Вставить("ДиагностическаяИнформация", Заголовок); ИнформацияОПрограммахЦиклНачало(Контекст); КонецПроцедуры Процедура ДиагностическаяИнформацияОПрограммах(Оповещение) ИспользуемыеПрограммы = ЭлектроннаяПодписьСлужебныйВызовСервера.ИспользуемыеПрограммы(); Если ИспользуемыеПрограммы.Количество() = 0 Тогда ВыполнитьОбработкуОповещения(Оповещение, ""); Возврат; КонецЕсли; Заголовок = Символы.ПС + НСтр("ru = 'Программы на клиенте из справочника:'") + Символы.ПС; Контекст = Новый Структура; Контекст.Вставить("Индекс", 0); Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("ИспользуемыеПрограммы", ИспользуемыеПрограммы); Контекст.Вставить("ДиагностическаяИнформация", Заголовок); ИнформацияОПрограммахЦиклНачало(Контекст); КонецПроцедуры Процедура ИнформацияОПрограммахЦиклНачало(Контекст) ПараметрыСоздания = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСоздания.ПоказатьОшибку = Неопределено; ПараметрыСоздания.Автоопределение = Ложь; ПараметрыСоздания.Программа = Контекст.ИспользуемыеПрограммы[Контекст.Индекс]; Оповещение = Новый ОписаниеОповещения( "ИнформацияОПрограммахПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст); СоздатьМенеджерКриптографии(Оповещение, "", ПараметрыСоздания); КонецПроцедуры // Описание // // Параметры: // МенеджерКриптографии - МенеджерКриптографии // Контекст - Структура: // * Индекс - Число // Процедура ИнформацияОПрограммахПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст) Экспорт Контекст.ДиагностическаяИнформация = Контекст.ДиагностическаяИнформация + ЭлектроннаяПодписьСлужебныйКлиентСервер.ДиагностическаяИнформацияПоПрограмме( Контекст.ИспользуемыеПрограммы[Контекст.Индекс], МенеджерКриптографии, МенеджерКриптографии); Если Контекст.Индекс = Контекст.ИспользуемыеПрограммы.Количество() - 1 Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Контекст.ДиагностическаяИнформация); Возврат; КонецЕсли; Контекст.Индекс = Контекст.Индекс + 1; ИнформацияОПрограммахЦиклНачало(Контекст); КонецПроцедуры Процедура ПослеСбораТехническойИнформацииОКомпоненте(ИнформацияОКомпоненте, Контекст) Экспорт Контекст.СопроводительныйТекст = Контекст.СопроводительныйТекст + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Версия компоненты %1 на клиенте - %2'"), "ExtraCryptoAPI", ИнформацияОКомпоненте) + Символы.ПС; ДиагностическаяИнформацияОПрограммахОпределенныхАвтоматически( Новый ОписаниеОповещения("ПослеСбораТехническойИнформацииОПрограммахОпределенныхАвтоматически", ЭтотОбъект, Контекст)); КонецПроцедуры Процедура ПослеСбораТехническойИнформацииОПрограммахОпределенныхАвтоматически(ИнформацияОПрограммах, Контекст) Экспорт Контекст.СопроводительныйТекст = Контекст.СопроводительныйТекст + Символы.ПС + ИнформацияОПрограммах + Символы.ПС; ДиагностическаяИнформацияОПрограммах( Новый ОписаниеОповещения("ПослеСбораТехническойИнформацииОПрограммах", ЭтотОбъект, Контекст)); КонецПроцедуры Процедура ПослеСбораТехническойИнформацииОПрограммах(ИнформацияОПрограммах, Контекст) Экспорт Контекст.СопроводительныйТекст = Контекст.СопроводительныйТекст + ИнформацияОПрограммах; Контекст.Вставить("АдресАрхива", ЭлектроннаяПодписьСлужебныйВызовСервера.АдресАрхиваТехническойИнформации( Контекст.СопроводительныйТекст, Контекст.ДополнительныеФайлы, ПроверенныеПутиКМодулямПрограмм())); ФайловаяСистемаКлиент.СохранитьФайл(Новый ОписаниеОповещения( "СформироватьТехническуюИнформациюПослеСохраненияФайла", ЭтотОбъект, Контекст), Контекст.АдресАрхива, "service_info.zip"); КонецПроцедуры Процедура СформироватьТехническуюИнформациюПослеСохраненияФайла(СохраненныеФайлы, Контекст) Экспорт УдалитьИзВременногоХранилища(Контекст.АдресАрхива); Если Контекст.ОбработчикЗавершения <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОбработчикЗавершения, СохраненныеФайлы <> Неопределено); КонецЕсли; КонецПроцедуры Процедура ПолучитьВерсиюКомпоненты(Оповещение) ПараметрыПодключения = ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты(); ПараметрыПодключения.ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для получения версии требуется установка компоненты %1'"), "ExtraCryptoAPI"); ПараметрыПодключения.ПредложитьЗагрузить = Ложь; ПараметрыПодключения.ПредложитьУстановить = Ложь; ОписаниеКомпоненты = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеКомпоненты(); ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета( Новый ОписаниеОповещения("ПолучитьВерсиюПослеПодключенияКомпоненты", ЭтотОбъект, Оповещение), ОписаниеКомпоненты.ИмяОбъекта, ОписаниеКомпоненты.ПолноеИмяМакета, ПараметрыПодключения); КонецПроцедуры // Продолжение процедуры ПолучитьВерсиюКомпоненты. Процедура ПолучитьВерсиюПослеПодключенияКомпоненты(Результат, Оповещение) Экспорт ВерсияКомпоненты = ""; Если Результат.Подключено Тогда Попытка ОповещениеПослеПолученияВерсии = Новый ОписаниеОповещения("ПослеПолученияВерсииКомпоненты", ЭтотОбъект, Оповещение); Результат.ПодключаемыйМодуль.НачатьВызовПолучитьВерсию(ОповещениеПослеПолученияВерсии); Возврат; Исключение ВерсияКомпоненты = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось определить версию компоненты. %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); КонецПопытки; Иначе Если ПустаяСтрока(Результат.ОписаниеОшибки) Тогда // Пользователь отказался от установки. ВерсияКомпоненты = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Компонента %1 не установлена.'"), "ExtraCryptoAPI"); Иначе // Установка не удалась, описание ошибки в Результат.ОписаниеОшибки. ВерсияКомпоненты = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Компонента %1 не установлена (%2).'"), "ExtraCryptoAPI", Результат.ОписаниеОшибки); КонецЕсли; КонецЕсли; ВыполнитьОбработкуОповещения(Оповещение, ВерсияКомпоненты); КонецПроцедуры Процедура ПослеПолученияВерсииКомпоненты(ВерсияКомпоненты, Параметры, Оповещение) Экспорт ВыполнитьОбработкуОповещения(Оповещение, ВерсияКомпоненты); КонецПроцедуры Процедура ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение, Параметры = Неопределено) Контекст = Новый Структура; Контекст.Вставить("УстанавливатьРасширение", Истина); Контекст.Вставить("УстанавливатьКомпоненту", Истина); Контекст.Вставить("ТекстПояснения"); Если ТипЗнч(Параметры) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Контекст, Параметры); КонецЕсли; Если Контекст.ТекстПояснения = Неопределено Тогда Контекст.ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для выполнения требуется установка компоненты %1'"), "ExtraCryptoAPI") КонецЕсли; Контекст.Вставить("Оповещение", Оповещение); НачатьПодключениеРасширенияРаботыСКриптографией(Новый ОписаниеОповещения( "ВыполнитьПослеПодключенияРасширенияРаботыСКриптографией", ЭтотОбъект, Контекст)); КонецПроцедуры Процедура ВыполнитьПослеПодключенияРасширенияРаботыСКриптографией(Подключено, Контекст) Экспорт Если Не Подключено Тогда Если Контекст.УстанавливатьРасширение Тогда ЭлектроннаяПодписьКлиент.УстановитьРасширение(Истина, Новый ОписаниеОповещения("ВыполнитьПослеУстановкиРасширения", ЭтотОбъект, Контекст)); Возврат; Иначе ПродолжатьБезУстановкиРасширения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры( Контекст, "ПродолжатьБезУстановкиРасширения", Ложь); ВыполнитьПослеУстановкиРасширения(ПродолжатьБезУстановкиРасширения, Контекст); Возврат; КонецЕсли; КонецЕсли; ВыполнитьПослеУстановкиРасширения(Истина, Контекст); КонецПроцедуры Процедура ВыполнитьПослеУстановкиРасширения(Установлено, Контекст) Экспорт Если Не Установлено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, ТекстОшибкиНеУстановленоРасширение()); Возврат; КонецЕсли; Если Не ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() И Не ОбщегоНазначенияКлиент.ЭтоLinuxКлиент() И Не ОбщегоНазначенияКлиент.ЭтоMacOSКлиент() Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, ТекстОшибкиУстройствоНеПоддерживается()); Возврат; КонецЕсли; ПараметрыПодключения = ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты(); ПараметрыПодключения.ТекстПояснения = Контекст.ТекстПояснения; ПараметрыПодключения.ПредложитьУстановить = Контекст.УстанавливатьКомпоненту; ПараметрыПодключения.ПредложитьЗагрузить = Контекст.УстанавливатьКомпоненту; ОписаниеКомпоненты = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеКомпоненты(); ОбщегоНазначенияКлиент.ПодключитьКомпонентуИзМакета( Новый ОписаниеОповещения("ВыполнитьПослеПодключенияКомпоненты", ЭтотОбъект, Контекст), ОписаниеКомпоненты.ИмяОбъекта, ОписаниеКомпоненты.ПолноеИмяМакета, ПараметрыПодключения); КонецПроцедуры Функция ТекстОшибкиНеУстановленоРасширение() Возврат НСтр("ru = 'Не установлено расширение для работы с криптографией.'"); КонецФункции Функция ТекстОшибкиУстройствоНеПоддерживается() Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Действие доступно только на компьютерах с операционной системой %1, %2 или %3.'"), "MacOS", "Windows", "Linux"); КонецФункции Процедура ВыполнитьПослеПодключенияКомпоненты(Результат, Контекст) Экспорт Если Результат.Подключено Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат.ПодключаемыйМодуль); Иначе Если ПустаяСтрока(Результат.ОписаниеОшибки) Тогда // Пользователь отказался от установки. ВыполнитьОбработкуОповещения(Контекст.Оповещение, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Операция невозможна. Требуется установка компоненты %1.'"), "ExtraCryptoAPI")); Иначе // Установка не удалась, описание ошибки в Результат.ОписаниеОшибки. ВыполнитьОбработкуОповещения(Контекст.Оповещение, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Операция невозможна. %1'"), Результат.ОписаниеОшибки)); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОповеститьОбУспешномПодключенииКомпоненты(Результат, Контекст) Экспорт Если ТипЗнч(Результат) = Тип("Строка") Тогда ПоказатьПредупреждение(, Результат); Возврат; КонецЕсли; ОчиститьКэшУстановленныхКриптопровайдеров(); Оповестить("Установка_КомпонентаExtraCryptoAPI"); КонецПроцедуры Асинх Функция ПолучитьСвойстваСертификатаАсинх(Сертификат, ОбъектКомпоненты) Экспорт СертификатBase64Строка = Ждать СертификатBase64Строка(Сертификат); Результат = Новый Структура("Ошибка, СвойстваСертификата, СертификатBase64Строка", ""); Результат.СертификатBase64Строка = СертификатBase64Строка; Попытка Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); СвойстваСертификатаРезультат = Ждать ОбъектКомпоненты.ПолучитьСвойстваСертификатаАсинх(СертификатBase64Строка); Ошибка = Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); Если ЗначениеЗаполнено(Ошибка) Тогда ВызватьИсключение Ошибка; КонецЕсли; СвойстваСертификата = ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваСертификатаИзОтветаКомпоненты( СвойстваСертификатаРезультат.Значение); Результат.СвойстваСертификата = СвойстваСертификата; Исключение Результат.Ошибка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Ошибка при получении расширенных свойств сертификата: | %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); Возврат Результат; КонецПопытки; Возврат Результат; КонецФункции // Сертификат base64 строка. // // Параметры: // Сертификат - ДвоичныеДанные // - Строка - адрес во временном хранилище // - Строка - Сертификат base64 строка // - СертификатКриптографии // // Возвращаемое значение: // Обещание - Сертификат base64 строка // Асинх Функция СертификатBase64Строка(Сертификат) Если ТипЗнч(Сертификат) = Тип("Строка") И ЭтоАдресВременногоХранилища(Сертификат) Тогда Сертификат = ПолучитьИзВременногоХранилища(Сертификат); КонецЕсли; Если ТипЗнч(Сертификат) = Тип("Строка") Тогда Возврат Сертификат; КонецЕсли; Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда Сертификат = Ждать Сертификат.ВыгрузитьАсинх(); КонецЕсли; Сертификат = Base64Строка(Сертификат); Сертификат = СтрЗаменить(Сертификат, Символы.ВК, ""); Сертификат = СтрЗаменить(Сертификат, Символы.ПС, ""); Возврат Сертификат; КонецФункции Процедура ДополнитьРешениеКлассификатораОшибокПодробностями( Оповещение, ОшибкаИзКлассификатора, ПараметрыДополненияТекстаРешенияОшибкиКлассификатора, ДанныеДляДополнения) Экспорт Если ПараметрыДополненияТекстаРешенияОшибкиКлассификатора.ПроверитьСертификатВЛокальномХранилищеКлиента И ЗначениеЗаполнено(ДанныеДляДополнения.ДанныеСертификата) Тогда Контекст = Новый Структура; Контекст.Вставить("ОповещениеОЗавершении", Оповещение); Контекст.Вставить("ОшибкаИзКлассификатора", ОшибкаИзКлассификатора); Контекст.Вставить("ДанныеСертификата", ДанныеДляДополнения.ДанныеСертификата); Контекст.Вставить("ПараметрыДополненияТекстаРешенияОшибкиКлассификатора", ПараметрыДополненияТекстаРешенияОшибкиКлассификатора); ЭлектроннаяПодписьКлиент.СоздатьМенеджерКриптографии( Новый ОписаниеОповещения("ПослеСозданияМенеджераКриптографииДляДополненияКлассификатораОшибок", ЭтотОбъект, Контекст), "ПолучениеСертификатов"); КонецЕсли; КонецПроцедуры Асинх Процедура ПослеСозданияМенеджераКриптографииДляДополненияКлассификатораОшибок(МенеджерКриптографии, Контекст) Экспорт Если ТипЗнч(МенеджерКриптографии) <> Тип("МенеджерКриптографии") Тогда ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Контекст.ОшибкаИзКлассификатора); Возврат; КонецЕсли; #Если Не МобильноеПриложениеКлиент И Не МобильныйКлиент Тогда ДанныеСертификата = Контекст.ДанныеСертификата; Попытка СертификатКриптографии = Новый СертификатКриптографии; Ждать СертификатКриптографии.ИнициализироватьАсинх(ДанныеСертификата); ХранилищеЛокальногоКомпьютера = Ждать МенеджерКриптографии.ПолучитьХранилищеСертификатовАсинх( ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты, РасположениеХранилищаСертификатовКриптографии.ДанныеКомпьютера); Исключение ЖурналРегистрацииКлиент.ДобавитьСообщениеДляЖурналаРегистрации( НСтр("ru = 'Электронная подпись.Диагностика ошибок'", ОбщегоНазначенияКлиент.КодОсновногоЯзыка()), "Ошибка", ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())); ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Контекст.ОшибкаИзКлассификатора); Возврат; КонецПопытки; Если Ждать ХранилищеЛокальногоКомпьютера.НайтиПоОтпечаткуАсинх(СертификатКриптографии.Отпечаток) = Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Контекст.ОшибкаИзКлассификатора); Возврат; КонецЕсли; Контекст.ОшибкаИзКлассификатора.Решение = СтроковыеФункцииКлиент.ФорматированнаяСтрока( ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатВЛокальномХранилищеТекстРешения()); Контекст.ОшибкаИзКлассификатора.Причина = СтроковыеФункцииКлиент.ФорматированнаяСтрока( ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатВЛокальномХранилищеТекстПричины()); ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Контекст.ОшибкаИзКлассификатора); #КонецЕсли КонецПроцедуры Процедура УдалитьСертификатИзЛокальногоХранилища(ДанныеСертификата) ЭлектроннаяПодписьКлиент.СоздатьМенеджерКриптографии( Новый ОписаниеОповещения("УдалитьСертификатИзЛокальногоХранилищаПродолжение", ЭтотОбъект, ДанныеСертификата), "ПолучениеСертификатов"); КонецПроцедуры Асинх Процедура УдалитьСертификатИзЛокальногоХранилищаПродолжение(МенеджерКриптографии, ДанныеСертификата) Экспорт Если ТипЗнч(МенеджерКриптографии) <> Тип("МенеджерКриптографии") Тогда Возврат; КонецЕсли; СертификатКриптографии = Новый СертификатКриптографии; Ждать СертификатКриптографии.ИнициализироватьАсинх(ПолучитьИзВременногоХранилища(ДанныеСертификата)); ХранилищеЛокальногоКомпьютера = Ждать МенеджерКриптографии.ПолучитьХранилищеСертификатовАсинх( ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты, РасположениеХранилищаСертификатовКриптографии.ДанныеКомпьютера); Если Ждать ХранилищеЛокальногоКомпьютера.НайтиПоОтпечаткуАсинх(СертификатКриптографии.Отпечаток) = Неопределено Тогда ПоказатьПредупреждение(, НСтр("ru = 'Сертификат не найден в личном хранилище компьютера. Выполните проверку заново.'")); Возврат; КонецЕсли; ТекстОшибки = ""; Попытка Ждать ХранилищеЛокальногоКомпьютера.УдалитьАсинх(СертификатКриптографии); Исключение ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); КонецПопытки; Если ЗначениеЗаполнено(ТекстОшибки) Тогда ПараметрыОшибки = Новый Структура; ПараметрыОшибки.Вставить("ЗаголовокПредупреждения", НСтр("ru = 'Удаление сертификата из локального хранилища'")); ПараметрыОшибки.Вставить("ТекстОшибкиКлиент", ТекстОшибки); ОткрытьФорму("ОбщаяФорма.РасширенноеПредставлениеОшибки", ПараметрыОшибки, ЭтотОбъект); Возврат; КонецЕсли; ПоказатьПредупреждение(, НСтр("ru = 'Сертификат удален из личного хранилища компьютера. Выполните проверку заново.'")); КонецПроцедуры #Область УстановкаСпискаОтзыва Асинх Процедура УстановитьСписокОтзываСертификатаПослеПодключенияКомпоненты(ОбъектКомпоненты, Контекст) Экспорт Если ТипЗнч(ОбъектКомпоненты) = Тип("Строка") Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(ОбъектКомпоненты, Контекст); Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(Контекст.Адреса) Тогда СвойстваСертификатаРасширенные = Ждать ПолучитьСвойстваСертификатаАсинх(Контекст.Сертификат, ОбъектКомпоненты); Если ЗначениеЗаполнено(СвойстваСертификатаРасширенные.Ошибка) Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(СвойстваСертификатаРасширенные.Ошибка, Контекст); Возврат; КонецЕсли; АдресаСписковОтзыва = СвойстваСертификатаРасширенные.СвойстваСертификата.АдресаСписковОтзыва; Если АдресаСписковОтзыва.Количество() = 0 Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(НСтр("ru = 'В сертификате не указаны адреса списков отзыва.'"), Контекст); Возврат; КонецЕсли; Иначе Если ТипЗнч(Контекст.Адреса) = Тип("Строка") Тогда АдресаСписковОтзыва = СтрРазделить(Контекст.Адреса, ";"); КонецЕсли; КонецЕсли; Параметры = Новый Структура("АдресРесурса, НаименованиеОперации, АдресВнутренний"); Параметры.АдресРесурса = АдресаСписковОтзыва; Параметры.АдресВнутренний = Контекст.АдресВнутренний; Параметры.НаименованиеОперации = НСтр("ru = 'Загрузка списка отзыва сертификата'"); Контекст.Вставить("ОбъектКомпоненты", ОбъектКомпоненты); Контекст.Вставить("АдресРесурса", Параметры.АдресРесурса); СвойстваСертификата = ЭлектроннаяПодписьСлужебныйКлиентСервер.ДополнительныеСвойстваСертификата(Контекст.Сертификат); Контекст.Вставить("ИдентификаторКлючаУдостоверяющегоЦентра", СвойстваСертификата.ИдентификаторКлючаУдостоверяющегоЦентра); ДлительнаяОперация = ЭлектроннаяПодписьСлужебныйВызовСервера.НачатьСкачиваниеФайлаНаСервере(Параметры); Если Не ДлительнаяОперация.Свойство("АдресРезультата") Тогда ПродолжитьУстановкуСпискаОтзываПослеСкачивания(ДлительнаяОперация, Контекст); Возврат; КонецЕсли; ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(Неопределено); ПараметрыОжидания.Заголовок = Параметры.НаименованиеОперации; ПараметрыОжидания.ВыводитьОкноОжидания = Истина; ОповещениеОЗавершении = Новый ОписаниеОповещения("ПродолжитьУстановкуСпискаОтзываПослеСкачивания", ЭтотОбъект, Контекст); ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания); КонецПроцедуры Процедура ПродолжитьУстановкуСпискаОтзываПослеСкачивания(РезультатВыполнения, Контекст) Экспорт Если РезультатВыполнения = Неопределено Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(НСтр("ru = 'Загрузка списка отзыва не была завершена штатно'"), Контекст); Возврат; КонецЕсли; Если РезультатВыполнения.Статус = "Ошибка" Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(РезультатВыполнения.КраткоеПредставлениеОшибки, Контекст); Возврат; КонецЕсли; // Результат выполнения фонового задания. Попытка Результат = ПолучитьИзВременногоХранилища(РезультатВыполнения.АдресРезультата); Исключение ТекстОшибки = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); ОбработатьОшибкуУстановкиСпискаОтзыва(ТекстОшибки, Контекст); Возврат; КонецПопытки; УдалитьИзВременногоХранилища(РезультатВыполнения.АдресРезультата); Если ЗначениеЗаполнено(Результат.СообщениеОбОшибке) И Не ЗначениеЗаполнено(Результат.ДанныеФайла) Тогда ОбработатьОшибкуУстановкиСпискаОтзыва(Результат.СообщениеОбОшибке, Контекст); Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(Результат.ДанныеФайла) Тогда ОбработатьОшибкуУстановкиСпискаОтзыва( НСтр("ru = 'Не удалось загрузить список отзыва. Подробнее см. в журнале регистрации.'"), Контекст); Возврат; КонецЕсли; ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(Результат, Контекст); СвойстваСпискаОтзыва = ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваСпискаОтзыва(Результат.ДанныеФайла); Если ЗначениеЗаполнено(Результат.ИдентификаторКлючаУдостоверяющегоЦентра) И ЗначениеЗаполнено(СвойстваСпискаОтзыва.ИдентификаторКлючаУдостоверяющегоЦентра) И Результат.ИдентификаторКлючаУдостоверяющегоЦентра <> СвойстваСпискаОтзыва.ИдентификаторКлючаУдостоверяющегоЦентра Тогда Ошибка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не совпадают идентификаторы ключа удостоверяющего центра полученного списка отзыва (%1) и сертификата (%2). |Обратитесь в удостоверяющий центр, выдавший сертификат.'"), СвойстваСпискаОтзыва.ИдентификаторКлючаУдостоверяющегоЦентра, Результат.ИдентификаторКлючаУдостоверяющегоЦентра); ОбработатьОшибкуУстановкиСпискаОтзыва(Ошибка, Результат, Истина); Возврат; КонецЕсли; ФайловаяСистемаКлиент.СоздатьВременныйКаталог( Новый ОписаниеОповещения("УстановитьСписокОтзываПослеСозданияВременногоКаталога", ЭтотОбъект, Результат)); КонецПроцедуры // Установить список отзыва после создания временного каталога. // // Параметры: // ИмяВременногоКаталога - Строка // Контекст - Структура: // * ИмяФайла - Строка // * ДанныеФайла - ДвоичныеДанные // Асинх Процедура УстановитьСписокОтзываПослеСозданияВременногоКаталога(ИмяВременногоКаталога, Контекст) Экспорт Если Не ЗначениеЗаполнено(ИмяВременногоКаталога) Тогда ОбработатьОшибкуУстановкиСпискаОтзыва( НСтр("ru = 'Не удалось создать временный каталог для загрузки списка отзыва.'"), Контекст); Возврат; КонецЕсли; ИмяФайлаСпискаОтзыва = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ИмяВременногоКаталога) + Контекст.ИмяФайла; Ждать Контекст.ДанныеФайла.ЗаписатьАсинх(ИмяФайлаСпискаОтзыва); Контекст.Вставить("ИмяФайлаСпискаОтзыва", ИмяФайлаСпискаОтзыва); Контекст.Вставить("ИмяВременногоКаталога", ИмяВременногоКаталога); ИмяХранилища = "CA"; РезультатУстановки = Ждать Контекст.ОбъектКомпоненты.ИмпортироватьСписокОтзываСертификатовАсинх( Контекст.ИмяФайлаСпискаОтзыва, ИмяХранилища); Если РезультатУстановки.Значение <> Истина Тогда Ошибка = Ждать Контекст.ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); Ошибка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить список отзыва в хранилище ""%1"" по причине: | %2'"), ИмяХранилища, Ошибка); ОбработатьОшибкуУстановкиСпискаОтзыва(Ошибка, Контекст); Иначе Сообщение = НСтр("ru = 'Установка списка отзыва выполнена успешно.'"); Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда Результат = РезультатУстановкиСертификата(); Результат.УстановкаВыполнена = Истина; Результат.Сообщение = Сообщение; ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Результат); Иначе ПоказатьПредупреждение(, Сообщение); КонецЕсли; КонецЕсли; Ждать УдалитьФайлыАсинх(Контекст.ИмяВременногоКаталога); КонецПроцедуры Процедура ОбработатьОшибкуУстановкиСпискаОтзыва(Ошибка, Контекст, ОшибкаИздателя = Ложь) АдресРесурса = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Контекст, "АдресРесурса", Неопределено); Если ЗначениеЗаполнено(АдресРесурса) Тогда Если ОшибкаИздателя Тогда Ошибка = Ошибка + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Адрес списка отзыва, указанный в сертификате: %1'"), СтрСоединить(АдресРесурса, Символы.ПС)); Иначе Ошибка = Ошибка + Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Загрузите вручную и установите список отзыва с: |%1'"), СтрСоединить(АдресРесурса, Символы.ПС)); КонецЕсли; КонецЕсли; Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда Результат = РезультатУстановкиСертификата(); Результат.Сообщение = Ошибка; ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Результат); Иначе ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ЗаголовокПредупреждения", НСтр("ru = 'Не удалось установить список отзыва'")); ПараметрыФормы.Вставить("ТекстОшибкиКлиент", Ошибка); ОткрытьФорму("ОбщаяФорма.РасширенноеПредставлениеОшибки", ПараметрыФормы, Контекст.Форма,,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); КонецЕсли; КонецПроцедуры #КонецОбласти #Область УстановкаСертификата // Установить корневой сертификат после подключения компоненты. // // Параметры: // ОбъектКомпоненты - ОбъектВнешнейКомпоненты - экземпляр объекта внешней компоненты // ПараметрыУстановки - см. ПараметрыУстановкиСертификата // Асинх Процедура УстановитьКорневойСертификатПослеПодключенияКомпоненты(ОбъектКомпоненты, ПараметрыУстановки) Экспорт Если ТипЗнч(ОбъектКомпоненты) = Тип("Строка") Тогда ОбработатьОшибкуУстановкиСертификата(ОбъектКомпоненты, ПараметрыУстановки); Возврат; КонецЕсли; Результат = Ждать ЦепочкаСертификатовАсинх(ПараметрыУстановки.Сертификат, ОбъектКомпоненты); Если ЗначениеЗаполнено(Результат.Ошибка) Тогда ОбработатьОшибкуУстановкиСертификата(Результат.Ошибка, ПараметрыУстановки); Возврат; КонецЕсли; Если Результат.Сертификаты.Количество() = 0 Тогда ОбработатьОшибкуУстановкиСертификата(НСтр("ru = 'Цепочка сертификатов не содержит сертификатов.'"), ПараметрыУстановки); Возврат; КонецЕсли; СписокЗначений = Новый СписокЗначений; Если Не ЗначениеЗаполнено(ПараметрыУстановки.Хранилище) Тогда СписокЗначений.Добавить("ROOT", НСтр("ru = 'Доверенные корневые сертификаты'")); Иначе СписокЗначений.Добавить(ПараметрыУстановки.Хранилище.Значение, ПараметрыУстановки.Хранилище.Представление); КонецЕсли; Сертификат = Результат.Сертификаты[Результат.Сертификаты.ВГраница()]; ПараметрыУстановкиСертификата = ПараметрыУстановкиСертификата(Сертификат.ДанныеСертификата); ПараметрыУстановкиСертификата.ВариантыУстановки = СписокЗначений; УстановитьСертификатПослеПодключенияКомпоненты(ОбъектКомпоненты, ПараметрыУстановкиСертификата); КонецПроцедуры Процедура УстановитьСертификатПослеПодключенияКомпоненты(ОбъектКомпоненты, ПараметрыУстановкиСертификата) Экспорт Если ТипЗнч(ОбъектКомпоненты) = Тип("Строка") Тогда ОбработатьОшибкуУстановкиСертификата(ОбъектКомпоненты, ПараметрыУстановкиСертификата); Возврат; КонецЕсли; Если ПараметрыУстановкиСертификата.ВариантыУстановки = Неопределено Или ТипЗнч(ПараметрыУстановкиСертификата.ВариантыУстановки) = Тип("СписокЗначений") Или ПараметрыУстановкиСертификата.ВариантыУстановки = "Контейнер" И ПараметрыУстановкиСертификата.СвойстваКонтейнера = Неопределено Тогда ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Сертификат", ПараметрыУстановкиСертификата.Сертификат); ПараметрыФормы.Вставить("ВариантыУстановки", ПараметрыУстановкиСертификата.ВариантыУстановки); ОповещениеОЗакрытииФормы = Новый ОписаниеОповещения("ВыполнитьПослеУстановкиСертификата", ЭтотОбъект, ПараметрыУстановкиСертификата); ОткрытьФорму("Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Форма.УстановкаСертификата", ПараметрыУстановкиСертификата, ПараметрыУстановкиСертификата.Форма,,,, ОповещениеОЗакрытииФормы, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); Возврат; КонецЕсли; УстановитьСертификатПослеВыбораВариантаУстановки(ПараметрыУстановкиСертификата, ОбъектКомпоненты); КонецПроцедуры Асинх Процедура УстановитьСертификатПослеВыбораВариантаУстановки(ПараметрыУстановкиСертификата, ОбъектКомпоненты = Неопределено) Экспорт Хранилище = ПараметрыУстановкиСертификата.Хранилище; ПредставлениеХранилища = ""; Если ТипЗнч(Хранилище) = Тип("Структура") Тогда Хранилище = ПараметрыУстановкиСертификата.Хранилище.Значение; ПредставлениеХранилища = ПараметрыУстановкиСертификата.Хранилище.Представление; КонецЕсли; Если Не ЗначениеЗаполнено(ПредставлениеХранилища) Тогда ПредставлениеХранилища = Хранилище; КонецЕсли; СертификатСтрокой = Ждать СертификатBase64Строка(ПараметрыУстановкиСертификата.Сертификат); Если ОбъектКомпоненты = Неопределено Тогда Попытка ОбъектКомпоненты = Ждать ОбъектВнешнейКомпонентыExtraCryptoAPI(); Исключение Ошибка = ТекстОшибкиНеУстановленаКомпонента(); ОбработатьОшибкуУстановкиСертификата(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить сертификат в %1. |%2'"), ПредставлениеХранилища, Ошибка), ПараметрыУстановкиСертификата); КонецПопытки КонецЕсли; Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); Если ЗначениеЗаполнено(ПараметрыУстановкиСертификата.СвойстваКонтейнера) Тогда СвойстваКонтейнера = ПараметрыУстановкиСертификата.СвойстваКонтейнера; Результат = Ждать ОбъектКомпоненты.УстановитьСвязьСКонтейнеромАсинх( СвойстваКонтейнера.ТипПрограммы, СвойстваКонтейнера.ИмяПрограммы, СвойстваКонтейнера.Имя, СертификатСтрокой); Если Результат.Значение <> Истина Тогда Ошибка = Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); ОбработатьОшибкуУстановкиСертификата(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось связать сертификат с контейнером %1. |%2'"), СвойстваКонтейнера.Имя, Ошибка), ПараметрыУстановкиСертификата); Возврат; КонецЕсли; ПредставлениеХранилища = СвойстваКонтейнера.Имя; Иначе Результат = Ждать ОбъектКомпоненты.УстановитьСертификатВХранилищеАсинх(СертификатСтрокой, Хранилище); Если Результат.Значение <> Истина Тогда Ошибка = Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); ОбработатьОшибкуУстановкиСертификата(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось установить сертификат в %1. |%2'"), ПредставлениеХранилища, Ошибка), ПараметрыУстановкиСертификата); Возврат; КонецЕсли; КонецЕсли; Результат = РезультатУстановкиСертификата(); Результат.УстановкаВыполнена = Истина; Результат.Сообщение = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Сертификат успешно установлен в %1.'"), ПредставлениеХранилища); ВыполнитьПослеУстановкиСертификата(Результат, Новый Структура("ОповещениеОЗавершении", ПараметрыУстановкиСертификата.ОповещениеОЗавершении)); КонецПроцедуры Процедура ОбработатьОшибкуУстановкиСертификата(Ошибка, Контекст) Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда Результат = РезультатУстановкиСертификата(); Результат.Сообщение = Ошибка; ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Результат); Иначе ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ЗаголовокПредупреждения", НСтр("ru = 'Не удалось установить сертификат.'")); ПараметрыФормы.Вставить("ТекстОшибкиКлиент", Ошибка); ОткрытьФорму("ОбщаяФорма.РасширенноеПредставлениеОшибки", ПараметрыФормы, Контекст.Форма,,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); КонецЕсли; КонецПроцедуры Процедура ВыполнитьПослеУстановкиСертификата(Результат, Контекст) Экспорт Если Результат = Неопределено Тогда Результат = РезультатУстановкиСертификата(); Результат.УстановкаВыполнена = Ложь; Результат.Сообщение = НСтр("ru = 'Установка сертификата не выполнена.'"); КонецЕсли; Если Контекст.ОповещениеОЗавершении <> Неопределено Тогда ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗавершении, Результат); Иначе ПоказатьПредупреждение(, Результат.Сообщение); КонецЕсли; КонецПроцедуры Функция РезультатУстановкиСертификата() Возврат Новый Структура("УстановкаВыполнена, Сообщение", Ложь, ""); КонецФункции #КонецОбласти #Область ПолучениеЦепочкиСертификатов // Получает из сертификата цепочку корневых сертификатов // Процедура ПолучитьЦепочкуСертификатов(Оповещение, Сертификат, ИдентификаторФормы = Неопределено) Экспорт Контекст = Новый Структура; Контекст.Вставить("Оповещение", Оповещение); Контекст.Вставить("Сертификат", Сертификат); Контекст.Вставить("ИдентификаторФормы", ИдентификаторФормы); Оповещение = Новый ОписаниеОповещения("ПолучитьЦепочкуСертификатовПослеПодключенияКомпоненты", ЭтотОбъект, Контекст); ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение); КонецПроцедуры Асинх Процедура ПолучитьЦепочкуСертификатовПослеПодключенияКомпоненты(ОбъектКомпоненты, Контекст) Экспорт Результат = Новый Структура("Сертификаты, Ошибка", Новый Массив, ""); Если ТипЗнч(ОбъектКомпоненты) = Тип("Строка") Тогда Результат.Ошибка = ОбъектКомпоненты; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); Возврат; КонецЕсли; Результат = Ждать ЦепочкаСертификатовАсинх(Контекст.Сертификат, ОбъектКомпоненты, Контекст.ИдентификаторФормы); ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры Асинх Функция ЦепочкаСертификатовАсинх(Сертификат, ОбъектКомпоненты = Неопределено, ИдентификаторФормы = Неопределено) Результат = Новый Структура("Сертификаты, Ошибка", Новый Массив, ""); Сертификат = Ждать СертификатBase64Строка(Сертификат); Если ОбъектКомпоненты = Неопределено Тогда Попытка ОбъектКомпоненты = Ждать ОбъектВнешнейКомпонентыExtraCryptoAPI(Истина); Исключение Результат.Ошибка = ТекстОшибкиНеУстановленаКомпонента(); Возврат Результат; КонецПопытки; КонецЕсли; Попытка Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); СертификатыРезультат = Ждать ОбъектКомпоненты.ПолучитьЦепочкуСертификатовАсинх(Сертификат); Ошибка = Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); Если ЗначениеЗаполнено(Ошибка) Тогда ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось получить цепочку сертификатов на компьютере: %1'"), Ошибка); КонецЕсли; Если СертификатыРезультат = Неопределено Тогда ВызватьИсключение НСтр("ru = 'Не удалось получить цепочку сертификатов.'"); КонецЕсли; Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.ЦепочкаСертификатовИзОтветаКомпоненты( СертификатыРезультат.Значение, ИдентификаторФормы); Исключение Результат.Вставить("Ошибка", ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); Возврат Результат; КонецПопытки; Возврат Результат; КонецФункции #КонецОбласти #Область УстановкаИПроверкаПрограммКриптографии // Результат получения установленных криптопровайдеров. // // Возвращаемое значение: // Структура - результат получения установленных криптопровайдеров: // * ПроверкаВыполнена - Булево // * КомпонентаУстановлена - Булево // * РасширениеУстановлено - Булево // * Криптопровайдеры - Массив // * КриптопровайдерыНаСервере - Массив // * Ошибка - Строка // Функция РезультатПолученияУстановленныхКриптопровайдеров() Результат = Новый Структура; Результат.Вставить("ПроверкаВыполнена", Ложь); Результат.Вставить("КомпонентаУстановлена", Ложь); Результат.Вставить("Криптопровайдеры", Новый Массив); Результат.Вставить("КриптопровайдерыНаСервере", Новый Массив); Результат.Вставить("Ошибка", ""); Возврат Результат; КонецФункции // Продолжение процедуры ПолучитьУстановленныеКриптопровайдеры Асинх Процедура ПолучитьУстановленныеКриптопровайдерыПослеПодключенияКомпоненты(ОбъектКомпоненты, Контекст) Экспорт Результат = Контекст.Результат; Если ТипЗнч(ОбъектКомпоненты) = Тип("Строка") Тогда Результат.Ошибка = ОбъектКомпоненты; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); Возврат; КонецЕсли; Результат.КомпонентаУстановлена = Истина; КриптопровайдерыРезультат = Ждать УстановленныеКриптопровайдерыИзКэша(Контекст.УстанавливатьКомпоненту); Если КриптопровайдерыРезультат.ПроверкаВыполнена Тогда Результат.Криптопровайдеры = КриптопровайдерыРезультат.Криптопровайдеры; Результат.ПроверкаВыполнена = Истина; Иначе Результат.Ошибка = КриптопровайдерыРезультат.Ошибка; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры Асинх Функция УстановленныеКриптопровайдеры(ОбъектКомпоненты = Неопределено, ПредложитьУстановить = Ложь) Экспорт Результат = Новый Структура; Результат.Вставить("ПроверкаВыполнена", Ложь); Результат.Вставить("Криптопровайдеры", Новый Массив); Результат.Вставить("Ошибка", ""); Если ОбъектКомпоненты = Неопределено Тогда ТекстПояснения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Для получения данных об установленных программах для работы с электронной подписью требуется установка внешней компоненты %1.'"), "ExtraCryptoAPI"); Попытка ОбъектКомпоненты = Ждать ОбъектВнешнейКомпонентыExtraCryptoAPI(ПредложитьУстановить, ТекстПояснения); Исключение Результат.Ошибка = ТекстОшибкиНеУстановленаКомпонента(); Возврат Результат; КонецПопытки; КонецЕсли; Попытка Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); РезультатСписок = Ждать ОбъектКомпоненты.ПолучитьСписокКриптопровайдеровАсинх(); Ошибка = Ждать ОбъектКомпоненты.ПолучитьСписокОшибокАсинх(); Если ЗначениеЗаполнено(Ошибка) Тогда ВызватьИсключение Ошибка; КонецЕсли; ПрограммыПоИменамСТипом = ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ПрограммыПоИменамСТипом; Криптопровайдеры = ЭлектроннаяПодписьСлужебныйКлиентСервер.УстановленныеКриптопровайдерыИзОтветаКомпоненты( РезультатСписок.Значение, ПрограммыПоИменамСТипом); Результат.ПроверкаВыполнена = Истина; Исключение Результат.Ошибка = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); Возврат Результат; КонецПопытки; Результат.Криптопровайдеры = Криптопровайдеры; ЗаписатьВКэшУстановленныеКриптопровайдеры(Результат); Возврат Результат; КонецФункции // Возвращает результат проверки криптопровайдеров из кэша с обновлением в 5 минут. Асинх Функция УстановленныеКриптопровайдерыИзКэша(ПредложитьУстановить = Ложь) ИмяПараметра = "ЭлектроннаяПодпись.УстановленныеКриптопровайдеры"; Если ПараметрыПриложения[ИмяПараметра] = Неопределено Или ПараметрыПриложения[ИмяПараметра].ВремяПроверки + 300 < ТекущаяДата() // АПК:143 Должна использоваться ТекущаяДата(). Или ПараметрыПриложения[ИмяПараметра].Ошибка = ТекстОшибкиНеУстановленаКомпонента() И ПредложитьУстановить Тогда РезультатПроверки = Ждать УстановленныеКриптопровайдеры(Неопределено, ПредложитьУстановить); Если Не РезультатПроверки.ПроверкаВыполнена Тогда ЗаписатьВКэшУстановленныеКриптопровайдеры(РезультатПроверки); КонецЕсли; Возврат РезультатПроверки; Иначе РезультатИзКэша = ПараметрыПриложения[ИмяПараметра]; Результат = Новый Структура; Результат.Вставить("ПроверкаВыполнена", РезультатИзКэша.ПроверкаВыполнена); Результат.Вставить("Криптопровайдеры", Новый Массив(РезультатИзКэша.Криптопровайдеры)); Результат.Вставить("Ошибка", РезультатИзКэша.Ошибка); Возврат Результат; КонецЕсли; КонецФункции Процедура ОчиститьКэшУстановленныхКриптопровайдеров() Экспорт ИмяПараметра = "ЭлектроннаяПодпись.УстановленныеКриптопровайдеры"; Если ПараметрыПриложения[ИмяПараметра] <> Неопределено Тогда ПараметрыПриложения[ИмяПараметра] = Неопределено; КонецЕсли; КонецПроцедуры Процедура ЗаписатьВКэшУстановленныеКриптопровайдеры(Результат) РезультатДляКэша = Новый Структура; РезультатДляКэша.Вставить("ПроверкаВыполнена", Результат.ПроверкаВыполнена); РезультатДляКэша.Вставить("Криптопровайдеры", Новый ФиксированныйМассив(Результат.Криптопровайдеры)); РезультатДляКэша.Вставить("Ошибка", Результат.Ошибка); РезультатДляКэша.Вставить("ВремяПроверки", ТекущаяДата()); // АПК:143 Должна использоваться ТекущаяДата(). ИмяПараметра = "ЭлектроннаяПодпись.УстановленныеКриптопровайдеры"; ПараметрыПриложения.Вставить(ИмяПараметра, Новый ФиксированнаяСтруктура(РезультатДляКэша)); КонецПроцедуры Функция ТекстОшибкиНеУстановленаКомпонента() Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не установлена компонента %1'"), "ExtraCryptoAPI"); КонецФункции // Продолжение процедуры ПроверитьУстановкуПрограммКриптографии Процедура ПроверитьУстановкуПрограммКриптографииПослеПолученияУстановленных(Результат, Контекст) Экспорт РезультатПроверки = Новый Структура("КомпонентаУстановлена, Ошибка, ПроверкаВыполнена"); ЗаполнитьЗначенияСвойств(РезультатПроверки, Результат); РезультатПроверки.Вставить("Программы", Новый Массив); РезультатПроверки.Вставить("ПрограммыНаСервере", Новый Массив); РезультатПроверки.Вставить("ВозможенКонфликт", Ложь); РезультатПроверки.Вставить("ВозможенКонфликтНаСервере", Ложь); Если Не РезультатПроверки.ПроверкаВыполнена Тогда ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверки); Возврат; КонецЕсли; ПараметрыОбработки = Новый Структура("АлгоритмыПодписи, ПроверяемыеПрограммы, ТипДанных, РасширенноеОписание"); ЗаполнитьЗначенияСвойств(ПараметрыОбработки, Контекст); ПараметрыОбработки.Вставить("ЭтоСервер", Ложь); ЕстьПроверяемыеПрограммы = Ложь; ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбработатьРезультатПроверкиПрограмм(Результат.Криптопровайдеры, РезультатПроверки.Программы, РезультатПроверки.ВозможенКонфликт, ПараметрыОбработки, ЕстьПроверяемыеПрограммы); ПараметрыОбработки.Вставить("ЭтоСервер", Истина); ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбработатьРезультатПроверкиПрограмм(Результат.КриптопровайдерыНаСервере, РезультатПроверки.ПрограммыНаСервере, РезультатПроверки.ВозможенКонфликтНаСервере, ПараметрыОбработки, ЕстьПроверяемыеПрограммы); // Локализация Если Контекст.ПредлагатьУстановитьПрограмму И РезультатПроверки.ПроверкаВыполнена И Не ЕстьПроверяемыеПрограммы И Не Контекст.ЭтоПовторнаяПроверка Тогда Оповещение = Новый ОписаниеОповещения("ПослеУстановкиКриптопровайдера", ЭтотОбъект, Контекст); ОткрытьФорму("Обработка.ПрограммыЭлектроннойПодписиИШифрования.Форма.УстановкаПрограммКриптопровайдеров",, Контекст.Форма,,,,Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); Возврат; КонецЕсли; // Конец Локализация ВыполнитьОбработкуОповещения(Контекст.Оповещение, РезультатПроверки); КонецПроцедуры // Возвращаемое значение: // Структура: // * ОповещениеОЗавершении - ОписаниеОповещения // * Программы - см. ЭлектроннаяПодписьСлужебныйВызовСервера.ЗаполнитьСписокПрограммДляПоиска // * Индекс - Число // Функция КонтекстПоискаУстановленныхПрограмм() Контекст = Новый Структура; Контекст.Вставить("Индекс"); Контекст.Вставить("Программы"); Контекст.Вставить("ОповещениеОЗавершении"); Возврат Контекст; КонецФункции // Локализация #Область УстановкаКриптопровайдеровЛокализация #Область УстановитьCryptoPRO Процедура УстановитьКриптоПро(Форма, ОповещениеОЗавершении, ВходящийКонтекст) Экспорт Если ЗначениеЗаполнено(ВходящийКонтекст) Тогда ПослеСохраненияФайловДистрибутива(Истина, ВходящийКонтекст); Возврат; КонецЕсли; Если ОбщегоНазначенияКлиент.ЭтоWindowsКлиент() Тогда Контекст = Новый Структура; Контекст.Вставить("ОповещениеОЗавершении", ОповещениеОЗавершении); Контекст.Вставить("ВладелецФормы", Форма.ВладелецФормы); Контекст.Вставить("Форма", Форма); Контекст.Вставить("ИмяПрограммы", ЭлектроннаяПодписьКлиентСерверЛокализация.ИмяПрограммыКриптоПро()); Оповещение = Новый ОписаниеОповещения("УстановитьCryptoProCSPПослеВводаРегистрационныхДанных", ЭлектроннаяПодписьСлужебныйКлиент, Контекст); ОткрытьФорму( "Обработка.ПрограммыЭлектроннойПодписиИШифрования.Форма.УстановкаCryptoProCSPРегистрационныеДанные",, Форма,,,, Оповещение); Иначе ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Автоматическая установка %1 возможна только на операционных системах семейства Windows. |Вы можете скачать дистрибутив программы с %2 и установить ее самостоятельно.'"), ЭлектроннаяПодписьКлиентСерверЛокализация.ИмяПрограммыКриптоПро(), "www.cryptopro.ru"); ОбработатьОшибкуУстановкиПрограммыКриптографии(ОписаниеОшибки, ОповещениеОЗавершении); КонецЕсли; КонецПроцедуры Процедура УстановитьCryptoProCSPПослеВводаРегистрационныхДанных(РегистрационныеДанные, ВходящийКонтекст) Экспорт ОповещениеПослеСозданияКаталога = Новый ОписаниеОповещения( "УстановитьКриптопровайдерПослеСозданияВременногоКаталога", ЭтотОбъект, ВходящийКонтекст); ВходящийКонтекст.Вставить("ПослеСозданияВременногоКаталога", ОповещениеПослеСозданияКаталога); Если ЗначениеЗаполнено(РегистрационныеДанные) И ТипЗнч(РегистрационныеДанные) = Тип("Структура") Тогда ВходящийКонтекст.Вставить("РегистрационныеДанные", РегистрационныеДанные); Оповещение = Новый ОписаниеОповещения( "УстановитьКриптопровайдерПослеПолученияДистрибутива", ЭтотОбъект, ВходящийКонтекст); ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ВходящийКонтекст.Форма); ПараметрыОжидания.ВыводитьОкноОжидания = Истина; ДлительнаяОперация = ЭлектроннаяПодписьСлужебныйВызовСервера.ПолучитьДистрибутивCryptoProCSP( ВходящийКонтекст.РегистрационныеДанные); ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания); Иначе ОбработатьОшибкуУстановкиПрограммыКриптографии(НСтр("ru = 'Пользователь прервал операцию'"), ВходящийКонтекст); КонецЕсли; КонецПроцедуры #КонецОбласти #Область УстановитьVipNet Процедура УстановитьVipNet(Форма, ОповещениеОЗавершении, ВходящийКонтекст) Экспорт Если ЗначениеЗаполнено(ВходящийКонтекст) Тогда ПослеСохраненияФайловДистрибутива(Истина, ВходящийКонтекст); Возврат; КонецЕсли; СистемнаяИнформация = Новый СистемнаяИнформация; Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 ИЛИ СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда Контекст = Новый Структура; Контекст.Вставить("ОповещениеОЗавершении", ОповещениеОЗавершении); Контекст.Вставить("ВладелецФормы", Форма.ВладелецФормы); Контекст.Вставить("Форма", Форма); Контекст.Вставить("ИмяПрограммы", ЭлектроннаяПодписьКлиентСерверЛокализация.ИмяПрограммыVipNet()); Оповещение = Новый ОписаниеОповещения("УстановитьViPNetCSPПослеВводаРегистрационныхДанных", ЭлектроннаяПодписьСлужебныйКлиент, Контекст); ОткрытьФорму( "Обработка.ПрограммыЭлектроннойПодписиИШифрования.Форма.УстановкаViPNetCSPРегистрационныеДанные",, Форма,,,, Оповещение); Иначе ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Установка %1 возможна только на операционных системах семейства Windows.'"), ЭлектроннаяПодписьКлиентСерверЛокализация.ИмяПрограммыVipNet()); ОбработатьОшибкуУстановкиПрограммыКриптографии(ОписаниеОшибки, ОповещениеОЗавершении); КонецЕсли; КонецПроцедуры Процедура УстановитьViPNetCSPПослеВводаРегистрационныхДанных(РегистрационныеДанные, ВходящийКонтекст) Экспорт Если РегистрационныеДанные = КодВозвратаДиалога.Отмена Или РегистрационныеДанные = Неопределено Тогда Возврат; КонецЕсли; СистемнаяИнформация = Новый СистемнаяИнформация; Если СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86 Тогда РегистрационныеДанные.Вставить("Разрядность", 32); ИначеЕсли СистемнаяИнформация.ТипПлатформы = ТипПлатформы.Windows_x86_64 Тогда РегистрационныеДанные.Вставить("Разрядность", 64); Иначе Возврат; КонецЕсли; ОповещениеПослеСозданияКаталога = Новый ОписаниеОповещения( "УстановитьКриптопровайдерПослеСозданияВременногоКаталога", ЭтотОбъект, ВходящийКонтекст); ВходящийКонтекст.Вставить("ПослеСозданияВременногоКаталога", ОповещениеПослеСозданияКаталога); Если ЗначениеЗаполнено(РегистрационныеДанные) И ТипЗнч(РегистрационныеДанные) = Тип("Структура") Тогда ВходящийКонтекст.Вставить("РегистрационныеДанные", РегистрационныеДанные); Оповещение = Новый ОписаниеОповещения( "УстановитьКриптопровайдерПослеПолученияДистрибутива", ЭтотОбъект, ВходящийКонтекст); ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ВходящийКонтекст.Форма); ПараметрыОжидания.ВыводитьОкноОжидания = Истина; ДлительнаяОперация = ЭлектроннаяПодписьСлужебныйВызовСервера.ПолучитьДистрибутивViPNetCSP(ВходящийКонтекст.РегистрационныеДанные); ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыОжидания); Иначе ОбработатьОшибкуУстановкиПрограммыКриптографии(НСтр("ru = 'Пользователь прервал операцию'"), ВходящийКонтекст); КонецЕсли; КонецПроцедуры #КонецОбласти Процедура УстановитьSignalCOM() Экспорт ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку("https://www.signal-com.ru/products/crypt/signal-com-csp/"); КонецПроцедуры Процедура УстановитьLISSI() Экспорт ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку("http://soft.lissi.ru/ls_product/skzi/"); КонецПроцедуры Процедура УстановитьКриптопровайдерПослеПолученияДистрибутива(ДлительнаяОперация, ВходящийКонтекст) Экспорт Если ДлительнаяОперация = Неопределено Тогда ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Вызов API сервиса выдачи дистрибутивов %1 не был завершен штатно.'"), ВходящийКонтекст.ИмяПрограммы); ОбработатьОшибкуУстановкиПрограммыКриптографии(ОписаниеОшибки, ВходящийКонтекст); Возврат; КонецЕсли; Если ДлительнаяОперация.Статус = "Выполнено" Тогда РезультатПолученияДистрибутива = ЭлектроннаяПодписьСлужебныйВызовСервера.РезультатПолученияДистрибутиваКриптопровайдера( ДлительнаяОперация, ВходящийКонтекст.Форма.УникальныйИдентификатор); Если ЗначениеЗаполнено(РезультатПолученияДистрибутива.Ошибка) Тогда ОбработатьОшибкуУстановкиПрограммыКриптографии(РезультатПолученияДистрибутива.Ошибка, ВходящийКонтекст); Возврат; КонецЕсли; ОбщегоНазначенияКлиентСервер.ДополнитьСтруктуру(ВходящийКонтекст, РезультатПолученияДистрибутива.ДанныеДистрибутива); ФайловаяСистемаКлиент.СоздатьВременныйКаталог(ВходящийКонтекст.ПослеСозданияВременногоКаталога); Иначе ОбработатьОшибкуУстановкиПрограммыКриптографии(НСтр("ru = 'Пользователь прервал операцию'"), ВходящийКонтекст); Возврат; КонецЕсли; КонецПроцедуры Процедура УстановитьКриптопровайдерПослеСозданияВременногоКаталога(ИмяКаталогаВременныхФайлов, ВходящийКонтекст) Экспорт ИмяКаталогаВременныхФайлов = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ИмяКаталогаВременныхФайлов); ВходящийКонтекст.Вставить("ВременныйКаталог", ИмяКаталогаВременныхФайлов); Оповещение = Новый ОписаниеОповещения("ПослеСохраненияФайловДистрибутива", ЭтотОбъект, ВходящийКонтекст); ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла(); ПараметрыСохранения.Интерактивно = Ложь; ПараметрыСохранения.Диалог.Каталог = ИмяКаталогаВременныхФайлов; ФайловаяСистемаКлиент.СохранитьФайлы(Оповещение, ВходящийКонтекст.Дистрибутив, ПараметрыСохранения); КонецПроцедуры Процедура ПослеСохраненияФайловДистрибутива(ПолученныеФайлы, ВходящийКонтекст) Экспорт Если ПолученныеФайлы = Неопределено Тогда ОбработатьОшибкуУстановкиПрограммыКриптографии(НСтр("ru = 'Не удалось сохранить на компьютер файлы дистрибутива'"), ВходящийКонтекст); Возврат; КонецЕсли; ВходящийКонтекст.Вставить("ФайлыДистрибутиваПолучены", Истина); Если ВходящийКонтекст.РегистрационныеДанные.ВыполнятьКонтрольЦелостности Тогда ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("Дистрибутив", ВходящийКонтекст.ВременныйКаталог + ВходящийКонтекст.ИмяФайлаДистрибутива); ПараметрыФормы.Вставить("Версия", ВходящийКонтекст.Версия); ПараметрыФормы.Вставить("ИмяПрограммы", ВходящийКонтекст.ИмяПрограммы); ПараметрыФормы.Вставить("КонтрольнаяСумма", ВходящийКонтекст.КонтрольнаяСумма); ПараметрыФормы.Вставить("КомандаЗапуска", ВходящийКонтекст.КомандаЗапуска); ОткрытьФорму( "Обработка.ПрограммыЭлектроннойПодписиИШифрования.Форма.УстановкаКриптопровайдераИнформацияОДистрибутиве", ПараметрыФормы, , , , , Новый ОписаниеОповещения("УстановитьКриптопровайдерПослеПолученияПодтвержденияНаУстановку", ЭтотОбъект, ВходящийКонтекст)); Иначе УстановитьКриптопровайдерПослеПолученияПодтвержденияНаУстановку(Истина, ВходящийКонтекст); КонецЕсли; КонецПроцедуры Процедура УстановитьКриптопровайдерПослеПолученияПодтвержденияНаУстановку(Результат, ВходящийКонтекст) Экспорт Если Результат = Истина Тогда ЗапуститьПриложениеНаКлиенте(ВходящийКонтекст.КомандаЗапуска, ВходящийКонтекст.ВременныйКаталог, Истина, Ложь, ВходящийКонтекст); Иначе ОбработатьОшибкуУстановкиПрограммыКриптографии(НСтр("ru = 'Пользователь прервал операцию'"), ВходящийКонтекст); КонецЕсли; КонецПроцедуры Процедура ОбработатьОшибкуУстановкиПрограммыКриптографии(Ошибка, ВходящийКонтекст) РезультатВыполнения = Новый Структура("Выполнено", Ложь); РезультатВыполнения.Вставить("ОписаниеОшибки", Ошибка); Если ТипЗнч(ВходящийКонтекст) = Тип("Структура") И ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ВходящийКонтекст,"ФайлыДистрибутиваПолучены", Ложь) Тогда РезультатВыполнения.Вставить("ВходящийКонтекст", ВходящийКонтекст); КонецЕсли; Если ТипЗнч(ВходящийКонтекст) = Тип("Структура") И ВходящийКонтекст.ОповещениеОЗавершении <> Неопределено Тогда ВыполнитьОбработкуОповещения(ВходящийКонтекст.ОповещениеОЗавершении, РезультатВыполнения); ИначеЕсли ТипЗнч(ВходящийКонтекст) = Тип("ОписаниеОповещения") Тогда РезультатВыполнения = Новый Структура("Выполнено", Ложь); РезультатВыполнения.Вставить("ОписаниеОшибки", Ошибка); ВыполнитьОбработкуОповещения(ВходящийКонтекст, РезультатВыполнения); Иначе ПоказатьПредупреждение(Неопределено, Ошибка,, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Установка %1'"), ВходящийКонтекст.ИмяПрограммы)); КонецЕсли; КонецПроцедуры #Область ЗапуститьПриложениеНаКлиенте Процедура ЗапуститьПриложениеНаКлиенте(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения, ВыводитьСообщения, ВходящийКонтекст) Оповещение = Новый ОписаниеОповещения( "ЗапуститьПриложениеНаКлиентеПослеЗапускаПриложения", ЭтотОбъект, ВходящийКонтекст, "ЗапуститьПриложениеНаКлиентеПриОшибкеЗапускаПриложения", ЭтотОбъект); ПараметрыЗапуска = ФайловаяСистемаКлиент.ПараметрыЗапускаПрограммы(); ПараметрыЗапуска.Оповещение = Оповещение; ПараметрыЗапуска.ТекущийКаталог = ТекущийКаталог; ПараметрыЗапуска.ДождатьсяЗавершения = ДождатьсяЗавершения; ПараметрыЗапуска.ВыполнитьСНаивысшимиПравами = Истина; ФайловаяСистемаКлиент.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыЗапуска); КонецПроцедуры Процедура ЗапуститьПриложениеНаКлиентеПослеЗапускаПриложения(КодВозврата, ВходящийКонтекст) Экспорт Если ТипЗнч(ВходящийКонтекст.ОповещениеОЗавершении) = Тип("ОписаниеОповещения") Тогда РезультатВыполнения = Новый Структура; РезультатВыполнения.Вставить("Выполнено", Истина); РезультатВыполнения.Вставить("ОписаниеОшибки", ""); ВыполнитьОбработкуОповещения( ВходящийКонтекст.ОповещениеОЗавершении, РезультатВыполнения); КонецЕсли; КонецПроцедуры Процедура ЗапуститьПриложениеНаКлиентеПриОшибкеЗапускаПриложения(ИнформацияОбОшибке, СтандартнаяОбработка, ВходящийКонтекст) Экспорт СтандартнаяОбработка = Ложь; ОписаниеОшибки = НСтр("ru = 'Не удалось открыть файл %1. |Возможно файл уже открыт.'"); ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ОписаниеОшибки, ВходящийКонтекст.СтрокаКоманды); ОбщегоНазначенияКлиент.СообщитьПользователю(ОписаниеОшибки); РезультатВыполнения = Новый Структура; РезультатВыполнения.Вставить("Выполнено", Ложь); РезультатВыполнения.Вставить("ОписаниеОшибки", ОписаниеОшибки); РезультатВыполнения.Вставить("ВходящийКонтекст", ВходящийКонтекст); ВыполнитьОбработкуОповещения( ВходящийКонтекст.ОповещениеОЗавершении, РезультатВыполнения); КонецПроцедуры #КонецОбласти Процедура ПослеУстановкиКриптопровайдера(Результат, Контекст) Экспорт Контекст.Вставить("ЭтоПовторнаяПроверка", Истина); ПроверитьУстановкуПрограммКриптографии(Контекст.Форма, Контекст, Контекст.Оповещение); КонецПроцедуры #КонецОбласти // Конец Локализация #КонецОбласти #КонецОбласти Процедура ПоказатьРезультатПроверкиСертификата(Сертификат, Результат, ВладелецФормы, Заголовок = "", ОбъединятьРезультаты = "НеОбъединять", ОбработкаЗавершения = Неопределено) Экспорт СерверныеПараметры = Новый Структура; СерверныеПараметры.Вставить("ЗаголовокФормы", Заголовок); СерверныеПараметры.Вставить("ПроверкаПриВыборе"); СерверныеПараметры.Вставить("ПараметрыДополнительныхПроверок"); СерверныеПараметры.Вставить("Сертификат", Сертификат); СерверныеПараметры.Вставить("РезультатПроверки", Результат); СерверныеПараметры.Вставить("ОбъединятьРезультаты", ОбъединятьРезультаты); ФормаПередачаПараметров().ОткрытьНовуюФорму("ПроверкаСертификата", СерверныеПараметры, Новый Структура, ОбработкаЗавершения, ВладелецФормы); КонецПроцедуры Процедура ОбработатьНавигационнуюСсылкуКлассификатора(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка, ДополнительныеДанные = Неопределено) Экспорт СтандартнаяОбработка = Ложь; Параметры = ДополнительныеДанныеДляКлассификатораОшибок(); Если ТипЗнч(ДополнительныеДанные) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(Параметры, ДополнительныеДанные); КонецЕсли; Если НавигационнаяСсылкаФорматированнойСтроки = "ОткрытьСертификат" Тогда Если ЗначениеЗаполнено(Параметры.Сертификат) И ТипЗнч(Параметры.Сертификат) = Тип("СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования") Тогда ПоказатьЗначение( , Параметры.Сертификат); ИначеЕсли ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("АдресСертификата", Параметры.ДанныеСертификата); ОткрытьФорму("ОбщаяФорма.Сертификат", ПараметрыФормы); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "ОткрытьСписокПрограмм" Тогда ЭлектроннаяПодписьКлиент.ОткрытьНастройкиЭлектроннойПодписиИШифрования("Программы"); ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "ПодатьЗаявлениеНаСертификат" Тогда Если ЗначениеЗаполнено(Параметры.Сертификат) И ТипЗнч(Параметры.Сертификат) = Тип("СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования") Тогда ПараметрыСоздания = Новый Структура; ПараметрыСоздания.Вставить("СоздатьЗаявление", Истина); ПараметрыСоздания.Вставить("СертификатОснование", Параметры.Сертификат); ДобавитьСертификат(ПараметрыСоздания); КонецЕсли; // Локализация ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "ДобавитьУдостоверяющийЦентрВСписокРазрешенныхНеаккредитованных" Тогда Если ЗначениеЗаполнено(Параметры.Сертификат) И ЭлектроннаяПодписьКлиент.ОбщиеНастройки().ДоступнаПроверкаПоСпискуУЦ Тогда ПараметрыСоздания = Новый Структура; ПараметрыСоздания.Вставить("Сертификат", Параметры.Сертификат); ОткрытьФорму("ОбщаяФорма.РазрешенныеНеаккредитованныеУЦ", ПараметрыСоздания, Элемент); КонецЕсли; // Конец Локализация ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УстановитьСписокОтзываСертификата" Тогда Если ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда ПараметрыУстановкиСпискаОтзыва = ПараметрыУстановкиСпискаОтзыва(Параметры.ДанныеСертификата); УстановитьСписокОтзываСертификата(ПараметрыУстановкиСпискаОтзыва); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УстановитьКорневойСертификат" Тогда Если ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда ЭлектроннаяПодписьКлиент.УстановитьКорневойСертификат(Параметры.ДанныеСертификата); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УстановитьСертификат" Тогда Если ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда ПараметрыУстановкиСертификата = ПараметрыУстановкиСертификата(Параметры.ДанныеСертификата); УстановитьСертификат(ПараметрыУстановкиСертификата); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УстановитьСертификатВКонтейнер" Тогда Если ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда ПараметрыУстановкиСертификата = ПараметрыУстановкиСертификата(Параметры.ДанныеСертификата); ПараметрыУстановкиСертификата.ВариантыУстановки = "Контейнер"; УстановитьСертификат(ПараметрыУстановкиСертификата); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УдалитьСертификатИзЛокальногоХранилища" Тогда Если ЗначениеЗаполнено(Параметры.ДанныеСертификата) Тогда УдалитьСертификатИзЛокальногоХранилища(Параметры.ДанныеСертификата); КонецЕсли; ИначеЕсли НавигационнаяСсылкаФорматированнойСтроки = "УстановитьКомпоненту" Тогда Оповещение = Новый ОписаниеОповещения("ОповеститьОбУспешномПодключенииКомпоненты", ЭтотОбъект); ВыполнитьПослеПроверкиРасширенияИКомпоненты(Оповещение); ИначеЕсли СтрНайти(НавигационнаяСсылкаФорматированнойСтроки, "http") Тогда ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(НавигационнаяСсылкаФорматированнойСтроки, ); ИначеЕсли СтрНачинаетсяС(НавигационнаяСсылкаФорматированнойСтроки, "e1cib") Тогда СтандартнаяОбработка = Истина; Иначе ПоказатьПредупреждение(, НСтр("ru = 'Действие будет доступно в следующих обновлениях программы'")); КонецЕсли; КонецПроцедуры // Дополнительные данные для классификатора ошибок. // // Возвращаемое значение: // Структура - дополнительные данные для классификатора ошибок: // * Сертификат - СправочникСсылка.СертификатыКлючейЭлектроннойПодписиИШифрования // * ДанныеСертификата - Строка - адрес данных сертификата во временном хранилище. // * ДанныеПодписи - Строка - адрес данных подписи во временном хранилище. // * ДополнительныеДанныеПроверокНаКлиенте - Структура // * ДополнительныеДанныеПроверокНаСервере - Структура // * ПараметрыПодключенияКомпоненты - см. ОбщегоНазначенияКлиент.ПараметрыПодключенияКомпоненты // Функция ДополнительныеДанныеДляКлассификатораОшибок() Экспорт ДополнительныеДанные = Новый Структура; ДополнительныеДанные.Вставить("Сертификат"); ДополнительныеДанные.Вставить("ДанныеСертификата"); ДополнительныеДанные.Вставить("ДанныеПодписи"); ДополнительныеДанные.Вставить("ПараметрыПодключенияКомпоненты"); ДополнительныеДанные.Вставить("ДополнительныеДанныеПроверокНаКлиенте"); ДополнительныеДанные.Вставить("ДополнительныеДанныеПроверокНаСервере"); Возврат ДополнительныеДанные; КонецФункции // Используется для управления напоминаниями пользователя из формы сертификата, заявления на сертификат // и формы ОповещениеОбОкончанииСрокаДействия. // Процедура ИзменитьОтметкуОНапоминании(Сертификат, Напомнить, ФормаВладелец) Экспорт Если ФормаВладелец.ИмяФормы = "Обработка.ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.Форма.Форма" Тогда ИдентификаторНапоминания = "АвтоматическоеНапоминаниеОбИзмененииСостоянияЗаявления"; Иначе ИдентификаторНапоминания = "АвтоматическоеНапоминаниеОПродленииСертификата"; КонецЕсли; ЭлектроннаяПодписьСлужебныйВызовСервера.ИзменитьОтметкуОНапоминании(Сертификат, Напомнить, ИдентификаторНапоминания); КонецПроцедуры // Только для внутреннего использования // Заполнение реквизита ФизическоеЛицо значением, найденным по наименованию из поля сертификата КомуВыдан // // Параметры: // Форма - ФормаКлиентскогоПриложения // КомуВыдан - Строка // ФизическоеЛицо - ОпределяемыйТип.ФизическоеЛицо - реквизит для заполнения физического лица // Процедура ПодобратьФизическоеЛицоДляСертификата(Форма, КомуВыдан, ФизическоеЛицо) Экспорт Если ЗначениеЗаполнено(ФизическоеЛицо) Тогда ТекстВопроса = НСтр("ru = 'Поле ""Физическое лицо"" заполнено. Перезаполнить?'"); Параметры = Новый Структура("Форма, КомуВыдан, ФизическоеЛицо", Форма, КомуВыдан, ФизическоеЛицо); ОповещениеОтвет = Новый ОписаниеОповещения("ОтветПодобратьФизическоеЛицо", ЭтотОбъект, Параметры); ПоказатьВопрос(ОповещениеОтвет, ТекстВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да); Возврат; КонецЕсли; УстановитьФизическоеЛицо(Форма, КомуВыдан, ФизическоеЛицо); КонецПроцедуры Процедура ОтветПодобратьФизическоеЛицо(Результат, Параметры) Экспорт Если Результат = КодВозвратаДиалога.Да Тогда УстановитьФизическоеЛицо(Параметры.Форма, Параметры.КомуВыдан, Параметры.ФизическоеЛицо); КонецЕсли; КонецПроцедуры Процедура УстановитьФизическоеЛицо(Форма, КомуВыдан, ФизическоеЛицо) Форма.Модифицированность = Истина; КомуВыдан = ЭлектроннаяПодписьСлужебныйКлиентСервер.ПреобразоватьКомуВыданКВидуФИО(КомуВыдан); Результат = ЭлектроннаяПодписьСлужебныйВызовСервера.ПолучитьФизическиеЛицаПоПолюСертификатаКомуВыдан(КомуВыдан); Если НЕ Результат.Свойство("ФизическиеЛица") Тогда Возврат; КонецЕсли; ФизическиеЛица = Результат.ФизическиеЛица.Получить(КомуВыдан); ФизическоеЛицоПустаяСсылка = Новый (ТипЗнч(ФизическоеЛицо)); ЭтоФормаЭлемента = ?(Форма.Элементы.Найти("СертификатФизическоеЛицо") = Неопределено, Истина, Ложь); Если ЭтоФормаЭлемента Тогда Форма.Объект.ФизическоеЛицо = ФизическоеЛицоПустаяСсылка; Иначе Форма.СертификатФизическоеЛицо = ФизическоеЛицоПустаяСсылка; КонецЕсли; Если ФизическиеЛица = Неопределено Тогда ОбработкаВыбора = Новый ОписаниеОповещения("ПриЗакрытииФормыВыбораФизическогоЛица", Форма); ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("РежимВыбора", Истина); ОткрытьФорму(Результат.ПутьФормыВыбораФизическогоЛица, ПараметрыФормы, Форма, , , , ОбработкаВыбора, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); Возврат; КонецЕсли; Если ФизическиеЛица.Количество() = 1 Тогда Если ЭтоФормаЭлемента Тогда Форма.Объект.ФизическоеЛицо = ФизическиеЛица[0]; Иначе Форма.СертификатФизическоеЛицо = ФизическиеЛица[0]; КонецЕсли; Возврат; КонецЕсли; ФиксированныеНастройки = Новый НастройкиКомпоновкиДанных; Отбор = ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка"); Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке; Отбор.ПравоеЗначение = ФизическиеЛица; Отбор.Использование = Истина; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ФиксированныеНастройки", ФиксированныеНастройки); ПараметрыФормы.Вставить("ОтборПоСсылке", Истина); ПараметрыФормы.Вставить("РежимВыбора", Истина); ОбработкаВыбора = Новый ОписаниеОповещения("ПриЗакрытииФормыВыбораФизическогоЛица", Форма); ОткрытьФорму(Результат.ПутьФормыВыбораФизическогоЛица, ПараметрыФормы, Форма, , , , ОбработкаВыбора, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); КонецПроцедуры // Прочитать свойства подписи. // // Параметры: // ОповещениеОЗавершении - ОписаниеОповещения - возвращает структуру или массив структур // Подпись - ДвоичныеДанные // - Строка - адрес двоичных данных во временном хранилище // - Массив из Строка // - Массив из ДвоичныеДанные // ПрочитатьСертификаты - Булево - прочитать сертификаты подписи // ИспользоватьМенеджерКриптографии - Булево - использовать менеджер криптографии // Процедура ПрочитатьСвойстваПодписи(ОповещениеОЗавершении, Подпись, ПрочитатьСертификаты = Истина, ИспользоватьМенеджерКриптографии = Истина) Экспорт Если ТипЗнч(Подпись) = Тип("Строка") Или ТипЗнч(Подпись) = Тип("ДвоичныеДанные") Тогда ВернутьСтруктуру = Истина; МассивПодписей = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Подпись); Иначе ВернутьСтруктуру = Ложь; МассивПодписей = Подпись; КонецЕсли; Контекст = Новый Структура; Контекст.Вставить("Оповещение", ОповещениеОЗавершении); Контекст.Вставить("МассивПодписей", МассивПодписей); Контекст.Вставить("ОбработанныеПодписи", Новый Соответствие); Контекст.Вставить("ВернутьСтруктуру", ВернутьСтруктуру); Контекст.Вставить("ОбработанныеНаСервереПодписи"); Контекст.Вставить("ПрочитатьСертификаты", ПрочитатьСертификаты); Контекст.Вставить("ИспользоватьМенеджерКриптографии", ИспользоватьМенеджерКриптографии); ПрочитатьСвойстваПодписейЦикл(Неопределено, Контекст); КонецПроцедуры Асинх Процедура ПрочитатьСвойстваПодписейЦикл(Результат, Контекст) Экспорт Если Контекст.ИспользоватьМенеджерКриптографии Тогда Если Контекст.МассивПодписей.Количество() > 0 Тогда Контекст.Вставить("Подпись", Контекст.МассивПодписей[0]); Если Контекст.ОбработанныеНаСервереПодписи <> Неопределено Тогда Результат = Контекст.ОбработанныеНаСервереПодписи.Получить(Контекст.Подпись); Если Результат.Успех <> Неопределено Тогда ДобавитьРезультатЧтенияПодписи(Результат, Контекст); Возврат; КонецЕсли; КонецЕсли; Оповещение = Новый ОписаниеОповещения("ПрочитатьСвойстваПодписиПослеСозданияМенеджераКриптографии", ЭтотОбъект, Контекст); ПараметрыСозданияМенеджераКриптографии = ПараметрыСозданияМенеджераКриптографии(); ПараметрыСозданияМенеджераКриптографии.Программа = Контекст.Подпись; ПараметрыСозданияМенеджераКриптографии.ПоказатьОшибку = Ложь; СоздатьМенеджерКриптографии(Оповещение, "ЧтениеПодписи", ПараметрыСозданияМенеджераКриптографии); Возврат; Иначе РезультатЧтенияПодписей(Контекст); КонецЕсли; Иначе Соответствие = Новый Соответствие; Для Каждого Подпись Из Контекст.МассивПодписей Цикл СвойстваПодписиИзДвоичныхДанных = Ждать СвойстваПодписиИзДвоичныхДанных(Подпись, Контекст.ПрочитатьСертификаты); Соответствие.Вставить(Подпись, СвойстваПодписиИзДвоичныхДанных); КонецЦикла; Контекст.ОбработанныеПодписи = Соответствие; РезультатЧтенияПодписей(Контекст); КонецЕсли; КонецПроцедуры Процедура РезультатЧтенияПодписей(Контекст) Если Контекст.ВернутьСтруктуру Тогда Для Каждого КлючИЗначение Из Контекст.ОбработанныеПодписи Цикл Результат = КлючИЗначение.Значение; Прервать; КонецЦикла; Иначе Результат = Контекст.ОбработанныеПодписи; КонецЕсли; ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат); КонецПроцедуры Процедура ДобавитьРезультатЧтенияПодписи(Результат, Контекст) Контекст.ОбработанныеПодписи.Вставить(Контекст.Подпись, Результат); Контекст.МассивПодписей.Удалить(0); Оповещение = Новый ОписаниеОповещения("ПрочитатьСвойстваПодписейЦикл", ЭтотОбъект, Контекст); ВыполнитьОбработкуОповещения(Оповещение, Неопределено); КонецПроцедуры Асинх Процедура ПрочитатьСвойстваПодписиПослеСозданияМенеджераКриптографии(МенеджерКриптографии, Контекст) Экспорт Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатЧтенияСвойствПодписи(); Если МенеджерКриптографии <> Неопределено Тогда Если ТипЗнч(МенеджерКриптографии) = Тип("Строка") Тогда Результат.ТекстОшибки = МенеджерКриптографии; Иначе Результат = Ждать СвойстваПодписиЧтениеМенеджеромКриптографии( Контекст.Подпись, МенеджерКриптографии, Контекст.ПрочитатьСертификаты); Если Результат.Успех = Истина Тогда ДобавитьРезультатЧтенияПодписи(Результат, Контекст); Возврат; Иначе Результат.Успех = Неопределено; КонецЕсли; КонецЕсли; ИначеЕсли Контекст.ИспользоватьМенеджерКриптографии И Контекст.ОбработанныеНаСервереПодписи = Неопределено И (ЭлектроннаяПодписьКлиент.ПроверятьЭлектронныеПодписиНаСервере() Или ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере()) Тогда Контекст.ОбработанныеНаСервереПодписи = Новый Соответствие; Адрес = ПоместитьВоВременноеХранилище(Контекст.МассивПодписей); РезультатЧтенияНаСервере = ЭлектроннаяПодписьСлужебныйВызовСервера.СвойстваПодписи( Адрес, Контекст.ПрочитатьСертификаты); Контекст.ОбработанныеНаСервереПодписи = ПолучитьИзВременногоХранилища(РезультатЧтенияНаСервере); ДобавитьРезультатЧтенияПодписи(Контекст.ОбработанныеНаСервереПодписи.Получить(Контекст.Подпись), Контекст); Возврат; КонецЕсли; Если Контекст.ОбработанныеНаСервереПодписи <> Неопределено Тогда ДобавитьРезультатЧтенияПодписи(Контекст.ОбработанныеНаСервереПодписи.Получить(Контекст.Подпись), Контекст); Возврат; КонецЕсли; СвойстваПодписиИзДвоичныхДанных = Ждать СвойстваПодписиИзДвоичныхДанных( Контекст.Подпись, Контекст.ПрочитатьСертификаты); ЗаполнитьЗначенияСвойств(Результат, СвойстваПодписиИзДвоичныхДанных,, "Успех, ТекстОшибки"); Если СвойстваПодписиИзДвоичныхДанных.Успех = Ложь Тогда Результат.Успех = Ложь; Результат.ТекстОшибки = ?(ПустаяСтрока(Результат.ТекстОшибки), "", Результат.ТекстОшибки + Символы.ПС) + СвойстваПодписиИзДвоичныхДанных.ТекстОшибки; КонецЕсли; ДобавитьРезультатЧтенияПодписи(Результат, Контекст); КонецПроцедуры Асинх Функция СвойстваПодписиЧтениеМенеджеромКриптографии(Подпись, МенеджерКриптографии, ПрочитатьСертификаты) Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатЧтенияСвойствПодписи(); ДвоичныеДанные = ЭлектроннаяПодписьСлужебныйКлиентСервер.ДвоичныеДанныеИзДанных(Подпись, "ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваПодписиИзДвоичныхДанных"); Попытка КонтейнерПодписи = Ждать МенеджерКриптографии.ПолучитьКонтейнерПодписейКриптографииАсинх(ДвоичныеДанные); Исключение Результат.Успех = Ложь; Результат.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru='При чтении данных подписи: %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки( ИнформацияОбОшибке())); Возврат Результат; КонецПопытки; ПараметрыПодписиКриптографии = Ждать ПараметрыПодписиКриптографии( КонтейнерПодписи, ДобавкаВремени(), ОбщегоНазначенияКлиент.ДатаСеанса()); Результат.ТипПодписи = ПараметрыПодписиКриптографии.ТипПодписи; Результат.СрокДействияПоследнейМеткиВремени = ПараметрыПодписиКриптографии.СрокДействияПоследнейМеткиВремени; Результат.НеподтвержденнаяДатаПодписи = ПараметрыПодписиКриптографии.НеподтвержденнаяДатаПодписи; Результат.ДатаПодписиИзМетки = ПараметрыПодписиКриптографии.ДатаПодписиИзМетки; Если ПараметрыПодписиКриптографии.ОписаниеСертификата <> Неопределено Тогда Результат.Отпечаток = ПараметрыПодписиКриптографии.ОписаниеСертификата.Отпечаток; Результат.КомуВыданСертификат = ПараметрыПодписиКриптографии.ОписаниеСертификата.КомуВыдан; КонецЕсли; Если ПрочитатьСертификаты Тогда СтрокаПодписи = КонтейнерПодписи.Подписи[0]; Если ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатСуществует( СтрокаПодписи.СертификатПодписи) Тогда Результат.Сертификат = Ждать СтрокаПодписи.СертификатПодписи.ВыгрузитьАсинх(); КонецЕсли; Для Каждого Сертификат Из СтрокаПодписи.СертификатыПроверкиПодписи Цикл Если ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатСуществует(Сертификат) Тогда Результат.Сертификаты.Добавить(Ждать Сертификат.ВыгрузитьАсинх()); КонецЕсли; КонецЦикла; КонецЕсли; Результат.Успех = Истина; Возврат Результат; КонецФункции Асинх Функция СвойстваПодписиИзДвоичныхДанных(Подпись, ПрочитатьСертификаты) Результат = ЭлектроннаяПодписьСлужебныйКлиентСервер.РезультатЧтенияСвойствПодписи(); Попытка СвойстваПодписиИзДвоичныхДанных = ЭлектроннаяПодписьСлужебныйКлиентСервер.СвойстваПодписиИзДвоичныхДанных( Подпись, ДобавкаВремени(), ПрочитатьСертификаты); Если Не ЗначениеЗаполнено(СвойстваПодписиИзДвоичныхДанных.ТипПодписи) Тогда Результат.ТекстОшибки = НСтр("ru = 'Данные не являются подписью'"); Результат.Успех = Ложь; Возврат Результат; КонецЕсли; Исключение Результат.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось прочитать свойства подписи: %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки( ИнформацияОбОшибке())); Результат.Успех = Ложь; Возврат Результат; КонецПопытки; Результат.ТипПодписи = СвойстваПодписиИзДвоичныхДанных.ТипПодписи; Если ЗначениеЗаполнено(СвойстваПодписиИзДвоичныхДанных.ДатаПодписания) Тогда Результат.НеподтвержденнаяДатаПодписи = СвойстваПодписиИзДвоичныхДанных.ДатаПодписания; КонецЕсли; Если ЗначениеЗаполнено(СвойстваПодписиИзДвоичныхДанных.ДатаШтампаВремени) Тогда Результат.ДатаПодписиИзМетки = СвойстваПодписиИзДвоичныхДанных.ДатаШтампаВремени; КонецЕсли; Если СвойстваПодписиИзДвоичныхДанных.Сертификаты.Количество() > 0 Тогда Если СвойстваПодписиИзДвоичныхДанных.Сертификаты.Количество() > 1 Тогда Попытка Результат.Сертификаты = Ждать СертификатыПоПорядкуДоКорневого( СвойстваПодписиИзДвоичныхДанных.Сертификаты); Результат.Сертификат = Результат.Сертификаты[0]; Исключение Результат.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось прочитать свойства сертификатов: %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); КонецПопытки; Иначе Результат.Сертификат = СвойстваПодписиИзДвоичныхДанных.Сертификаты[0]; КонецЕсли; Попытка Сертификат = Новый СертификатКриптографии(); Ждать Сертификат.ИнициализироватьАсинх(Результат.Сертификат); Результат.Сертификат = Ждать Сертификат.ВыгрузитьАсинх(); СвойстваСертификата = Ждать СвойстваСертификата(Сертификат); Результат.Отпечаток = СвойстваСертификата.Отпечаток; Результат.КомуВыданСертификат = СвойстваСертификата.КомуВыдан; Исключение Результат.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку( НСтр("ru = 'Не удалось прочитать свойства сертификата: %1'"), ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); КонецПопытки; КонецЕсли; Результат.Успех = ПустаяСтрока(Результат.ТекстОшибки); Возврат Результат; КонецФункции // Для процедуры ПроверитьПодпись. // // Параметры: // Результат - см. ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи.Результат. // РезультатСтруктура - Неопределено // - см. ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи // ТребуетсяПроверка - Неопределено, Булево - Истина, если удалось определить, что // подпись не удалось проверить из-за внешних обстоятельств. // // Возвращаемое значение: // см. ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи // см. ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи.Результат - если Контекст.РезультатПроверки = Неопределено // Функция РезультатПроверкиПодписи(Результат, РезультатСтруктура = Неопределено, ТребуетсяПроверка = Неопределено) Если РезультатСтруктура = Неопределено Тогда Возврат Результат; Иначе РезультатСтруктура.Результат = Результат; Если Результат = Истина Тогда РезультатСтруктура.ПодписьВерна = Истина; РезультатСтруктура.ТребуетсяПроверка = Ложь; Возврат РезультатСтруктура; КонецЕсли; Если ТребуетсяПроверка <> Неопределено Тогда РезультатСтруктура.ТребуетсяПроверка = ТребуетсяПроверка; КонецЕсли; Если РезультатСтруктура.ТребуетсяПроверка = Ложь Тогда РезультатСтруктура.ПодписьВерна = Ложь; КонецЕсли; Если РезультатСтруктура.ТребуетсяПроверка = Неопределено Тогда РезультатСтруктура.ТребуетсяПроверка = Ложь; РезультатСтруктура.ПодписьВерна = Ложь; КонецЕсли; Возврат РезультатСтруктура; КонецЕсли; КонецФункции // Только для внутреннего использования. // // Параметры: // ДанныеСертификатов - Массив из ДвоичныеДанные // // Возвращаемое значение: // Массив из ДвоичныеДанные - сертификаты по порядку до корневого // Асинх Функция СертификатыПоПорядкуДоКорневого(ДанныеСертификатов) Экспорт ПоПорядку = Новый Массив; ОписаниеСертификатов = Новый Соответствие; СертификатыПоСубъектам = Новый Соответствие; Для Каждого ДанныеСертификата Из ДанныеСертификатов Цикл Сертификат = Новый СертификатКриптографии; Ждать Сертификат.ИнициализироватьАсинх(ДанныеСертификата); ПоПорядку.Добавить(ДанныеСертификата); ОписаниеСертификатов.Вставить(Сертификат, ДанныеСертификата); СертификатыПоСубъектам.Вставить( ЭлектроннаяПодписьСлужебныйКлиентСервер.КлючИздателя(Сертификат.Субъект), ДанныеСертификата); КонецЦикла; Для Счетчик = 1 По ПоПорядку.Количество() Цикл ЕстьИзменения = Ложь; ЭлектроннаяПодписьСлужебныйКлиентСервер.УпорядочитьСертификаты( ПоПорядку, ОписаниеСертификатов, СертификатыПоСубъектам, ЕстьИзменения); Если Не ЕстьИзменения Тогда Прервать; КонецЕсли; КонецЦикла; Возврат ПоПорядку; КонецФункции // Только для внутреннего использования. // // Параметры: // КонтейнерПодписи - КонтейнерПодписейКриптографии // ДобавкаВремени - Число // ДатаСеанса - Дата // // Возвращаемое значение: // Структура - параметры подписи криптографии: // * ТипПодписи - ПеречислениеСсылка.ТипыПодписиКриптографии // * СрокДействияПоследнейМеткиВремени - Дата, Неопределено - заполняется только с помощью менеджера криптографии. // * ДатаПодписиИзМетки - Дата, Неопределено - самый ранний штамп времени. // * НеподтвержденнаяДатаПодписи - Дата - неподтвержденная дата подписи. // - Неопределено - неподтвержденная дата подписи отсутствует в данных подписи. // * ДатаПоследнейМеткиВремени - Дата - дата последней метки времени. // * Сертификат - СертификатКриптографии - сертификат подписанта. // * ОписаниеСертификата - см. ЭлектроннаяПодписьКлиент.СвойстваСертификата. // Асинх Функция ПараметрыПодписиКриптографии(КонтейнерПодписи, ДобавкаВремени, ДатаСеанса) Экспорт ПараметрыПодписи = ЭлектроннаяПодписьСлужебныйКлиентСервер.НовыеПараметрыПодписиКриптографии(); Подпись = КонтейнерПодписи.Подписи[0]; СертификатСуществует = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатСуществует(Подпись.СертификатПодписи); Если СертификатСуществует Тогда ПараметрыПодписи.ОписаниеСертификата = Ждать СвойстваСертификата(Подпись.СертификатПодписи); КонецЕсли; Возврат ЭлектроннаяПодписьСлужебныйКлиентСервер.ПараметрыПодписиКриптографии(ПараметрыПодписи, Подпись, СертификатСуществует, ДобавкаВремени, ДатаСеанса); КонецФункции #КонецОбласти