Сертификаты ключей электронной подписи и шифрования / Подписание данных / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

&НаКлиенте
Перем ВнутренниеДанные, СвойстваПароля, ОписаниеДанных, ФормаОбъекта, ОбработкаПослеПредупреждения, ТекущийСписокПредставлений;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ЭлектроннаяПодписьСлужебный.НастроитьПояснениеВводаПароля(ЭтотОбъект, ,
		Элементы.ПояснениеУсиленногоПароля.Имя);
	
	НовыйПараметрТипПодписи = Новый Структура;
	НовыйПараметрТипПодписи.Вставить("ТипыПодписи", Новый Массив);
	НовыйПараметрТипПодписи.Вставить("Видимость", Ложь);
	НовыйПараметрТипПодписи.Вставить("Доступность", Ложь);
	НовыйПараметрТипПодписи.Вставить("ВыборДоверенности", Ложь);
	НовыйПараметрТипПодписи.Вставить("ПроверятьСертификат", ЭлектроннаяПодписьСлужебныйКлиентСервер.ПроверятьКвалифицированные());
	
	Если Не ТипЗнч(Параметры.ТипПодписи) = Тип("Структура") Тогда
		
		Если ЗначениеЗаполнено(Параметры.ТипПодписи) Тогда
			НовыйПараметрТипПодписи.ТипыПодписи.Добавить(Параметры.ТипПодписи);
		КонецЕсли;
	Иначе
		ЗаполнитьЗначенияСвойств(НовыйПараметрТипПодписи, Параметры.ТипПодписи);
	КонецЕсли;
	
	УстановитьТипПодписи(НовыйПараметрТипПодписи);
	ЭлектроннаяПодписьСлужебный.НастроитьФормуПодписанияШифрованияРасшифровки(ЭтотОбъект);

	// СтандартныеПодсистемы.МашиночитаемыеДоверенности
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности") Тогда
		Элементы.ГруппаДоверенность.Видимость = НовыйПараметрТипПодписи.ВыборДоверенности;
		Если НовыйПараметрТипПодписи.ВыборДоверенности Тогда
			ПодобратьДоверенностьПоСертификату();
		КонецЕсли;
	КонецЕсли;
	// Конец СтандартныеПодсистемы.МашиночитаемыеДоверенности
	
	Если ЭлектроннаяПодписьСлужебный.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеСервер = ОбщегоНазначения.ОбщийМодуль("СервисКриптографииDSSПодтверждениеСервер");
		
		МодульСервисКриптографииDSSПодтверждениеСервер.ПодготовитьГруппуПодтверждения(ЭтотОбъект, "Подписание",
				"ГруппаПодписаниеИКомментарий",
				"ГруппаКонтейнер",
				"ГруппаКонтейнер1",
				"ГруппаКомандыПодтверждения");
		МодульСервисКриптографииDSSПодтверждениеСервер.ПодтверждениеПриИзмененииСертификата(ЭтотОбъект, Сертификат);
	КонецЕсли;
	
	ОбновитьВидимостьПредупреждения();
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если ВнутренниеДанные = Неопределено Тогда
		Отказ = Истина;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ИмяПоляАктивизироватьПоУмолчанию) Тогда
		ТекущийЭлемент = Элементы[ИмяПоляАктивизироватьПоУмолчанию];
	КонецЕсли;
	
	Если ЭлектроннаяПодписьСлужебныйКлиент.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
		МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеПриОткрытии(ЭтотОбъект, Отказ, ЗначениеЗаполнено(Пароль) И ЗапомнитьПароль, ОписаниеДанных);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
	
	ОчиститьПеременныеФормы();
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	Если ВРег(ИмяСобытия) = ВРег("Запись_СертификатыКлючейЭлектроннойПодписиИШифрования") Тогда
		ПодключитьОбработчикОжидания("ПриИзмененииСпискаСертификатов", 0.1, Истина);
		
	ИначеЕсли ВРег(ИмяСобытия) = ВРег("ПодтверждениеВыполнитьОсновнуюОперацию") И Источник = УникальныйИдентификатор Тогда
		Если Параметр.Выполнено Тогда
			ДанныеПакета = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Параметр, "ДанныеПакета");
			ЭлектроннаяПодписьСлужебныйКлиент.УстановитьСвойстваОблачнойПодписи(ОписаниеДанных, Новый Структура("ДанныеПакета", ДанныеПакета));
			СвойстваОблачнойПодписи = ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьСвойстваОблачнойПодписи(ОписаниеДанных);
			ОповещениеПриПодтверждении = СвойстваОблачнойПодписи.ОповещениеПриПодтверждении;
			
			Если ОповещениеПриПодтверждении = Неопределено Тогда
				ПодписатьДанные(Новый ОписаниеОповещения("ПодписатьЗавершение", ЭтотОбъект));
			Иначе
				ВыполнитьОбработкуОповещения(ОповещениеПриПодтверждении, ЭтотОбъект);
			КонецЕсли;
		Иначе
			Элементы.Подписать.Видимость = Истина;
			Элементы.Подписать.Доступность = Истина;
			Элементы.Подписать.КнопкаПоУмолчанию = Истина;
			ОбработатьОшибку(Новый ОписаниеОповещения("ПодписатьЗавершение", ЭтотОбъект),
				Новый Структура("ОписаниеОшибки", Параметр.Ошибка), Новый Структура);
		КонецЕсли;
		
	ИначеЕсли ВРег(ИмяСобытия) = ВРег("ПодтверждениеАвторизация") И Источник = УникальныйИдентификатор Тогда
		ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьОтпечаткиСертификатовНаКлиенте(
			Новый ОписаниеОповещения("СертификатОбработкаВыбораЗавершение", ЭтотОбъект));
	
	ИначеЕсли ВРег(ИмяСобытия) = ВРег("ПодтверждениеПодготовитьДанные") И Источник = УникальныйИдентификатор Тогда
		ВыбранныйСертификат = Новый Структура;
		ВыбранныйСертификат.Вставить("Ссылка",    Сертификат);
		ВыбранныйСертификат.Вставить("Отпечаток", СертификатОтпечаток);
		ВыбранныйСертификат.Вставить("Данные",    СертификатАдрес);
		Параметр.ОписаниеДанных.Вставить("ВыбранныйСертификат",   ВыбранныйСертификат);
		Параметр.ОписаниеДанных.Вставить("ВыбраннаяДоверенность", МашиночитаемаяДоверенность);
		Параметр.ОписаниеДанных.Вставить("РезультатПроверкиМЧДДляПодписания", РезультатПроверкиМЧДДляПодписания);

		ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьДанныеДляОблачнойПодписи(
			Параметр.ОбработчикСледующий, Параметр.КонтекстФормы, 
			Параметр.ОписаниеДанных, Параметр.Данные, Истина);
	
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ПарольНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ЭлектроннаяПодписьСлужебныйКлиент.ПолеПароляНачалоВыбора(ЭтотОбъект,
		ВнутренниеДанные, СвойстваПароля, СтандартнаяОбработка);
КонецПроцедуры

