Files
T
2024-05-16 09:48:00 +03:00

11126 lines
776 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// 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];
СертификатСуществует = ЭлектроннаяПодписьСлужебныйКлиентСервер.СертификатСуществует(Подпись.СертификатПодписи);
Если СертификатСуществует Тогда
ПараметрыПодписи.ОписаниеСертификата = Ждать СвойстваСертификата(Подпись.СертификатПодписи);
КонецЕсли;
Возврат ЭлектроннаяПодписьСлужебныйКлиентСервер.ПараметрыПодписиКриптографии(ПараметрыПодписи, Подпись, СертификатСуществует, ДобавкаВремени, ДатаСеанса);
КонецФункции
#КонецОбласти