&НаКлиенте
Процедура ВыборДоверенностиПриИзменении(Элемент)
	
	Элементы.ГруппаСтраницы.ТекущаяСтраница = ?(ПоДоверенности, Элементы.СтраницаВыборДоверенности,
		Элементы.СтраницаБезДоверенности);
	
	Если Не ПоДоверенности Тогда
		МашиночитаемаяДоверенность = Неопределено;
		РезультатПроверкиМЧДДляПодписания = Неопределено;
	Иначе
		ПодключитьОбработчикОжидания("Подключаемый_ПодобратьДоверенность", 0.1, Истина);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПредставлениеДанныхНажатие(Элемент, СтандартнаяОбработка)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПредставлениеДанныхНажатие(ЭтотОбъект,
		Элемент, СтандартнаяОбработка, ТекущийСписокПредставлений);
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатПриИзменении(Элемент)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьОтпечаткиСертификатовНаКлиенте(
		Новый ОписаниеОповещения("СертификатПриИзмененииЗавершение", ЭтотОбъект));
	
КонецПроцедуры

// Продолжение процедуры СертификатПриИзменении.
&НаКлиенте
Процедура СертификатПриИзмененииЗавершение(ОтпечаткиСертификатовНаКлиенте, Контекст) Экспорт
	
	СертификатПриИзмененииНаСервере(ОтпечаткиСертификатовНаКлиенте);
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект, ВнутренниеДанные, СвойстваПароля, Новый Структура("ПриОткрытии", Истина));
	
	Если ЭлектроннаяПодписьСлужебныйКлиент.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
		МодульСервисКриптографииDSSПодтверждениеКлиент.ПроверитьНаОшибкуСертификата(ЭтотОбъект);
		МодульСервисКриптографииDSSПодтверждениеКлиент.ФильтроватьСписокСпособов(ЭтотОбъект);
		МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеПриИзменении(ЭтотОбъект, Элементы.Сертификат, ОписаниеДанных, СвойстваПароля.Значение);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если ТипЗнч(ОтборСертификатов) = Тип("СписокЗначений") И ОтборСертификатов.Количество() > 0 Тогда
		ЭлектроннаяПодписьСлужебныйКлиент.НачалоВыбораСертификатаПриУстановленномОтборе(ЭтотОбъект);
		Возврат;
	КонецЕсли;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("ВыбранныйСертификат", Сертификат);
	ПараметрыФормы.Вставить("ДляШифрованияИРасшифровки", Ложь);
	ПараметрыФормы.Вставить("ВернутьПароль", Истина);
	Если ТипЗнч(ОтборСертификатов) <> Тип("СписокЗначений") Тогда
		ПараметрыФормы.Вставить("ОтборПоОрганизации", ОтборСертификатов);
	КонецЕсли;
	ПараметрыФормы.Вставить("ВыполнятьНаСервере", ВыполнятьНаСервере);
	ПараметрыФормы.Вставить("ОтображатьКомандыДобавления", Истина);
	
	ЭлектроннаяПодписьСлужебныйКлиент.ВыборСертификатаДляПодписанияИлиРасшифровки(ПараметрыФормы, Элемент);
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатОткрытие(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Если ЗначениеЗаполнено(Сертификат) Тогда
		ЭлектроннаяПодписьКлиент.ОткрытьСертификат(Сертификат);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	Если ВыбранноеЗначение = Истина Тогда
		Сертификат = ВнутренниеДанные["ВыбранныйСертификат"];
		ВнутренниеДанные.Удалить("ВыбранныйСертификат");
	Иначе
		Сертификат = ВыбранноеЗначение;
	КонецЕсли;
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьОтпечаткиСертификатовНаКлиенте(
		Новый ОписаниеОповещения("СертификатОбработкаВыбораЗавершение", ЭтотОбъект, ВыбранноеЗначение));
	
КонецПроцедуры

// Продолжение процедуры СертификатОбработкаВыбора.
&НаКлиенте
Процедура СертификатОбработкаВыбораЗавершение(ОтпечаткиСертификатовНаКлиенте, ВыбранноеЗначение) Экспорт
	
	СертификатПриИзмененииНаСервере(ОтпечаткиСертификатовНаКлиенте);
	
	Если ВыбранноеЗначение = Истина
	   И ВнутренниеДанные["ВыбранныйСертификатПароль"] <> Неопределено Тогда
		
		ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект,
			ВнутренниеДанные, СвойстваПароля,, ВнутренниеДанные["ВыбранныйСертификатПароль"]);
		ВнутренниеДанные.Удалить("ВыбранныйСертификатПароль");
	Иначе
		ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект, ВнутренниеДанные, СвойстваПароля);
	КонецЕсли;
	
	Если ЭлектроннаяПодписьСлужебныйКлиент.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
		МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеПриИзменении(ЭтотОбъект, Элементы.Сертификат, ОписаниеДанных, СвойстваПароля.Значение);
		МодульСервисКриптографииDSSПодтверждениеКлиент.ПроверитьНаОшибкуСертификата(ЭтотОбъект);
		МодульСервисКриптографииDSSПодтверждениеКлиент.ФильтроватьСписокСпособов(ЭтотОбъект);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, Ожидание, СтандартнаяОбработка)
	
	ЭлектроннаяПодписьСлужебныйКлиент.СертификатПодборИзСпискаВыбора(ЭтотОбъект, Текст, ДанныеВыбора, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура СертификатОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, Параметры, СтандартнаяОбработка)
	
	ЭлектроннаяПодписьСлужебныйКлиент.СертификатПодборИзСпискаВыбора(ЭтотОбъект, Текст, ДанныеВыбора, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ПарольПриИзменении(Элемент)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект,
		ВнутренниеДанные, СвойстваПароля, Новый Структура("ПриИзмененииРеквизитаПароль", Истина));
	
КонецПроцедуры

&НаКлиенте
Процедура ЗапомнитьПарольПриИзменении(Элемент)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект,
		ВнутренниеДанные, СвойстваПароля, Новый Структура("ПриИзмененииРеквизитаЗапомнитьПароль", Истина));
	
КонецПроцедуры

&НаКлиенте
Процедура ПояснениеУстановленногоПароляНажатие(Элемент)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПояснениеУстановленногоПароляНажатие(ЭтотОбъект, Элемент, СвойстваПароля);
	
КонецПроцедуры

&НаКлиенте
Процедура ПояснениеУстановленногоПароляРасширеннаяПодсказкаОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылка, СтандартнаяОбработка)
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПояснениеУстановленногоПароляОбработкаНавигационнойСсылки(
		ЭтотОбъект, Элемент, НавигационнаяСсылка, СтандартнаяОбработка, СвойстваПароля);
	
КонецПроцедуры

&НаКлиенте
Процедура ТипПодписиОчистка(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура Подписать(Команда)
	
	ОписаниеДанных.Вставить("ПользовательНажалКнопкуПодписать", Истина);
	
	Если Не ПроверитьЗаполнение() Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭлектроннаяПодписьСлужебныйКлиент.ЭтоОперацияОблачнойПодписи(ЭтотОбъект) Тогда
		МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль(
			"СервисКриптографииDSSПодтверждениеКлиент");
		Если МодульСервисКриптографииDSSПодтверждениеКлиент.ПроверкаПередВыполнениемОперации(ЭтотОбъект,
			СвойстваПароля.Значение) Тогда
				
			Если ТипЗнч(ОписаниеДанных) = Тип("Структура") И ОписаниеДанных.Свойство("Данные") И ТипЗнч(
				ОписаниеДанных.Данные) = Тип("Структура") И ОписаниеДанных.Данные.Свойство("ПараметрыCMS") Тогда
				ОписаниеДанных.Данные.ПараметрыCMS.ВключениеСертификатовВПодпись = ЭлектроннаяПодписьСлужебныйКлиент.ВключениеСертификатовВПодписьСтрокой(
					ОписаниеДанных.Данные.ПараметрыCMS.ВключениеСертификатовВПодпись);
			ИначеЕсли ТипЗнч(ОписаниеДанных) = Тип("Структура") И ОписаниеДанных.Свойство("НаборДанных") Тогда

				Для Каждого ДанныеНабора Из ОписаниеДанных.НаборДанных Цикл
					Если ТипЗнч(ДанныеНабора.Данные) = Тип("Структура") И ДанныеНабора.Данные.Свойство("ПараметрыCMS") Тогда
						ДанныеНабора.Данные.ПараметрыCMS.ВключениеСертификатовВПодпись = ЭлектроннаяПодписьСлужебныйКлиент.ВключениеСертификатовВПодписьСтрокой(
							ДанныеНабора.Данные.ПараметрыCMS.ВключениеСертификатовВПодпись);
					КонецЕсли;
				КонецЦикла;
				
			КонецЕсли;
			МодульСервисКриптографииDSSПодтверждениеКлиент.ВыполнитьНачальнуюОперациюСервиса(ЭтотОбъект,
				ОписаниеДанных, СвойстваПароля.Значение);
			Элементы.Подписать.Доступность = Ложь;
		КонецЕсли;
	Иначе
		Если Не Элементы.Подписать.Доступность Тогда
			Возврат;
		КонецЕсли;

		Элементы.Подписать.Доступность = Ложь;

		ПодписатьДанные(Новый ОписаниеОповещения("ПодписатьЗавершение", ЭтотОбъект));

	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры Подписать.
&НаКлиенте
Процедура ПодписатьЗавершение(Результат, Контекст) Экспорт
	
	Элементы.Подписать.Доступность = Истина;
	
	Если Результат = Истина Тогда
		Закрыть(Истина);
	ИначеЕсли ЭлектроннаяПодписьСлужебныйКлиент.ЭтоОперацияОблачнойПодписи(ЭтотОбъект) Тогда
		Элементы.Подписать.Видимость = Истина;
		Элементы.Подписать.КнопкаПоУмолчанию = Истина;
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура УстановитьТипПодписи(Знач ПараметрТипПодписи)
	
	ПроверятьСертификат = ПараметрТипПодписи.ПроверятьСертификат;
	
	Если ПараметрТипПодписи.ТипыПодписи.Количество() = 0 Тогда
		
		СписокТипов = Новый СписокЗначений;
		ЭлектроннаяПодписьСлужебный.ЗаполнитьСписокТиповПодписейКриптографии(СписокТипов, "Подписание",
			Константы.ТипПодписиКриптографииПоУмолчанию.Получить());
		Для Каждого Элемент Из СписокТипов Цикл
			ПараметрТипПодписи.ТипыПодписи.Добавить(Элемент.Значение);
		КонецЦикла;
		
		ПараметрТипПодписи.Доступность = ПараметрТипПодписи.ТипыПодписи.Количество() <> 1;
		ПараметрТипПодписи.Видимость = ПараметрТипПодписи.ТипыПодписи.Количество() <> 1;
		
	КонецЕсли;
	
	Элементы.ТипПодписи.СписокВыбора.Очистить();
	Элементы.ТипПодписи.СписокВыбора.ЗагрузитьЗначения(ПараметрТипПодписи.ТипыПодписи);
	
	ТипПодписи = ПараметрТипПодписи.ТипыПодписи[0];
	
	Элементы.ТипПодписи.Видимость = ПараметрТипПодписи.Видимость;
	Элементы.ТипПодписи.Доступность = ПараметрТипПодписи.Доступность;
	
	Элементы.ГруппаДоверенность.Видимость = Ложь;
	
	Если Элементы.ТипПодписи.Видимость Тогда
		СписокТипов = Новый СписокЗначений;
		ЭлектроннаяПодписьСлужебный.ЗаполнитьСписокТиповПодписейКриптографии(СписокТипов);
		
		ТекстПодсказки = Новый Массив;
		Для Каждого ЭлементСписка Из Элементы.ТипПодписи.СписокВыбора Цикл
			Найдено = СписокТипов.НайтиПоЗначению(ЭлементСписка.Значение);
			Если Найдено <> Неопределено Тогда
				ТекстПодсказки.Добавить(Найдено.Представление);
			КонецЕсли;
		КонецЦикла;
		
		Элементы.ТипПодписи.РасширеннаяПодсказка.Заголовок = СтрСоединить(ТекстПодсказки, Символы.ПС);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПодобратьДоверенностьПоСертификату()
	
	Если Не ЗначениеЗаполнено(Сертификат) Тогда
		НастройкаПоДоверенности = Неопределено;
	Иначе
		НастройкаПоДоверенности = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
				Сертификат, "ПоДоверенности", Неопределено);
	КонецЕсли;

	Если НастройкаПоДоверенности = Неопределено Или НастройкаПоДоверенности = Истина Тогда
		ПодобратьДоверенность();
	КонецЕсли;

	ПоДоверенности = ЗначениеЗаполнено(МашиночитаемаяДоверенность) Или НастройкаПоДоверенности = Истина;

	Элементы.ГруппаСтраницы.ТекущаяСтраница = ?(ПоДоверенности, Элементы.СтраницаВыборДоверенности,
		Элементы.СтраницаБезДоверенности);
		
КонецПроцедуры

&НаСервереБезКонтекста
Функция ОшибкаСертификатПомеченКакОтозванный()
	
	Возврат ЭлектроннаяПодписьСлужебный.ОшибкаСертификатПомеченКакОтозванный()
	
КонецФункции

&НаКлиенте
Процедура ПродолжитьОткрытие(Оповещение, ОбщиеВнутренниеДанные, КлиентскиеПараметры) Экспорт
	
	Если КлиентскиеПараметры = ВнутренниеДанные Тогда
		КлиентскиеПараметры = Новый Структура("Сертификат, СвойстваПароля", Сертификат, СвойстваПароля);
		Возврат;
	КонецЕсли;
	
	Если КлиентскиеПараметры.Свойство("УказанКонтекстДругойОперации") Тогда
		СвойстваСертификата = ОбщиеВнутренниеДанные;
		КлиентскиеПараметры.ОписаниеДанных.КонтекстОперации.ПродолжитьОткрытие(Неопределено, Неопределено, СвойстваСертификата);
		Если СвойстваСертификата.Сертификат = Сертификат Тогда
			СвойстваПароля = СвойстваСертификата.СвойстваПароля;
		КонецЕсли;
	КонецЕсли;
	
	ОписаниеДанных             = КлиентскиеПараметры.ОписаниеДанных;
	ФормаОбъекта               = КлиентскиеПараметры.Форма;
	ТекущийСписокПредставлений = КлиентскиеПараметры.ТекущийСписокПредставлений;
	
	ВнутренниеДанные = ОбщиеВнутренниеДанные;
	Контекст = Новый Структура("Оповещение", Оповещение);
	Оповещение = Новый ОписаниеОповещения("ПродолжитьОткрытие", ЭтотОбъект);
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПродолжитьОткрытиеНачало(Новый ОписаниеОповещения(
		"ПродолжитьОткрытиеПослеНачала", ЭтотОбъект, Контекст), ЭтотОбъект, КлиентскиеПараметры);
	
КонецПроцедуры

// Продолжение процедуры ПродолжитьОткрытие.
&НаКлиенте
Процедура ПродолжитьОткрытиеПослеНачала(Результат, Контекст) Экспорт
	
	Если Результат <> Истина Тогда
		ПродолжитьОткрытиеЗавершение(Контекст);
		Возврат;
	КонецЕсли;
	
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("ПриОткрытии", Истина);
	Если СвойстваПароля <> Неопределено Тогда
		ДополнительныеПараметры.Вставить("ПриУстановкеПароляИзДругойОперации", Истина);
	КонецЕсли;
	ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект,
		ВнутренниеДанные, СвойстваПароля, ДополнительныеПараметры);
	
	МодульСервисКриптографииDSSПодтверждениеКлиент = Неопределено;
	Если ЭлектроннаяПодписьСлужебныйКлиент.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	КонецЕсли;
	
	ОткрытьДляВыбораДоверенности = Ложь;
	Если ПоДоверенности И Не ЗначениеЗаполнено(МашиночитаемаяДоверенность) Тогда
		ОткрытьДляВыбораДоверенности = Истина;
	КонецЕсли;
	
	Если БезПодтверждения И Не ОткрытьДляВыбораДоверенности
	   И (    ДополнительныеПараметры.ПарольУказан
	      Или ДополнительныеПараметры.ВводитьПарольВПрограммеЭлектроннойПодписи
	      Или ОблачныйПарольПодтвержден) Тогда
		
		Если МодульСервисКриптографииDSSПодтверждениеКлиент <> Неопределено Тогда
			Если НЕ МодульСервисКриптографииDSSПодтверждениеКлиент.ОблачнаяПодписьТребуетПодтверждения(ЭтотОбъект, ДополнительныеПараметры.ПарольУказан) Тогда
				ОбработкаПослеПредупреждения = Неопределено;
				ПодписатьДанные(Новый ОписаниеОповещения("ПродолжитьОткрытиеПослеПодписанияДанных", ЭтотОбъект, Контекст));
				Возврат;
			КонецЕсли;
		Иначе	
			ОбработкаПослеПредупреждения = Неопределено;
			ПодписатьДанные(Новый ОписаниеОповещения("ПродолжитьОткрытиеПослеПодписанияДанных", ЭтотОбъект, Контекст));
			Возврат;
		КонецЕсли;	
	КонецЕсли;
	
	Открыть();
	
	Если МодульСервисКриптографииDSSПодтверждениеКлиент <> Неопределено Тогда
		Если МодульСервисКриптографииDSSПодтверждениеКлиент.ПроверкаВыполненияНачальнойОперации(ЭтотОбъект, БезПодтверждения И ДополнительныеПараметры.ПарольУказан) Тогда 
			МодульСервисКриптографииDSSПодтверждениеКлиент.ВыполнитьНачальнуюОперациюСервиса(ЭтотОбъект, ОписаниеДанных, СвойстваПароля.Значение);
		КонецЕсли;
	КонецЕсли;	
	
	ПродолжитьОткрытиеЗавершение(Контекст);
	
КонецПроцедуры

// Продолжение процедуры ПродолжитьОткрытие.
&НаКлиенте
Процедура ПродолжитьОткрытиеПослеПодписанияДанных(Результат, Контекст) Экспорт
	
	ПродолжитьОткрытиеЗавершение(Контекст, Результат = Истина);
	
КонецПроцедуры

// Продолжение процедуры ПродолжитьОткрытие.
&НаКлиенте
Процедура ПродолжитьОткрытиеЗавершение(Контекст, Результат = Неопределено)
	
	Если Не Открыта() Тогда
		ОчиститьПеременныеФормы();
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Контекст.Оповещение, Результат);
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьВидимостьПредупреждения()
	
	Элементы.ГруппаОтозван.Видимость = СертификатОтозван;
	
	Если ЗначениеЗаполнено(РезультатПроверкиУдостоверяющегоЦентра) Тогда
		Элементы.ГруппаДополнительныеСведения.Видимость = Не СертификатОтозван И ЗначениеЗаполнено(
			РезультатПроверкиУдостоверяющегоЦентра.Предупреждение.ДополнительныеСведения);
		Элементы.ДекорацияДополнительныеСведения.Заголовок =
			РезультатПроверкиУдостоверяющегоЦентра.Предупреждение.ДополнительныеСведения;
	Иначе
		Элементы.ГруппаДополнительныеСведения.Видимость = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьПеременныеФормы()
	
	ОписаниеДанных             = Неопределено;
	ФормаОбъекта               = Неопределено;
	ТекущийСписокПредставлений = Неопределено;
	
КонецПроцедуры

&НаКлиенте
Функция ПеременныеОчищены()
	
	Возврат ОписаниеДанных = Неопределено
		И ФормаОбъекта = Неопределено
		И ТекущийСписокПредставлений = Неопределено;
	
КонецФункции

// АПК:78-выкл: для безопасной передачи данных на клиенте между формами, не отправляя их на сервер.
&НаКлиенте
Процедура ВыполнитьПодписание(КлиентскиеПараметры, ОбработкаЗавершения) Экспорт
// АПК:78-вкл: для безопасной передачи данных на клиенте между формами, не отправляя их на сервер.
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОбновитьФормуПередПовторнымИспользованием(ЭтотОбъект, КлиентскиеПараметры);
	
	ОписаниеДанных             = КлиентскиеПараметры.ОписаниеДанных;
	ФормаОбъекта               = КлиентскиеПараметры.Форма;
	ТекущийСписокПредставлений = КлиентскиеПараметры.ТекущийСписокПредставлений;
	
	ОбработкаПослеПредупреждения = ОбработкаЗавершения;
	
	Контекст = Новый Структура("ОбработкаЗавершения", ОбработкаЗавершения);
	ПодписатьДанные(Новый ОписаниеОповещения("ВыполнитьПодписаниеЗавершение", ЭтотОбъект, Контекст));
	
КонецПроцедуры

// Продолжение процедуры ВыполнитьПодписание.
&НаКлиенте
Процедура ВыполнитьПодписаниеЗавершение(Результат, Контекст) Экспорт
	
	ВыполнитьОбработкуОповещения(Контекст.ОбработкаЗавершения, Результат);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриИзмененииСпискаСертификатов()
	
	ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьОтпечаткиСертификатовНаКлиенте(
		Новый ОписаниеОповещения("ПриИзмененииСпискаСертификатовЗавершение", ЭтотОбъект));
	
КонецПроцедуры

// Продолжение процедуры ПриИзмененииСпискаСертификатов.
&НаКлиенте
Процедура ПриИзмененииСпискаСертификатовЗавершение(ОтпечаткиСертификатовНаКлиенте, Контекст) Экспорт
	
	СертификатПриИзмененииНаСервере(ОтпечаткиСертификатовНаКлиенте, Истина);
	
	ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект,
		ВнутренниеДанные, СвойстваПароля, Новый Структура("ПриИзмененииСвойствСертификата", Истина));
	
КонецПроцедуры

&НаСервере
Процедура СертификатПриИзмененииНаСервере(ОтпечаткиСертификатовНаКлиенте, ПроверитьСсылку = Ложь)
	
	Если ПроверитьСсылку
	   И ЗначениеЗаполнено(Сертификат)
	   И ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Сертификат, "Ссылка") <> Сертификат Тогда
		
		Сертификат = Неопределено;
	КонецЕсли;
	
	ЭлектроннаяПодписьСлужебный.СертификатПриИзмененииНаСервере(ЭтотОбъект, ОтпечаткиСертификатовНаКлиенте);
	
	Если ЭлектроннаяПодписьСлужебный.ИспользоватьСервисОблачнойПодписи() Тогда
		МодульСервисКриптографииDSSПодтверждениеСервер = ОбщегоНазначения.ОбщийМодуль("СервисКриптографииDSSПодтверждениеСервер");
		МодульСервисКриптографииDSSПодтверждениеСервер.ПодтверждениеПриИзмененииСертификата(ЭтотОбъект, Сертификат);
	КонецЕсли;
	
	Если Элементы.ГруппаДоверенность.Видимость Тогда
		ПодобратьДоверенностьПоСертификату();
	КонецЕсли;
	
	ОбновитьВидимостьПредупреждения();
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПодобратьДоверенность()
	ПодобратьДоверенность()
КонецПроцедуры

&НаСервере
Процедура ПодобратьДоверенность()
	
	Если Не ЭтоАдресВременногоХранилища(СертификатАдрес) Тогда
		Возврат;
	КонецЕсли;
		
	// СтандартныеПодсистемы.МашиночитаемыеДоверенности
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности") Тогда
		Возврат;
	КонецЕсли;
		
	МашиночитаемаяДоверенность = Неопределено;
	РезультатПроверкиМЧДДляПодписания = Неопределено;
	Элементы.МашиночитаемаяДоверенность.СписокВыбора.Очистить();
	
	МодульМашиночитаемыеДоверенностиФНС = ОбщегоНазначения.ОбщийМодуль("МашиночитаемыеДоверенностиФНС");
	СертификатКриптографии = Новый СертификатКриптографии(ПолучитьИзВременногоХранилища(СертификатАдрес));
	ОтборДляДоверенностейПоСертификату = МодульМашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату(
		СертификатКриптографии, "Представитель");
	ВыбранныеПоля = Новый Массив;
	ВыбранныеПоля.Добавить("МашиночитаемаяДоверенность");
	ВыбранныеПоля.Добавить("Наименование");
	ВыбранныеПоля.Добавить("ДатаВыдачи");
	
	Доверенности = МодульМашиночитаемыеДоверенностиФНС.ДоверенностиСОтбором(ОтборДляДоверенностейПоСертификату, ВыбранныеПоля);
	
	Если Доверенности.Количество() > 0 Тогда
		Для Каждого Строка Из Доверенности Цикл
			Элементы.МашиночитаемаяДоверенность.СписокВыбора.Добавить(Строка.МашиночитаемаяДоверенность,
				СтрШаблон("%1, %2", Строка.Наименование, Формат(Строка.ДатаВыдачи, "ДЛФ=D")));
		КонецЦикла;
		МашиночитаемаяДоверенность = Элементы.МашиночитаемаяДоверенность.СписокВыбора[0].Значение;
	КонецЕсли;
	
	// Конец СтандартныеПодсистемы.МашиночитаемыеДоверенности

КонецПроцедуры

&НаКлиенте
Процедура ПодписатьДанные(Оповещение)
	
	ОписаниеДанных.Вставить("ТипПодписи", ТипПодписи);
	
	Если ЭлектроннаяПодписьСлужебныйКлиент.ЭтоОперацияОблачнойПодписи(ЭтотОбъект) Тогда
		ЭлектроннаяПодписьСлужебныйКлиент.УстановитьСвойстваОблачнойПодписи(ОписаниеДанных,
			Новый Структура("УчетнаяЗапись, ДанныеПодтверждения", 
					ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьДанныеОблачнойПодписи(ЭтотОбъект, "НастройкиПользователя"),
					ЭлектроннаяПодписьСлужебныйКлиент.ПолучитьДанныеОблачнойПодписи(ЭтотОбъект, "ДанныеПодтверждения")));
	Иначе	
		ЭлектроннаяПодписьСлужебныйКлиент.УстановитьСвойстваОблачнойПодписи(ОписаниеДанных,
			Новый Структура("УчетнаяЗапись, ДанныеПодтверждения"));
	КонецЕсли;	
	
	Контекст = Новый Структура;
	Контекст.Вставить("Оповещение", Оповещение);
	Контекст.Вставить("ОшибкаНаКлиенте", Новый Структура);
	Контекст.Вставить("ОшибкаНаСервере", Новый Структура);
	
	Если СертификатДействителенДо < ОбщегоНазначенияКлиент.ДатаСеанса() Тогда
		
		ДатаОкончанияЗакрытогоКлюча = ДатаОкончанияЗакрытогоКлюча(СертификатАдрес);
		Если ЗначениеЗаполнено(ДатаОкончанияЗакрытогоКлюча) И ДатаОкончанияЗакрытогоКлюча
			< ОбщегоНазначенияКлиент.ДатаСеанса() Тогда
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", НСтр("ru = 'У выбранного сертификата истек срок действия закрытого ключа.
																	 |Выберите другой сертификат.'"));
		Иначе
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", НСтр("ru = 'У выбранного сертификата истек срок действия.
																	 |Выберите другой сертификат.'"));
		КонецЕсли;
		
		ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере);
		Возврат;
	КонецЕсли;

	Если СертификатОтозван Тогда
		Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки",
			НСтр("ru = 'Сертификат помечен в приложении как отозванный.
			|Выберите другой сертификат.'"));
		ДополнительныеДанныеОшибки = Новый Структура("ДополнительныеДанныеПроверокНаКлиенте", ОшибкаСертификатПомеченКакОтозванный());
		ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере,,ДополнительныеДанныеОшибки);
		Возврат;
	КонецЕсли;
	
	// СтандартныеПодсистемы.МашиночитаемыеДоверенности
	
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.МашиночитаемыеДоверенности")
		И ПоДоверенности
		И ЗначениеЗаполнено(МашиночитаемаяДоверенность) Тогда
		
		МодульМашиночитаемыеДоверенностиФНССлужебныйКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("МашиночитаемыеДоверенностиФНССлужебныйКлиент");
		РезультатПроверкиМЧДДляПодписания = МодульМашиночитаемыеДоверенностиФНССлужебныйКлиент.РезультатПроверкиМЧДДляПодписания(
			МашиночитаемаяДоверенность, СертификатАдрес);
		Если РезультатПроверкиМЧДДляПодписания.ПроверкаПодписанта.Верна = Ложь Тогда
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", РезультатПроверкиМЧДДляПодписания.ПроверкаПодписанта.ТекстПроверки);
			ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере);
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	// Конец СтандартныеПодсистемы.МашиночитаемыеДоверенности
	
	Если ЗначениеЗаполнено(РезультатПроверкиУдостоверяющегоЦентра)
		И Не РезультатПроверкиУдостоверяющегоЦентра.Действует Тогда
		
		Если РезультатПроверкиУдостоверяющегоЦентра.Предупреждение.РазрешитьПодписание Тогда
			ПодписаниеРазрешено = ОбщегоНазначенияКлиент.ХранилищеОбщихНастроекЗагрузить(
				Сертификат, "РазрешитьПодписание", Неопределено);
			
			Если ПодписаниеРазрешено = Неопределено Тогда
				Оповещение = Новый ОписаниеОповещения("ПодписатьДанныеПослеОтветаНаВопросОбУЦ", ЭтотОбъект, Контекст);
				
				ПараметрыВопроса = СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю();
				ПараметрыВопроса.Картинка = БиблиотекаКартинок.ДиалогВосклицание;
				ПараметрыВопроса.Заголовок = НСтр("ru = 'Запрос разрешения на подпись'");
				ПараметрыВопроса.ТекстФлажка = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Запомнить выбор для сертификата ""%1""'"), Сертификат);
				
				Кнопки = Новый СписокЗначений;
				Кнопки.Добавить(Истина, НСтр("ru = 'Разрешить подписание'"));
				Кнопки.Добавить(Ложь,   НСтр("ru = 'Отменить подписание'"));
				
				ПредупреждениеОбОшибке = РезультатПроверкиУдостоверяющегоЦентра.Предупреждение; // см. ЭлектроннаяПодписьСлужебныйКлиентСервер.ПредупреждениеПриПроверкеУдостоверяющегоЦентраСертификата
				СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю(Оповещение, ПредупреждениеОбОшибке.ТекстОшибки, Кнопки, ПараметрыВопроса);
				Возврат;
			КонецЕсли;
		Иначе
			ПодписаниеРазрешено = Ложь;
		КонецЕсли;
		
		ПодписатьДанныеПослеОтветаНаВопросОбУЦ(ПодписаниеРазрешено, Контекст);
		Возврат;
	КонецЕсли;
	
	ПодписатьДанныеПослеОтветаНаВопросОбУЦ(Истина, Контекст);
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеОтветаНаВопросОбУЦ(Результат, Контекст) Экспорт
	
	Если ТипЗнч(Результат) = Тип("Структура") Тогда
		
		БольшеНеЗадаватьЭтотВопрос = Результат.БольшеНеЗадаватьЭтотВопрос;
		Результат = Результат.Значение;
		
		Если БольшеНеЗадаватьЭтотВопрос Тогда
			ОбщегоНазначенияКлиент.ХранилищеОбщихНастроекСохранить(
				Сертификат, "РазрешитьПодписание", Результат);
		КонецЕсли;
		
	КонецЕсли;
	
	Если ПроверятьСертификат = ЭлектроннаяПодписьСлужебныйКлиентСервер.НеПроверятьСертификат() Тогда
		ПодписатьДанныеПослеПроверкиВыбранногоСертификата(Истина, Контекст);
	Иначе
		Если Результат = Неопределено Или Не Результат Тогда
			ПредупреждениеОбОшибке = РезультатПроверкиУдостоверяющегоЦентра.Предупреждение; // см. ЭлектроннаяПодписьСлужебныйКлиентСервер.ПредупреждениеПриПроверкеУдостоверяющегоЦентраСертификата
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", ПредупреждениеОбОшибке.ТекстОшибки);
			ДополнительныеДанныеОшибки = Новый Структура("ДополнительныеДанныеПроверокНаКлиенте", ПредупреждениеОбОшибке);
			ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере, ,
				ДополнительныеДанныеОшибки);
			Возврат;
		КонецЕсли;
		
		ДополнительныеПараметрыПроверок = ЭлектроннаяПодписьСлужебныйКлиент.ДополнительныеПараметрыПроверкиСертификата();
		ДополнительныеПараметрыПроверок.ПоказатьОшибку = Ложь;
		ДополнительныеПараметрыПроверок.ДляПроверкиПодписи = Истина;
		ДополнительныеПараметрыПроверок.ОбъединитьОшибкиДанныхСертификата = Ложь;
		ДополнительныеПараметрыПроверок.ВыполнятьПроверкуУдостоверяющегоЦентра = ЭлектроннаяПодписьСлужебныйКлиентСервер.НеПроверятьСертификат();
	
		ЭлектроннаяПодписьСлужебныйКлиент.ПроверитьСертификат(Новый ОписаниеОповещения(
				"ПодписатьДанныеПослеПроверкиВыбранногоСертификата", ЭтотОбъект, Контекст),
			СертификатАдрес,,, ДополнительныеПараметрыПроверок);
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеПроверкиВыбранногоСертификата(Результат, Контекст) Экспорт
	
	Если ТипЗнч(Результат) = Тип("Структура") Тогда // Ошибка при проверке сертификата.
		
		Если Результат.СертификатОтозван Тогда
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", НСтр("ru = 'Сертификат отозван.
																	 |Выберите другой сертификат.'"));
			ДополнительныеДанныеОшибки = Новый Структура("ДополнительныеДанныеПроверокНаКлиенте",
				ОшибкаСертификатПомеченКакОтозванный());
			ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере, ,
				ДополнительныеДанныеОшибки);
			Возврат;
		КонецЕсли;
		
		Контекст.Вставить("СертификатВерен", Ложь);
		Контекст.Вставить("ТребуетсяПроверка", Результат.ТребуетсяПроверка);
		
		Оповещение = Новый ОписаниеОповещения("ПодписатьДанныеПослеПредупрежденияПодписьНеверна", ЭтотОбъект,
			Новый Структура("Контекст, РезультатПроверкиСертификата", Контекст, Результат));
		
		ПараметрыВопроса = СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю();
		ПараметрыВопроса.Картинка = БиблиотекаКартинок.ДиалогВосклицание;
		ПараметрыВопроса.Заголовок = НСтр("ru = 'Подпись будет неверна'");
		ПараметрыВопроса.ПредлагатьБольшеНеЗадаватьЭтотВопрос = Ложь;
		
		Кнопки = Новый СписокЗначений;
		Кнопки.Добавить("ОтменитьПодписание",  НСтр("ru = 'Отменить подписание'"));
		Кнопки.Добавить("РазрешитьПодписание", НСтр("ru = 'Разрешить подписание'"));
		Кнопки.Добавить("ПоказатьОшибку",      НСтр("ru = 'Подробности...'"));
		
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Сертификат не прошел проверку. Подпись, установленная таким сертификатом, будет неверна.
				|
				|%1'"), ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбщееОписаниеОшибки(
			Результат.ОписаниеОшибкиНаКлиенте, Результат.ОписаниеОшибкиНаСервере, Неопределено));
		
		СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю(Оповещение, ТекстОшибки, Кнопки, ПараметрыВопроса);
		Возврат;
		
	КонецЕсли;
	
	Контекст.Вставить("СертификатВерен",   Истина);
	Контекст.Вставить("ТребуетсяПроверка", Ложь);
	ПодписатьДанныеПослеПредупрежденияПодписьНеверна(Новый Структура("Значение", "РазрешитьПодписание"), 
		Новый Структура("Контекст", Контекст));
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеПредупрежденияПодписьНеверна(Результат, ДополнительныеПараметры) Экспорт
	
	Контекст = ДополнительныеПараметры.Контекст;

	Если Результат = Неопределено Или Результат.Значение = "ОтменитьПодписание" Или Результат.Значение = "ПоказатьОшибку" Тогда
		
		Если ЗначениеЗаполнено(ДополнительныеПараметры.РезультатПроверкиСертификата.ОписаниеОшибкиНаКлиенте) Тогда
			Контекст.ОшибкаНаКлиенте.Вставить("ОписаниеОшибки", ДополнительныеПараметры.РезультатПроверкиСертификата.ОписаниеОшибкиНаКлиенте);
		КонецЕсли;
		Если ЗначениеЗаполнено(ДополнительныеПараметры.РезультатПроверкиСертификата.ОписаниеОшибкиНаСервере) Тогда
			Контекст.ОшибкаНаСервере.Вставить("ОписаниеОшибки", ДополнительныеПараметры.РезультатПроверкиСертификата.ОписаниеОшибкиНаСервере);
		КонецЕсли;
		
		ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере,,, Результат <> Неопределено И Результат.Значение = "ПоказатьОшибку");
		Возврат;
	
	КонецЕсли;
		
	ВыбранныйСертификат = Новый Структура;
	ВыбранныйСертификат.Вставить("Ссылка",    Сертификат);
	ВыбранныйСертификат.Вставить("Отпечаток", СертификатОтпечаток);
	ВыбранныйСертификат.Вставить("Данные",    СертификатАдрес);
	ОписаниеДанных.Вставить("ВыбранныйСертификат",   ВыбранныйСертификат);
	ОписаниеДанных.Вставить("ВыбраннаяДоверенность", МашиночитаемаяДоверенность);
	ОписаниеДанных.Вставить("РезультатПроверкиМЧДДляПодписания", РезультатПроверкиМЧДДляПодписания);
	
	Если ОписаниеДанных.Свойство("ПередВыполнением")
	   И ТипЗнч(ОписаниеДанных.ПередВыполнением) = Тип("ОписаниеОповещения") Тогда
		
		ПараметрыВыполнения = Новый Структура;
		ПараметрыВыполнения.Вставить("ОписаниеДанных", ОписаниеДанных);
		ПараметрыВыполнения.Вставить("Оповещение", Новый ОписаниеОповещения(
			"ПодписатьДанныеПослеОбработкиПередВыполнением", ЭтотОбъект, Контекст));
		
		ВыполнитьОбработкуОповещения(ОписаниеДанных.ПередВыполнением, ПараметрыВыполнения);
	Иначе
		ПодписатьДанныеПослеОбработкиПередВыполнением(Новый Структура, Контекст);
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеОбработкиПередВыполнением(Результат, Контекст) Экспорт
	
	Если ПеременныеОчищены() Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат.Свойство("ОписаниеОшибки") Тогда
		ОбработатьОшибку(Контекст.Оповещение, Новый Структура("ОписаниеОшибки", Результат.ОписаниеОшибки), Новый Структура);
		Возврат;
	КонецЕсли;
	
	Контекст.Вставить("ИдентификаторФормы", УникальныйИдентификатор);
	Если ТипЗнч(ФормаОбъекта) = Тип("ФормаКлиентскогоПриложения") Тогда
		Контекст.ИдентификаторФормы = ФормаОбъекта.УникальныйИдентификатор;
	ИначеЕсли ТипЗнч(ФормаОбъекта) = Тип("УникальныйИдентификатор") Тогда
		Контекст.ИдентификаторФормы = ФормаОбъекта;
	КонецЕсли;
	
	ПараметрыВыполнения = Новый Структура;
	ПараметрыВыполнения.Вставить("ОписаниеДанных",     ОписаниеДанных);
	ПараметрыВыполнения.Вставить("Форма",              ЭтотОбъект);
	ПараметрыВыполнения.Вставить("ИдентификаторФормы", Контекст.ИдентификаторФормы);
	ПараметрыВыполнения.Вставить("ЗначениеПароля",     СвойстваПароля.Значение);
	ПараметрыВыполнения.Вставить("СертификатАдрес",    СертификатАдрес);
	ПараметрыВыполнения.Вставить("СертификатВерен",    Контекст.СертификатВерен);
	ПараметрыВыполнения.Вставить("ТребуетсяПроверка",  Контекст.ТребуетсяПроверка);
	
	ПараметрыВыполнения.Вставить("ПолноеПредставлениеДанных",
		ЭлектроннаяПодписьСлужебныйКлиент.ПолноеПредставлениеДанных(ЭтотОбъект));
	ПараметрыВыполнения.Вставить("ТекущийСписокПредставлений", ТекущийСписокПредставлений);
	
	Контекст.Вставить("ПараметрыВыполнения", ПараметрыВыполнения);
	
	Если ЭлектроннаяПодписьКлиент.СоздаватьЭлектронныеПодписиНаСервере()
	   И ВыполнятьНаСервере <> Ложь Тогда
		
		Если ЗначениеЗаполнено(СертификатНаСервереОписаниеОшибки) Тогда
			Результат = Новый Структура("Ошибка", СертификатНаСервереОписаниеОшибки);
			СертификатНаСервереОписаниеОшибки = Новый Структура;
			ПодписатьДанныеПослеВыполненияНаСторонеСервера(Результат, Контекст);
		Иначе
			// Попытка подписания на сервере.
			ЭлектроннаяПодписьСлужебныйКлиент.ВыполнитьНаСтороне(Новый ОписаниеОповещения(
					"ПодписатьДанныеПослеВыполненияНаСторонеСервера", ЭтотОбъект, Контекст),
				"Подписание", "НаСторонеСервера", Контекст.ПараметрыВыполнения);
		КонецЕсли;
	Иначе
		ПодписатьДанныеПослеВыполненияНаСторонеСервера(Неопределено, Контекст);
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Асинх Процедура ПодписатьДанныеПослеВыполненияНаСторонеСервера(Результат, Контекст) Экспорт
	
	Если ПеременныеОчищены() Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат <> Неопределено Тогда
		ПодписатьДанныеПослеВыполнения(Результат);
	КонецЕсли;
	
	Если Результат <> Неопределено И Не Результат.Свойство("Ошибка") Тогда
		ПодписатьДанныеПослеВыполненияНаСторонеКлиента(Новый Структура, Контекст);
	Иначе
		Если Результат <> Неопределено Тогда
			Контекст.ОшибкаНаСервере = Результат.Ошибка;
			Если ВыполнятьНаСервере = Истина Тогда
				ПодписатьДанныеПослеВыполненияНаСторонеКлиента(Новый Структура, Контекст);
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
		// Попытка подписания на клиенте.
		ЭлектроннаяПодписьСлужебныйКлиент.ВыполнитьНаСтороне(Новый ОписаниеОповещения(
				"ПодписатьДанныеПослеВыполненияНаСторонеКлиента", ЭтотОбъект, Контекст),
			"Подписание", "НаСторонеКлиента", Контекст.ПараметрыВыполнения);
	КонецЕсли;
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеВыполненияНаСторонеКлиента(Результат, Контекст) Экспорт
	
	Если ПеременныеОчищены() Тогда
		Возврат;
	КонецЕсли;
	
	ПодписатьДанныеПослеВыполнения(Результат);
	
	Если Результат.Свойство("Ошибка") Тогда
		
		Если ОписаниеДанных.Свойство("КонтекстОперации") Тогда
			ОписаниеДанных.КонтекстОперации = ЭтотОбъект;
		КонецЕсли;
		
		Контекст.ОшибкаНаКлиенте = Результат.Ошибка;
		НеподписанныеДанные = ЭлектроннаяПодписьСлужебныйКлиент.СвойстваТекущегоЭлементаДанных(
			Контекст.ПараметрыВыполнения);
			
		ОбработатьОшибку(Контекст.Оповещение, Контекст.ОшибкаНаКлиенте, Контекст.ОшибкаНаСервере, НеподписанныеДанные);
		Возврат;
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПредставлениеДанных)
	   И (Не ОписаниеДанных.Свойство("СообщитьОЗавершении")
	      Или ОписаниеДанных.СообщитьОЗавершении <> Ложь) Тогда
		
		ЭлектроннаяПодписьКлиент.ИнформироватьОПодписанииОбъекта(
			ЭлектроннаяПодписьСлужебныйКлиент.ПолноеПредставлениеДанных(ЭтотОбъект),
			ТекущийСписокПредставлений.Количество() > 1);
	КонецЕсли;
	
	Если ОписаниеДанных.Свойство("КонтекстОперации") Тогда
		ОписаниеДанных.КонтекстОперации = ЭтотОбъект;
	КонецЕсли;
	
	Если ОповеститьОбОкончанииСрокаДействия Тогда
		
		ПараметрыОткрытияФормы = Новый Структура("Сертификат", Сертификат);
		Если РезультатПроверкиУдостоверяющегоЦентра <> Неопределено 
			И РезультатПроверкиУдостоверяющегоЦентра.Действует
			И (ЗначениеЗаполнено(РезультатПроверкиУдостоверяющегоЦентра.Предупреждение.ТекстОшибки) 
			Или ЗначениеЗаполнено(РезультатПроверкиУдостоверяющегоЦентра.Предупреждение.ДополнительныеСведения)) Тогда
			ПараметрыОткрытияФормы.Вставить("ДополнительныеДанныеПроверки", РезультатПроверкиУдостоверяющегоЦентра.Предупреждение);
		КонецЕсли;
		
		ДействиеПриНажатии = Новый ОписаниеОповещения("ОткрытьФормуОповещенияОНеобходимостиЗаменыСертификата",
			ЭлектроннаяПодписьСлужебныйКлиент, ПараметрыОткрытияФормы);
		
		ПоказатьОповещениеПользователя(
			НСтр("ru = 'Необходима замена сертификата'"), ДействиеПриНажатии, Сертификат,
			БиблиотекаКартинок.ДиалогВосклицание, СтатусОповещенияПользователя.Важное,
			Сертификат);
	КонецЕсли;

	
	ВыполнитьОбработкуОповещения(Контекст.Оповещение, Истина);
	
КонецПроцедуры

// Продолжение процедуры ПодписатьДанные.
&НаКлиенте
Процедура ПодписатьДанныеПослеВыполнения(Результат)
	
	Если Результат.Свойство("ОперацияНачалась") Тогда
		ЭлектроннаяПодписьСлужебныйКлиент.ОбработатьПарольВФорме(ЭтотОбъект, ВнутренниеДанные,
			СвойстваПароля, Новый Структура("ПриУспешномВыполненииОперации", Истина));
	КонецЕсли;
	
	Если Результат.Свойство("ЕстьОбработанныеЭлементыДанных") Тогда
		// После начала подписания изменять сертификат более недопустимо,
		// иначе набор данных будет обработан по-разному.
		Элементы.Сертификат.ТолькоПросмотр = Истина;
		Элементы.Комментарий.ТолькоПросмотр = Истина;
	КонецЕсли;
	
	Если Элементы.ГруппаДоверенность.Видимость Тогда
		ОбщегоНазначенияКлиент.ХранилищеОбщихНастроекСохранить(
			Сертификат, "ПоДоверенности", ПоДоверенности);
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция ДатаОкончанияЗакрытогоКлюча(АдресСертификата)
	СвойстваСертификата = ЭлектроннаяПодпись.СвойстваСертификата(ПолучитьИзВременногоХранилища(АдресСертификата));
	Возврат СвойстваСертификата.ДатаОкончанияЗакрытогоКлюча;
КонецФункции

&НаКлиенте
Процедура ОбработатьОшибку(Оповещение, ОшибкаНаКлиенте, ОшибкаНаСервере, НеподписанныеДанные = Неопределено, ДополнительныеДанные = Неопределено, ПоказыватьОшибку = Истина)
	
	Если ОписаниеДанных.Свойство("ПрекратитьВыполнение") Тогда
		
		Если ПоказыватьОшибку Тогда
			
			Если Не ОписаниеДанных.Свойство("ОписаниеОшибки") Тогда
				ОписаниеДанных.Вставить("ОписаниеОшибки");
			КонецЕсли;
		
		ОписаниеДанных.ОписаниеОшибки = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОбщееОписаниеОшибки(
			ОшибкаНаКлиенте, ОшибкаНаСервере, НСтр("ru = 'Не удалось подписать документы по причине:'"));

		КонецЕсли;
		
		Если Открыта() Тогда
			Закрыть(Ложь);
		Иначе
			ВыполнитьОбработкуОповещения(Оповещение, Ложь);
		КонецЕсли;
		
	Иначе
		
		Если Не Открыта() И ОбработкаПослеПредупреждения = Неопределено Тогда
			Открыть();
		КонецЕсли;
		
		Если ПоказыватьОшибку Тогда
			ДополнительныеПараметры = Новый Структура;
			Если ЗначениеЗаполнено(ДополнительныеДанные) Тогда
				Для Каждого КлючИЗначение Из ДополнительныеДанные Цикл
					ДополнительныеПараметры.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение);
				КонецЦикла;
			КонецЕсли;
			Если НеподписанныеДанные <> Неопределено Тогда
				ДополнительныеПараметры.Вставить("НеподписанныеДанные", НеподписанныеДанные);
			КонецЕсли;
			ДополнительныеПараметры.Вставить("Сертификат", Сертификат);
			
			ЭлектроннаяПодписьСлужебныйКлиент.ПоказатьОшибкуОбращенияКПрограмме(
				НСтр("ru = 'Не удалось подписать документы'"), "", 
				ОшибкаНаКлиенте, ОшибкаНаСервере, ДополнительныеПараметры, ОбработкаПослеПредупреждения);
		КонецЕсли;
			
		ВыполнитьОбработкуОповещения(Оповещение, Ложь);
		
	КонецЕсли;
	
КонецПроцедуры

// СтандартныеПодсистемы.ЭлектроннаяПодписьСервисаDSS

#Область ПодключаемыеОбработчики

&НаКлиенте
Процедура Подключаемый_ПодтверждениеОбработкаКоманды(Команда)
	
	МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеОбработкаКоманды(ЭтотОбъект, Команда, ОписаниеДанных, 
		СвойстваПароля.Значение);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПодтверждениеОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, 
	СтандартнаяОбработка)

	МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеОбработкаНавигационнойСсылки(ЭтотОбъект, Элемент, 
		НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПодтверждениеПриИзменении(Элемент)

	МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеПриИзменении(ЭтотОбъект, Элемент, ОписаниеДанных, 
		СвойстваПароля.Значение);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПодтверждениеОбработчикОжидания()
	
	МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеОбработкаОжидания(ЭтотОбъект, ОписаниеДанных, 
		СвойстваПароля.Значение);

КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПодтверждениеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	МодульСервисКриптографииDSSПодтверждениеКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("СервисКриптографииDSSПодтверждениеКлиент");
	МодульСервисКриптографииDSSПодтверждениеКлиент.ПодтверждениеНачалоВыбора(ЭтотОбъект, Элемент, ДанныеВыбора, 
		СтандартнаяОбработка);
	
КонецПроцедуры

#КонецОбласти

// Конец СтандартныеПодсистемы.ЭлектроннаяПодписьСервисаDSS

#КонецОбласти

Связанные материалы