Files
SSL/SSL/src/CommonModules/ЭлектроннаяПодписьСлужебный/Module.bsl
T
2019-04-12 00:28:00 +03:00

2098 lines
141 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) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
// Добавляет сертификаты к переданному объекту.
Процедура ДобавитьСертификатыШифрования(ОбъектСсылка, МассивОтпечатков) Экспорт
УстановитьПривилегированныйРежим(Истина);
ПорядковыйНомер = 1;
Для Каждого ОтпечатокСтруктура Из МассивОтпечатков Цикл
МенеджерЗаписи = РегистрыСведений.СертификатыШифрования.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ЗашифрованныйОбъект = ОбъектСсылка;
МенеджерЗаписи.Отпечаток = ОтпечатокСтруктура.Отпечаток;
МенеджерЗаписи.Представление = ОтпечатокСтруктура.Представление;
МенеджерЗаписи.Сертификат = Новый ХранилищеЗначения(ОтпечатокСтруктура.Сертификат);
МенеджерЗаписи.ПорядковыйНомер = ПорядковыйНомер;
ПорядковыйНомер = ПорядковыйНомер + 1;
МенеджерЗаписи.Записать();
КонецЦикла;
КонецПроцедуры
// Очищает записи о сертификатах шифрования после расшифровка объекта.
Процедура ОчиститьСертификатыШифрования(ОбъектСсылка) Экспорт
УстановитьПривилегированныйРежим(Истина);
НаборЗаписей = РегистрыСведений.СертификатыШифрования.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ЗашифрованныйОбъект.Установить(ОбъектСсылка);
НаборЗаписей.Записать(Истина);
КонецПроцедуры
// Только для внутреннего использования.
Процедура ОформитьСписокПодписей(Форма, ИмяСпискаПодписей) Экспорт
Элемент = Форма.УсловноеОформление.Элементы.Добавить();
ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(ИмяСпискаПодписей);
ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяСпискаПодписей + ".ПодписьВерна");
ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ОтборЭлемента.ПравоеЗначение = Ложь;
Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветОсобогоТекста);
КонецПроцедуры
// Определяет доступность электронной подписи для объекта (по его типу)
Функция ДоступнаЭлектроннаяПодпись(ТипОбъекта) Экспорт
Возврат ЭлектроннаяПодписьСлужебныйПовтИсп.ТипыВладельцев().Получить(ТипОбъекта) <> Неопределено;
КонецФункции
// Возвращает адрес сертификата во временном хранилище и его расширение.
//
// Параметры:
// СведенияОЭлектроннойПодписи - Структура - Строка с подписями из массива полученного методом ЭлектроннаяПодпись.УстановленныеПодписи.
// УникальныйИдентификатор - УникальныйИдентификатор - Идентификатор формы.
//
// Возвращаемое значение:
// Структура -
// * РасширениеСертификата - Строка - Расширение файла сертификата.
// * АдресСертификата - Строка - Адрес во временном хранилище, по которому был помещен сертификат.
//
Функция ДанныеПоСертификату(СведенияОЭлектроннойПодписи, УникальныйИдентификатор) Экспорт
Результат = Новый Структура("РасширениеСертификата, АдресСертификата");
ДанныеСертификата = СведенияОЭлектроннойПодписи.Сертификат.Получить();
Если ТипЗнч(ДанныеСертификата) = Тип("Строка") Тогда
Результат.РасширениеСертификата = "txt";
Результат.АдресСертификата = ПоместитьВоВременноеХранилище(
ДвоичныеДанныеСтроки(ДанныеСертификата), УникальныйИдентификатор);
Иначе
Результат.РасширениеСертификата = "cer";
Результат.АдресСертификата = ПоместитьВоВременноеХранилище(
ДанныеСертификата, УникальныйИдентификатор);
КонецЕсли;
Возврат Результат;
КонецФункции
// Возвращает признак возможности интерактивного использования электронных подписей и шифрования
// для текущего пользователя.
//
// Возвращаемое значение:
// Булево - если Истина, то интерактивное использование электронных подписей и шифрование возможно.
//
Функция ИспользоватьИнтерактивноеДобавлениеЭлектронныхПодписейИШифрование() Экспорт
Возврат ПравоДоступа("ИнтерактивноеДобавление", Метаданные.Справочники.СертификатыКлючейЭлектроннойПодписиИШифрования);
КонецФункции
// Из переданных имен файлов выделяются имена файлов данных и имена файлов их подписей.
// Сопоставление происходит по правилам формирования имени подписи и расширения файла подписи (p7s).
// Например:
// Имя файла данных: "example.txt"
// имя файла подписи: "example-Ivanov Petr.p7s"
// имя файла подписи: "example-Ivanov Petr (1).p7s".
//
// Параметры:
// ИменаФайлов - Массив - имена файлов типа Строка.
//
// Возвращаемое значение:
// Соответствие - содержит:
// * Ключ - Строка - имя файла.
// * Значение - Массив - имена файлов подписей типа Строка.
//
Функция ИменаФайловПодписейИменФайловДанных(ИменаФайлов) Экспорт
РасширениеДляФайловПодписи = ЭлектроннаяПодпись.ПерсональныеНастройки().РасширениеДляФайловПодписи;
Результат = Новый Соответствие;
// Разделяем файлы по расширению.
ИменаФайловДанных = Новый Массив;
ИменаФайловПодписей = Новый Массив;
Для Каждого ИмяФайла Из ИменаФайлов Цикл
Если СтрЗаканчиваетсяНа(ИмяФайла, РасширениеДляФайловПодписи) Тогда
ИменаФайловПодписей.Добавить(ИмяФайла);
Иначе
ИменаФайловДанных.Добавить(ИмяФайла);
КонецЕсли;
КонецЦикла;
// Отсортируем имена файлов данных по убыванию числа символов в строке.
Для ИндексА = 1 По ИменаФайловДанных.Количество() Цикл
ИндексМАКС = ИндексА; // Считаем что текущий файл имеет самое большое число символов.
Для ИндексБ = ИндексА+1 По ИменаФайловДанных.Количество() Цикл
Если СтрДлина(ИменаФайловДанных[ИндексМАКС-1]) > СтрДлина(ИменаФайловДанных[ИндексБ-1]) Тогда
ИндексМАКС = ИндексБ;
КонецЕсли;
КонецЦикла;
своп = ИменаФайловДанных[ИндексА-1];
ИменаФайловДанных[ИндексА-1] = ИменаФайловДанных[ИндексМАКС-1];
ИменаФайловДанных[ИндексМАКС-1] = своп;
КонецЦикла;
// Поиск соответствий имен файлов.
Для Каждого ИмяФайлаДанных Из ИменаФайловДанных Цикл
Результат.Вставить(ИмяФайлаДанных, НайтиИменаФайловПодписей(ИмяФайлаДанных, ИменаФайловПодписей));
КонецЦикла;
// Оставшиеся файлы подписей не распознаны как подписи относящиеся к какому то файлу.
Для Каждого ИмяФайлаПодписи Из ИменаФайловПодписей Цикл
Результат.Вставить(ИмяФайлаПодписи, Новый Массив);
КонецЦикла;
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// Обработчики событий подсистем конфигурации.
// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
Обработчик = Обработчики.Добавить();
Обработчик.НачальноеЗаполнение = Истина;
Обработчик.Процедура = "Справочники.ПрограммыЭлектроннойПодписиИШифрования.ЗаполнитьНачальныеНастройки";
Обработчик.РежимВыполнения = "Монопольно";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "2.2.4.7";
Обработчик.Процедура = "ЭлектроннаяПодписьСлужебный.ПеренестиНастройкиМенеджераКриптографии";
Обработчик.РежимВыполнения = "Монопольно";
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "3.0.1.69";
Обработчик.Комментарий =
НСтр("ru = 'Заполнение справочника Программы электронной подписи и шифрования.'");
Обработчик.Идентификатор = Новый УникальныйИдентификатор("8e76369a-e16c-415d-bfeb-95e7e5f07a00");
Обработчик.Процедура = "Справочники.ПрограммыЭлектроннойПодписиИШифрования.ОбработатьДанныеДляПереходаНаНовуюВерсию";
Обработчик.РежимВыполнения = "Отложенно";
Обработчик.ПроцедураЗаполненияДанныхОбновления = "Справочники.ПрограммыЭлектроннойПодписиИШифрования.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
Обработчик.ЧитаемыеОбъекты = "Справочник.ПрограммыЭлектроннойПодписиИШифрования";
Обработчик.ИзменяемыеОбъекты = "Справочник.ПрограммыЭлектроннойПодписиИШифрования";
Обработчик.ОчередьОтложеннойОбработки = 1;
Обработчик.ПроцедураПроверки = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПереименованийОбъектовМетаданных.
Процедура ПриДобавленииПереименованийОбъектовМетаданных(Итог) Экспорт
Библиотека = "СтандартныеПодсистемы";
СтароеИмя = "Роль.ИспользованиеЭЦП";
НовоеИмя = "Роль.ИспользованиеЭП";
ОбщегоНазначения.ДобавитьПереименование(Итог, "2.2.1.7", СтароеИмя, НовоеИмя, Библиотека);
СтароеИмя = "Подсистема.СтандартныеПодсистемы.Подсистема.ЭлектроннаяЦифроваяПодпись";
НовоеИмя = "Подсистема.СтандартныеПодсистемы.Подсистема.ЭлектроннаяПодпись";
ОбщегоНазначения.ДобавитьПереименование(Итог, "2.2.1.7", СтароеИмя, НовоеИмя, Библиотека);
СтароеИмя = "Роль.ИспользованиеЭП";
НовоеИмя = "Роль.ИспользованиеЭлектроннойПодписиИШифрования";
ОбщегоНазначения.ДобавитьПереименование(Итог, "2.3.1.10", СтароеИмя, НовоеИмя, Библиотека);
СтароеИмя = "Роль.ИспользованиеЭлектроннойПодписиИШифрования";
НовоеИмя = "Роль.ДобавлениеИзменениеЭлектронныхПодписейИШифрование";
ОбщегоНазначения.ДобавитьПереименование(Итог, "2.3.3.2", СтароеИмя, НовоеИмя, Библиотека);
КонецПроцедуры
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиента.
Процедура ПриДобавленииПараметровРаботыКлиента(Параметры) Экспорт
Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
НастройкиПодсистемы = Новый Структура;
НастройкиПодсистемы.Вставить("ПерсональныеНастройки", ЭлектроннаяПодпись.ПерсональныеНастройки());
НастройкиПодсистемы.Вставить("ОбщиеНастройки", ЭлектроннаяПодпись.ОбщиеНастройки());
НастройкиПодсистемы = Новый ФиксированнаяСтруктура(НастройкиПодсистемы);
Параметры.Вставить("ЭлектроннаяПодпись", НастройкиПодсистемы);
КонецЕсли;
КонецПроцедуры
// См. ЗагрузкаДанныхИзФайлаПереопределяемый.ПриОпределенииСправочниковДляЗагрузкиДанных.
Процедура ПриОпределенииСправочниковДляЗагрузкиДанных(ЗагружаемыеСправочники) Экспорт
// Загрузка в справочник ПрограммыЭлектроннойПодписиИШифрования запрещена.
СтрокаТаблицы = ЗагружаемыеСправочники.Найти(Метаданные.Справочники.ПрограммыЭлектроннойПодписиИШифрования.ПолноеИмя(), "ПолноеИмя");
Если СтрокаТаблицы <> Неопределено Тогда
ЗагружаемыеСправочники.Удалить(СтрокаТаблицы);
КонецЕсли;
// Загрузка в справочник СертификатыКлючейЭлектроннойПодписиИШифрования запрещена.
СтрокаТаблицы = ЗагружаемыеСправочники.Найти(Метаданные.Справочники.СертификатыКлючейЭлектроннойПодписиИШифрования.ПолноеИмя(), "ПолноеИмя");
Если СтрокаТаблицы <> Неопределено Тогда
ЗагружаемыеСправочники.Удалить(СтрокаТаблицы);
КонецЕсли;
КонецПроцедуры
// См. ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииОбъектовСРедактируемымиРеквизитами.
Процедура ПриОпределенииОбъектовСРедактируемымиРеквизитами(Объекты) Экспорт
Объекты.Вставить(Метаданные.Справочники.ПрограммыЭлектроннойПодписиИШифрования.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке");
Объекты.Вставить(Метаданные.Справочники.СертификатыКлючейЭлектроннойПодписиИШифрования.ПолноеИмя(), "РеквизитыНеРедактируемыеВГрупповойОбработке");
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// Возвращает менеджер криптографии (на сервере) для указанной программы.
//
// Параметры:
// Операция - Строка - если не пустая, то должна содержать одну из строк, которые определяют
// операцию для вставки в описание ошибки: Подписание, ПроверкаПодписи, Шифрование,
// Расшифровка, ПроверкаСертификата, ПолучениеСертификатов.
//
// ПоказатьОшибку - Булево - если Истина, тогда будет вызвано исключение, содержащее описание ошибки.
//
// ОписаниеОшибки - Строка - возвращаемое описание ошибки, когда функция возвратила значение Неопределено.
// - Структура - содержит ошибки обращения к программам, если возвращено Неопределено.
// * ОписаниеОшибки - Строка - полное описание ошибки, когда оно возвращается строкой.
// * ЗаголовокОшибки - Строка - заголовок ошибки, который соответствует операции.
// * ИмяКомпьютера - Строка - имя компьютера при получении менеджера криптографии.
// * Описание - Строка - описание общей ошибки.
// * Общая - Булево - если Истина, то содержит описание ошибки для всех программ,
// иначе альтернативное описание массиву Ошибки.
// * КАдминистратору - Булево - для исправления общей ошибки требуются права администратора.
// * Ошибки - Массив - содержит структуры описания ошибок программ со свойствами:
// * Программа - СправочникСсылка.ПрограммыЭлектроннойПодписиИШифрования.
// * Описание - Строка - содержит представление ошибки.
// * ИзИсключения - Булево - описание содержит краткое представление информации об ошибке.
// * НеУказанПуть - Булево - описание содержит ошибку о неуказанном пути для ОС Linux.
// * КАдминистратору - Булево - для исправления ошибки требуются права администратора.
//
// Программа - Неопределено - возвращает менеджер криптографии первой
// программы из справочника для которой удалось его создать.
// - СправочникСсылка.ПрограммыЭлектроннойПодписиИШифрования - программа
// для которой нужно создать и вернуть менеджер криптографии.
//
// Возвращаемое значение:
// МенеджерКриптографии - менеджер криптографии.
// Неопределено - произошла ошибка, описание которой в параметре ОписаниеОшибки.
//
Функция МенеджерКриптографии(Операция, ПоказатьОшибку = Истина, ОписаниеОшибки = "", Программа = Неопределено) Экспорт
ИмяКомпьютера = ИмяКомпьютера();
Ошибки = Новый Массив;
Менеджер = НовыйМенеджерКриптографии(Программа, Ошибки, ИмяКомпьютера);
Если Менеджер <> Неопределено Тогда
Возврат Менеджер;
КонецЕсли;
Если Операция = "Подписание" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось подписать данные на сервере %1 по причине:'");
ИначеЕсли Операция = "ПроверкаПодписи" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось проверить подпись на сервере %1 по причине:'");
ИначеЕсли Операция = "Шифрование" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось зашифровать данные на сервере %1 по причине:'");
ИначеЕсли Операция = "Расшифровка" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось расшифровать данные на сервере %1 по причине:'");
ИначеЕсли Операция = "ПроверкаСертификата" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось проверить сертификат на сервере %1 по причине:'");
ИначеЕсли Операция = "ПолучениеСертификатов" Тогда
ЗаголовокОшибки = НСтр("ru = 'Не удалось получить сертификаты на сервере %1 по причине:'");
ИначеЕсли Операция <> "" Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в функции МенеджерКриптографии.
|Неверное значение параметра Операция ""%1"".'"), Операция);
ИначеЕсли ТипЗнч(ОписаниеОшибки) = Тип("Структура")
И ОписаниеОшибки.Свойство("ЗаголовокОшибки") Тогда
ЗаголовокОшибки = ОписаниеОшибки.ЗаголовокОшибки;
Иначе
ЗаголовокОшибки = НСтр("ru = 'Не удалось выполнить операцию на сервере %1 по причине:'");
КонецЕсли;
ЗаголовокОшибки = СтрЗаменить(ЗаголовокОшибки, "%1", ИмяКомпьютера);
СвойстваОшибки = Новый Структура;
СвойстваОшибки.Вставить("ЗаголовокОшибки", ЗаголовокОшибки);
СвойстваОшибки.Вставить("ИмяКомпьютера", ИмяКомпьютера);
СвойстваОшибки.Вставить("КАдминистратору", Истина);
СвойстваОшибки.Вставить("Общая", Ложь);
СвойстваОшибки.Вставить("Ошибки", Ошибки);
Если Ошибки.Количество() = 0 Тогда
ТекстОшибки = НСтр("ru = 'Не предусмотрено использование ни одной программы.'");
СвойстваОшибки.Общая = Истина;
СвойстваОшибки.Вставить("Инструкция", Истина);
СвойстваОшибки.Вставить("НастройкаПрограмм", Истина);
ИначеЕсли Программа <> Неопределено Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Программа ""%1"" не доступна или не установлена.'"), Программа);
Иначе
ТекстОшибки = НСтр("ru = 'Ни одна из программ не доступна или не установлена.'");
КонецЕсли;
СвойстваОшибки.Вставить("Описание", ТекстОшибки);
Если Не Пользователи.ЭтоПолноправныйПользователь(,, Ложь) Тогда
ТекстОшибки = ТекстОшибки + Символы.ПС + Символы.ПС
+ НСтр("ru = 'Обратитесь к администратору.'");
КонецЕсли;
СвойстваОшибки.Вставить("ОписаниеОшибки", ЗаголовокОшибки + Символы.ПС + ТекстОшибки);
Если ТипЗнч(ОписаниеОшибки) = Тип("Структура") Тогда
ОписаниеОшибки = СвойстваОшибки;
Иначе
ОписаниеОшибки = СвойстваОшибки.ОписаниеОшибки;
КонецЕсли;
Если ПоказатьОшибку Тогда
ВызватьИсключение ТекстОшибки;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Находит сертификат на компьютере по строке отпечатка.
//
// Параметры:
// Отпечаток - Строка - Base64 кодированный отпечаток сертификата.
// ТолькоВЛичномХранилище - Булево - если Истина, тогда искать в личном хранилище, иначе везде.
//
// Возвращаемое значение:
// СертификатКриптографии - сертификат электронной подписи и шифрования.
// Неопределено - сертификат не найден.
//
Функция ПолучитьСертификатПоОтпечатку(Отпечаток, ТолькоВЛичномХранилище,
ПоказатьОшибку = Истина, Программа = Неопределено, ОписаниеОшибки = "") Экспорт
МенеджерКриптографии = МенеджерКриптографии("ПолучениеСертификатов",
ПоказатьОшибку, ОписаниеОшибки, Программа);
Если МенеджерКриптографии = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТипХранилища = ЭлектроннаяПодписьСлужебныйКлиентСервер.ТипХранилищаДляПоискаСертификата(ТолькоВЛичномХранилище);
Попытка
ДвоичныеДанныеОтпечатка = Base64Значение(Отпечаток);
Исключение
Если ПоказатьОшибку Тогда
ВызватьИсключение;
КонецЕсли;
ИнформацияОбОшибке = ИнформацияОбОшибке();
ПредставлениеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
Если Не ЗначениеЗаполнено(ПредставлениеОшибки) Тогда
Попытка
ХранилищеСертификатовКриптографии = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилища);
Исключение
Если ПоказатьОшибку Тогда
ВызватьИсключение;
КонецЕсли;
ИнформацияОбОшибке = ИнформацияОбОшибке();
ПредставлениеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
КонецЕсли;
Если Не ЗначениеЗаполнено(ПредставлениеОшибки) Тогда
Попытка
Сертификат = ХранилищеСертификатовКриптографии.НайтиПоОтпечатку(ДвоичныеДанныеОтпечатка);
Исключение
Если ПоказатьОшибку Тогда
ВызватьИсключение;
КонецЕсли;
ИнформацияОбОшибке = ИнформацияОбОшибке();
ПредставлениеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
КонецЕсли;
Если ТипЗнч(Сертификат) = Тип("СертификатКриптографии") Тогда
Возврат Сертификат;
КонецЕсли;
Если ЗначениеЗаполнено(ПредставлениеОшибки) Тогда
ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Сертификат не найден на сервере по причине:
|%1'")
+ Символы.ПС,
ПредставлениеОшибки);
Иначе
ТекстОшибки = НСтр("ru = 'Сертификат не найден на сервере.'");
КонецЕсли;
Если Не Пользователи.ЭтоПолноправныйПользователь(,, Ложь) Тогда
ТекстОшибки = ТекстОшибки + Символы.ПС + НСтр("ru = 'Обратитесь к администратору.'")
КонецЕсли;
ТекстОшибки = СокрП(ТекстОшибки);
Если ТипЗнч(ОписаниеОшибки) = Тип("Структура") Тогда
ОписаниеОшибки = Новый Структура;
ОписаниеОшибки.Вставить("ОписаниеОшибки", ТекстОшибки);
Иначе
ОписаниеОшибки = ПредставлениеОшибки;
КонецЕсли;
Возврат Неопределено;
КонецФункции
// Только для внутреннего использования.
Функция ДобавкаВремени() Экспорт
Возврат ТекущаяДатаСеанса() - ТекущаяУниверсальнаяДата();
КонецФункции
// Сохраняет настройки текущего пользователя для работы с электронной подписью.
Процедура СохранитьПерсональныеНастройки(ПерсональныеНастройки) Экспорт
КлючПодсистемы = КлючХраненияНастроек();
Для Каждого КлючИЗначение Из ПерсональныеНастройки Цикл
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(КлючПодсистемы, КлючИЗначение.Ключ,
КлючИЗначение.Значение);
КонецЦикла;
КонецПроцедуры
// Ключ, который используется для хранения настроек подсистемы.
Функция КлючХраненияНастроек() Экспорт
Возврат "ЭЦП"; // Не заменять на "ЭП". Используется для обратной совместимости.
КонецФункции
// Только для внутреннего использования.
Процедура ПередНачаломРедактированияСертификатаКлюча(Ссылка, Сертификат, ПараметрыРеквизитов) Экспорт
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("ИмяРеквизита", Новый ОписаниеТипов("Строка"));
Таблица.Колонки.Добавить("ТолькоПросмотр", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("ПроверкаЗаполнения", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("Видимость", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("ЗначениеЗаполнения");
ЭлектроннаяПодписьПереопределяемый.ПередНачаломРедактированияСертификатаКлюча(Ссылка, Сертификат, Таблица);
ПараметрыРеквизитов = Новый Структура;
Для каждого Строка Из Таблица Цикл
Параметры = Новый Структура;
Параметры.Вставить("ТолькоПросмотр", Строка.ТолькоПросмотр);
Параметры.Вставить("ПроверкаЗаполнения", Строка.ПроверкаЗаполнения);
Параметры.Вставить("Видимость", Строка.Видимость);
Параметры.Вставить("ЗначениеЗаполнения", Строка.ЗначениеЗаполнения);
ПараметрыРеквизитов.Вставить(Строка.ИмяРеквизита, Параметры);
КонецЦикла;
КонецПроцедуры
// Только для внутреннего использования.
Процедура ПроверитьУникальностьПредставления(Представление, СертификатСсылка, Поле, Отказ) Экспорт
Если Не ЗначениеЗаполнено(Представление) Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Ссылка", СертификатСсылка);
Запрос.УстановитьПараметр("Наименование", Представление);
Запрос.Текст =
"ВЫБРАТЬ
| ИСТИНА КАК ЗначениеИстина
|ИЗ
| Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК Сертификаты
|ГДЕ
| Сертификаты.Ссылка <> &Ссылка
| И Сертификаты.Наименование = &Наименование";
Если Не Запрос.Выполнить().Пустой() Тогда
ТекстСообщения = НСтр("ru = 'Сертификат с таким представлением уже существует.'");
ОбщегоНазначения.СообщитьПользователю(ТекстСообщения,, Поле,, Отказ);
КонецЕсли;
КонецПроцедуры
// Только для внутреннего использования.
Функция СведенияОПодписиДляЖурналаРегистрации(ДатаПодписи, СвойстваПодписи, ЭтоОшибкаПодписания = Ложь) Экспорт
Если СвойстваПодписи.Свойство("ОписаниеСертификата") Тогда
СвойстваСертификата = СвойстваПодписи.ОписаниеСертификата;
Иначе
СвойстваСертификата = Новый Структура;
СвойстваСертификата.Вставить("СерийныйНомер", Base64Значение(""));
СвойстваСертификата.Вставить("КемВыдан", "");
СвойстваСертификата.Вставить("КомуВыдан", "");
СвойстваСертификата.Вставить("ДатаНачала", '00010101');
СвойстваСертификата.Вставить("ДатаОкончания", '00010101');
Если ТипЗнч(СвойстваПодписи.Сертификат) = Тип("Строка")
И ЭтоАдресВременногоХранилища(СвойстваПодписи.Сертификат) Тогда
Сертификат = ПолучитьИзВременногоХранилища(СвойстваПодписи.Сертификат);
Иначе
Сертификат = СвойстваПодписи.Сертификат;
КонецЕсли;
Если ТипЗнч(Сертификат) = Тип("ДвоичныеДанные") Тогда
СертификатКриптографии = Новый СертификатКриптографии(Сертификат);
СвойстваСертификата = ЭлектроннаяПодпись.СвойстваСертификата(СертификатКриптографии);
ИначеЕсли СвойстваПодписи.Свойство("КомуВыданСертификат") Тогда
СвойстваСертификата.КомуВыдан = СвойстваПодписи.КомуВыданСертификат;
КонецЕсли;
КонецЕсли;
Если ЭтоОшибкаПодписания Тогда
СведенияОПодписи = "";
Иначе
СведенияОПодписи = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Дата подписи: %1'"), Формат(ДатаПодписи, "ДЛФ=DT")) + Символы.ПС;
КонецЕсли;
СведенияОПодписи = СведенияОПодписи + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Сертификат: %1
|Кем выдан: %2
|Владелец: %3
|Действителен: с %4 по %5'"),
Строка(СвойстваСертификата.СерийныйНомер),
СвойстваСертификата.КемВыдан,
СвойстваСертификата.КомуВыдан,
Формат(СвойстваСертификата.ДатаНачала, "ДЛФ=D"),
Формат(СвойстваСертификата.ДатаОкончания, "ДЛФ=D"));
Возврат СведенияОПодписи;
КонецФункции
// Только для внутреннего использования.
Процедура ЗарегистрироватьПодписаниеДанныхВЖурнале(ЭлементДанных, ОписаниеОшибки = "") Экспорт
ЭтоОшибкаПодписания = ЗначениеЗаполнено(ОписаниеОшибки);
Если ТипЗнч(ЭлементДанных.СвойстваПодписи) = Тип("Строка") Тогда
СвойстваПодписи = ПолучитьИзВременногоХранилища(ЭлементДанных.СвойстваПодписи);
Иначе
СвойстваПодписи = ЭлементДанных.СвойстваПодписи;
КонецЕсли;
СообщениеЖурналаРегистрации = СведенияОПодписиДляЖурналаРегистрации(
СвойстваПодписи.ДатаПодписи, СвойстваПодписи, ЭтоОшибкаПодписания);
Если ЭтоОшибкаПодписания Тогда
ИмяСобытия = НСтр("ru = 'Электронная подпись.Ошибка подписания данных'",
ОбщегоНазначения.КодОсновногоЯзыка());
СообщениеЖурналаРегистрации = СообщениеЖурналаРегистрации + "
|
|" + ОписаниеОшибки;
Иначе
ИмяСобытия = НСтр("ru = 'Электронная подпись.Подписание данных'",
ОбщегоНазначения.КодОсновногоЯзыка());
КонецЕсли;
Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(ЭлементДанных.ПредставлениеДанных)) Тогда
МетаданныеЭлементаДанных = ЭлементДанных.ПредставлениеДанных.Метаданные();
Иначе
МетаданныеЭлементаДанных = Неопределено;
КонецЕсли;
ЗаписьЖурналаРегистрации(ИмяСобытия,
УровеньЖурналаРегистрации.Информация,
МетаданныеЭлементаДанных,
ЭлементДанных.ПредставлениеДанных,
СообщениеЖурналаРегистрации);
КонецПроцедуры
// Только для внутреннего использования.
Процедура ОбновитьСписокСертификатов(Сертификаты, СвойстваСертификатовНаКлиенте, КромеУжеДобавленных,
Личные, Ошибка, БезОтбора, ОтборПоОрганизации = Неопределено) Экспорт
ТаблицаСвойствСертификатов = Новый ТаблицаЗначений;
ТаблицаСвойствСертификатов.Колонки.Добавить("Отпечаток", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(255)));
ТаблицаСвойствСертификатов.Колонки.Добавить("КемВыдан");
ТаблицаСвойствСертификатов.Колонки.Добавить("Представление");
ТаблицаСвойствСертификатов.Колонки.Добавить("НаКлиенте", Новый ОписаниеТипов("Булево"));
ТаблицаСвойствСертификатов.Колонки.Добавить("НаСервере", Новый ОписаниеТипов("Булево"));
ТаблицаСвойствСертификатов.Колонки.Добавить("ЭтоЗаявление", Новый ОписаниеТипов("Булево"));
ТаблицаСвойствСертификатов.Колонки.Добавить("ВОблачномСервисе", Новый ОписаниеТипов("Булево"));
Для Каждого СвойстваСертификата Из СвойстваСертификатовНаКлиенте Цикл
НоваяСтрока = ТаблицаСвойствСертификатов.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СвойстваСертификата);
НоваяСтрока.НаКлиенте = Истина;
КонецЦикла;
ТаблицаСвойствСертификатов.Индексы.Добавить("Отпечаток");
Если ЭлектроннаяПодпись.СоздаватьЭлектронныеПодписиНаСервере() Тогда
МенеджерКриптографии = МенеджерКриптографии("ПолучениеСертификатов", Ложь, Ошибка);
Если МенеджерКриптографии <> Неопределено Тогда
МассивСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(
ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты).ПолучитьВсе();
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьСвойстваСертификатов(ТаблицаСвойствСертификатов,
МассивСертификатов, БезОтбора, ДобавкаВремени(), ТекущаяДатаСеанса());
Если Не Личные Тогда
МассивСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(
ТипХранилищаСертификатовКриптографии.СертификатыПолучателей).ПолучитьВсе();
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьСвойстваСертификатов(ТаблицаСвойствСертификатов,
МассивСертификатов, БезОтбора, ДобавкаВремени(), ТекущаяДатаСеанса());
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда
МодульХранилищеСертификатов = ОбщегоНазначения.ОбщийМодуль("ХранилищеСертификатов");
МассивСертификатов = МодульХранилищеСертификатов.Получить("ПерсональныеСертификаты");
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьСвойстваСертификатов(ТаблицаСвойствСертификатов,
МассивСертификатов, БезОтбора, ДобавкаВремени(), ТекущаяДатаСеанса(), , Истина);
Если Не Личные Тогда
МассивСертификатов = МодульХранилищеСертификатов.Получить("СертификатыПолучателей");
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьСвойстваСертификатов(ТаблицаСвойствСертификатов,
МассивСертификатов, БезОтбора, ДобавкаВремени(), ТекущаяДатаСеанса(), , Истина);
КонецЕсли;
КонецЕсли;
ОбработатьДобавленныеСертификаты(ТаблицаСвойствСертификатов, Не БезОтбора И КромеУжеДобавленных, ОтборПоОрганизации);
ТаблицаСвойствСертификатов.Индексы.Добавить("Представление");
ТаблицаСвойствСертификатов.Сортировать("Представление Возр");
ОбработанныеСтроки = Новый Соответствие;
Индекс = 0;
Отбор = Новый Структура("Отпечаток", "");
Для каждого СвойстваСертификата Из ТаблицаСвойствСертификатов Цикл
Отбор.Отпечаток = СвойстваСертификата.Отпечаток;
Строки = Сертификаты.НайтиСтроки(Отбор);
Если Строки.Количество() = 0 Тогда
Если Сертификаты.Количество()-1 < Индекс Тогда
Строка = Сертификаты.Добавить();
Иначе
Строка = Сертификаты.Вставить(Индекс);
КонецЕсли;
Иначе
Строка = Строки[0];
ИндексСтроки = Сертификаты.Индекс(Строка);
Если ИндексСтроки <> Индекс Тогда
Сертификаты.Сдвинуть(ИндексСтроки, Индекс - ИндексСтроки);
КонецЕсли;
КонецЕсли;
// Обновление только измененных значений, чтобы таблица формы не обновлялась лишний раз.
ОбновитьЗначение(Строка.Отпечаток, СвойстваСертификата.Отпечаток);
ОбновитьЗначение(Строка.Представление, СвойстваСертификата.Представление);
ОбновитьЗначение(Строка.КемВыдан, СвойстваСертификата.КемВыдан);
ОбновитьЗначение(Строка.НаКлиенте, СвойстваСертификата.НаКлиенте);
ОбновитьЗначение(Строка.НаСервере, СвойстваСертификата.НаСервере);
ОбновитьЗначение(Строка.ЭтоЗаявление, СвойстваСертификата.ЭтоЗаявление);
ОбновитьЗначение(Строка.ВОблачномСервисе, СвойстваСертификата.ВОблачномСервисе);
ОбработанныеСтроки.Вставить(Строка, Истина);
Индекс = Индекс + 1;
КонецЦикла;
Индекс = Сертификаты.Количество()-1;
Пока Индекс >=0 Цикл
Строка = Сертификаты.Получить(Индекс);
Если ОбработанныеСтроки.Получить(Строка) = Неопределено Тогда
Сертификаты.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс-1;
КонецЦикла;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Общие процедуры и функции управляемых форм.
// Только для внутреннего использования.
Процедура НастроитьФормуПодписанияШифрованияРасшифровки(Форма, Шифрование = Ложь, Расшифровка = Ложь) Экспорт
Элементы = Форма.Элементы;
Параметры = Форма.Параметры;
Элементы.Сертификат.КнопкаВыпадающегоСписка = Истина;
Элементы.Сертификат.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.ОтображатьВВыпадающемСписке;
Форма.Заголовок = Параметры.Операция;
Форма.ВыполнятьНаСервере = Параметры.ВыполнятьНаСервере;
Если Шифрование Тогда
Если Форма.УказанНеизменяемыйНаборСертификатов Тогда
Форма.БезПодтверждения = Параметры.БезПодтверждения;
КонецЕсли;
Иначе
Форма.ОтборСертификатов = Новый СписокЗначений;
Если ТипЗнч(Параметры.ОтборСертификатов) = Тип("Массив") Тогда
Форма.ОтборСертификатов.ЗагрузитьЗначения(Параметры.ОтборСертификатов);
ИначеЕсли ТипЗнч(Параметры.ОтборСертификатов) = Тип("Структура") Тогда
Форма.ОтборСертификатов = Параметры.ОтборСертификатов.Организация;
КонецЕсли;
Форма.БезПодтверждения = Параметры.БезПодтверждения;
КонецЕсли;
Если ЗначениеЗаполнено(Параметры.ЗаголовокДанных) Тогда
Элементы.ПредставлениеДанных.Заголовок = Параметры.ЗаголовокДанных;
Иначе
Элементы.ПредставлениеДанных.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
КонецЕсли;
Форма.ПредставлениеДанных = Параметры.ПредставлениеДанных;
Элементы.ПредставлениеДанных.Гиперссылка = Параметры.ПредставлениеДанныхОткрывается;
Если Не ЗначениеЗаполнено(Форма.ПредставлениеДанных) Тогда
Элементы.ПредставлениеДанных.Видимость = Ложь;
КонецЕсли;
Если Расшифровка Тогда
ЗаполнитьОтборОтпечатков(Форма);
ИначеЕсли Не Шифрование Тогда // Подписание
Элементы.Комментарий.Видимость = Параметры.ПоказатьКомментарий И Не Форма.БезПодтверждения;
КонецЕсли;
ЗаполнитьСуществующиеСертификатыПользователя(Форма.СертификатСписокВыбора,
Параметры.ОтпечаткиСертификатовНаКлиенте, Форма.ОтборСертификатов, Форма.ОтборОтпечатков);
Сертификат = Неопределено;
Если Расшифровка Тогда
Для каждого ЭлементСписка Из Форма.СертификатСписокВыбора Цикл
Если ТипЗнч(ЭлементСписка.Значение) = Тип("Строка") Тогда
Продолжить;
КонецЕсли;
Сертификат = ЭлементСписка.Значение;
Прервать;
КонецЦикла;
ИначеЕсли ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
Если Шифрование Тогда
Сертификат = ХранилищеОбщихНастроек.Загрузить("Криптография", "СертификатДляШифрования");
Иначе
Сертификат = ХранилищеОбщихНастроек.Загрузить("Криптография", "СертификатДляПодписания");
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Форма.ОтборСертификатов) = Тип("СписокЗначений") Тогда
Если Форма.СертификатСписокВыбора.Количество() = 0 Тогда
Сертификат = Неопределено;
Иначе
Сертификат = Форма.СертификатСписокВыбора[0].Значение;
КонецЕсли;
КонецЕсли;
Если Не (Шифрование И Форма.УказанНеизменяемыйНаборСертификатов) Тогда
Форма.Сертификат = Сертификат;
КонецЕсли;
Если ЗначениеЗаполнено(Форма.Сертификат)
И ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Форма.Сертификат, "Ссылка") <> Форма.Сертификат Тогда
Форма.Сертификат = Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(Форма.Сертификат) Тогда
Если Шифрование Тогда
Форма.ИмяПоляАктивизироватьПоУмолчанию = "СертификатыШифрования";
Иначе
Форма.ИмяПоляАктивизироватьПоУмолчанию = "Пароль";
КонецЕсли;
Иначе
Если Не (Шифрование И Форма.УказанНеизменяемыйНаборСертификатов) Тогда
Форма.ИмяПоляАктивизироватьПоУмолчанию = "Сертификат";
КонецЕсли;
КонецЕсли;
ЗаполнитьДополнительныеСвойстваСертификата(Форма);
Форма.МенеджерКриптографииНаСервереОписаниеОшибки = Новый Структура;
Если ЭлектроннаяПодпись.СоздаватьЭлектронныеПодписиНаСервере() Тогда
МенеджерКриптографии("ПолучениеСертификатов",
Ложь, Форма.МенеджерКриптографииНаСервереОписаниеОшибки);
КонецЕсли;
Если Не Шифрование Тогда
ЭлектроннаяПодписьПереопределяемый.ПередНачаломОперации(?(Расшифровка, "Расшифровка", "Подписание"),
Параметры.ПараметрыДополнительныхДействий, Форма.ВыходныеПараметрыДополнительныхДействий);
КонецЕсли;
КонецПроцедуры
// Только для внутреннего использования.
Процедура СертификатПриИзмененииНаСервере(Форма, ОтпечаткиСертификатовНаКлиенте, Шифрование = Ложь, Расшифровка = Ложь) Экспорт
Если ТипЗнч(Форма.ОтборСертификатов) <> Тип("СписокЗначений") И ПравоДоступа("СохранениеДанныхПользователя", Метаданные) Тогда
Если Шифрование Тогда
ХранилищеОбщихНастроек.Сохранить("Криптография", "СертификатДляШифрования", Форма.Сертификат);
ИначеЕсли Не Расшифровка Тогда
ХранилищеОбщихНастроек.Сохранить("Криптография", "СертификатДляПодписания", Форма.Сертификат);
КонецЕсли;
КонецЕсли;
ЗаполнитьСуществующиеСертификатыПользователя(Форма.СертификатСписокВыбора,
ОтпечаткиСертификатовНаКлиенте, Форма.ОтборСертификатов, Форма.ОтборОтпечатков);
ЗаполнитьДополнительныеСвойстваСертификата(Форма);
КонецПроцедуры
// Только для внутреннего использования.
Функция СохраненныеСвойстваСертификата(Отпечаток, Адрес, ПараметрыРеквизитов, ДляШифрования = Ложь) Экспорт
СохраненныеСвойства = Новый Структура;
СохраненныеСвойства.Вставить("Ссылка");
СохраненныеСвойства.Вставить("Наименование");
СохраненныеСвойства.Вставить("Пользователь");
СохраненныеСвойства.Вставить("Организация");
СохраненныеСвойства.Вставить("УсиленнаяЗащитаЗакрытогоКлюча");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Отпечаток", Отпечаток);
Запрос.Текст =
"ВЫБРАТЬ
| Сертификаты.Ссылка КАК Ссылка,
| Сертификаты.Наименование КАК Наименование,
| Сертификаты.Пользователь,
| Сертификаты.Организация,
| Сертификаты.УсиленнаяЗащитаЗакрытогоКлюча,
| Сертификаты.ДанныеСертификата
|ИЗ
| Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК Сертификаты
|ГДЕ
| Сертификаты.Отпечаток = &Отпечаток";
СертификатКриптографии = Новый СертификатКриптографии(ПолучитьИзВременногоХранилища(Адрес));
ЗначенияЗаполнения = ПараметрыРеквизитов;
ПараметрыРеквизитов = Неопределено; // Заполняется в процедуре ПередНачаломРедактированияСертификатаКлюча.
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЗаполнитьЗначенияСвойств(СохраненныеСвойства, Выборка);
Иначе
СохраненныеСвойства.Ссылка = Справочники.СертификатыКлючейЭлектроннойПодписиИШифрования.ПустаяСсылка();
Если ТипЗнч(ЗначенияЗаполнения) = Тип("Структура")
И ЗначенияЗаполнения.Свойство("Организация")
И ЗначениеЗаполнено(ЗначенияЗаполнения.Организация) Тогда
СохраненныеСвойства.Организация = ЗначенияЗаполнения.Организация;
ИначеЕсли Не Метаданные.ОпределяемыеТипы.Организация.Тип.СодержитТип(Тип("Строка")) Тогда
ПолноеИмя = Метаданные.НайтиПоТипу(Метаданные.ОпределяемыеТипы.Организация.Тип.Типы()[0]).ПолноеИмя();
ИмяСправочникаОрганизации = "Справочники." + СтрРазделить(ПолноеИмя, ".")[1];
МодульОрганизации = ОбщегоНазначения.ОбщийМодуль(ИмяСправочникаОрганизации);
Если Не ДляШифрования Тогда
СохраненныеСвойства.Организация = МодульОрганизации.ОрганизацияПоУмолчанию();
КонецЕсли;
КонецЕсли;
СохраненныеСвойства.Наименование = ЭлектроннаяПодпись.ПредставлениеСертификата(СертификатКриптографии);
Если Не ДляШифрования Тогда
СохраненныеСвойства.Пользователь = Пользователи.ТекущийПользователь();
КонецЕсли;
КонецЕсли;
ПередНачаломРедактированияСертификатаКлюча(
СохраненныеСвойства.Ссылка, СертификатКриптографии, ПараметрыРеквизитов);
Если Не ЗначениеЗаполнено(СохраненныеСвойства.Ссылка) Тогда
ЗаполнитьРеквизит(СохраненныеСвойства, ПараметрыРеквизитов, "Наименование");
ЗаполнитьРеквизит(СохраненныеСвойства, ПараметрыРеквизитов, "Пользователь");
ЗаполнитьРеквизит(СохраненныеСвойства, ПараметрыРеквизитов, "Организация");
ЗаполнитьРеквизит(СохраненныеСвойства, ПараметрыРеквизитов, "УсиленнаяЗащитаЗакрытогоКлюча");
КонецЕсли;
Если Не ЗначениеЗаполнено(СохраненныеСвойства.Ссылка)
И ТипЗнч(ЗначенияЗаполнения) = Тип("Структура")
И ЗначенияЗаполнения.Свойство("Организация")
И ЗначениеЗаполнено(ЗначенияЗаполнения.Организация)
И Не ПараметрыРеквизитов.Свойство("Организация") Тогда
Параметры = Новый Структура;
Параметры.Вставить("ТолькоПросмотр", Истина);
Параметры.Вставить("ПроверкаЗаполнения", Ложь);
Параметры.Вставить("Видимость", Истина);
ПараметрыРеквизитов.Вставить("Организация", Параметры);
КонецЕсли;
Возврат СохраненныеСвойства;
КонецФункции
// Только для внутреннего использования.
Процедура ЗаписатьСертификатВСправочник(Форма, Программа = Неопределено, ДляШифрования = Ложь) Экспорт
ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("Наименование", Форма.СертификатНаименование);
ДополнительныеПараметры.Вставить("Пользователь", Форма.СертификатПользователь);
ДополнительныеПараметры.Вставить("Организация", Форма.СертификатОрганизация);
Если Не ДляШифрования Тогда
ДополнительныеПараметры.Вставить("Программа", Программа);
ДополнительныеПараметры.Вставить("УсиленнаяЗащитаЗакрытогоКлюча",
Форма.СертификатУсиленнаяЗащитаЗакрытогоКлюча);
КонецЕсли;
Если Не ЗначениеЗаполнено(Форма.Сертификат) Тогда
ПропускаемыеРеквизиты = Новый Соответствие;
ПропускаемыеРеквизиты.Вставить("Ссылка", Истина);
ПропускаемыеРеквизиты.Вставить("Наименование", Истина);
ПропускаемыеРеквизиты.Вставить("Организация", Истина);
ПропускаемыеРеквизиты.Вставить("УсиленнаяЗащитаЗакрытогоКлюча", Истина);
Если Не ДляШифрования И Форма.ЛичныйСписокПриДобавлении Тогда
ПропускаемыеРеквизиты.Вставить("Пользователь", Истина);
КонецЕсли;
Для каждого КлючИЗначение Из Форма.СертификатПараметрыРеквизитов Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
Свойства = КлючИЗначение.Значение;
Если ПропускаемыеРеквизиты.Получить(ИмяРеквизита) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Если Свойства.ЗначениеЗаполнения = Неопределено Тогда
Продолжить;
КонецЕсли;
ДополнительныеПараметры.Вставить(ИмяРеквизита, Свойства.ЗначениеЗаполнения);
КонецЦикла;
КонецЕсли;
Форма.Сертификат = ЭлектроннаяПодпись.ЗаписатьСертификатВСправочник(Форма.СертификатАдрес,
ДополнительныеПараметры);
КонецПроцедуры
// Только для внутреннего использования.
Процедура УстановитьУсловноеОформлениеСпискаСертификатов(Список, ИсключитьЗаявления = Ложь) Экспорт
ЭлементУсловногоОформления = Список.УсловноеОформление.Элементы.Добавить();
ЭлементЦветаОформления = ЭлементУсловногоОформления.Оформление.Элементы.Найти("TextColor");
ЭлементЦветаОформления.Значение = Метаданные.ЭлементыСтиля.ТекстЗапрещеннойЯчейкиЦвет.Значение;
ЭлементЦветаОформления.Использование = Истина;
Если ИсключитьЗаявления И Метаданные.Обработки.Найти("ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата") <> Неопределено Тогда
ОбработкаЗаявлениеНаВыпускНовогоКвалифицированногоСертификата =
ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(
"Обработка.ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата");
ОбработкаЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.УстановитьУсловноеОформлениеСпискаСертификатов(
ЭлементУсловногоОформления);
КонецЕсли;
ГруппаЭлементовОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаЭлементовОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаНе;
ЭлементОтбораДанных = ГруппаЭлементовОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораДанных.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Отозван");
ЭлементОтбораДанных.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораДанных.ПравоеЗначение = Ложь;
ЭлементОтбораДанных.Использование = Истина;
ЭлементОтбораДанных = ГруппаЭлементовОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораДанных.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДействителенДо");
ЭлементОтбораДанных.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
ЭлементОтбораДанных.ПравоеЗначение = Новый СтандартнаяДатаНачала(ВариантСтандартнойДатыНачала.НачалоЭтогоДня);
ЭлементОтбораДанных.Использование = Истина;
ЭлементОформляемогоПоля = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ЭлементОформляемогоПоля.Поле = Новый ПолеКомпоновкиДанных("");
ЭлементОформляемогоПоля.Использование = Истина;
КонецПроцедуры
// Только для внутреннего использования.
Функция СертификатИзДвоичныхДанных(ДанныеСертификата) Экспорт
Если ТипЗнч(ДанныеСертификата) <> Тип("ДвоичныеДанные") Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
СертификатКриптографии = Новый СертификатКриптографии(ДанныеСертификата);
Исключение
СертификатКриптографии = Неопределено;
КонецПопытки;
Если СертификатКриптографии <> Неопределено Тогда
Возврат СертификатКриптографии;
КонецЕсли;
ПолноеИмяВременногоФайла = ПолучитьИмяВременногоФайла("cer");
ДанныеСертификата.Записать(ПолноеИмяВременногоФайла);
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ПолноеИмяВременногоФайла);
Попытка
УдалитьФайлы(ПолноеИмяВременногоФайла);
Исключение
ЗаписьЖурналаРегистрации(
НСтр("ru = 'Электронная подпись.Удаление временного файла'",
ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Если Текст.КоличествоСтрок() < 3
Или Текст.ПолучитьСтроку(1) <> "-----BEGIN CERTIFICATE-----"
Или Текст.ПолучитьСтроку(Текст.КоличествоСтрок()) <> "-----END CERTIFICATE-----" Тогда
Возврат Неопределено;
КонецЕсли;
Текст.УдалитьСтроку(1);
Текст.УдалитьСтроку(Текст.КоличествоСтрок());
СтрокаBase64 = Текст.ПолучитьТекст();
Попытка
ДанныеСертификата = Base64Значение(СтрокаBase64);
Исключение
Возврат Неопределено;
КонецПопытки;
Если ТипЗнч(ДанныеСертификата) <> Тип("ДвоичныеДанные") Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
СертификатКриптографии = Новый СертификатКриптографии(ДанныеСертификата);
Исключение
СертификатКриптографии = Неопределено;
КонецПопытки;
Возврат СертификатКриптографии;
КонецФункции
// Только для внутреннего использования.
Процедура НастроитьПояснениеВводаПароля(Форма, ИмяЭлементаУсиленнаяЗащитаЗакрытогоКлюча = "", ИмяЭлементаПояснениеУсиленногоПароля = "") Экспорт
Если Не ЭлектроннаяПодписьСлужебныйКлиентСервер.ИнтерактивныйРежимДоступен() Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(ИмяЭлементаУсиленнаяЗащитаЗакрытогоКлюча) Тогда
Элемент = Форма.Элементы[ИмяЭлементаУсиленнаяЗащитаЗакрытогоКлюча];
Элемент.Заголовок = НСтр("ru = 'Ввод и сохранение пароля в программе'");
Элемент.Подсказка =
НСтр("ru = '- Включается интерактивный режим работы программы электронной подписи,
| при котором она запрашивает пароль и позволяет его сохранить.
|- Отключается запрос пароля в форме 1С:Предприятия.
|
|Обязательно для закрытых ключей сертификатов, для которых в ОС включена усиленная защита.'");
КонецЕсли;
Если ЗначениеЗаполнено(ИмяЭлементаПояснениеУсиленногоПароля) Тогда
Элемент = Форма.Элементы[ИмяЭлементаПояснениеУсиленногоПароля];
Элемент.Подсказка =
НСтр("ru = 'Пароль запрашивает программа электронной подписи, а не программа 1С:Предприятие,
|так как для выбранного сертификата включен режим ""Ввод и сохранение пароля в программе"".'");
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.
// Обработчик конвертации данных при переходе на поддержку использования
// нескольких программ электронной подписи и шифрования в одной ИБ.
//
Процедура ПеренестиНастройкиМенеджераКриптографии() Экспорт
ПрограммаОбъект = СтараяПрограмма();
Программа = Неопределено;
НачатьТранзакцию();
Попытка
Если ПрограммаОбъект <> Неопределено Тогда
Если Не ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
ОбновлениеИнформационнойБазы.ЗаписатьДанные(ПрограммаОбъект);
КонецЕсли;
Программа = ПрограммаОбъект.Ссылка;
КонецЕсли;
Если Константы.ИспользоватьЭлектронныеПодписи.Получить()
И Не Константы.ИспользоватьШифрование.Получить() Тогда
МенеджерЗначения = Константы.ИспользоватьШифрование.СоздатьМенеджерЗначения();
МенеджерЗначения.Значение = Истина;
ОбновлениеИнформационнойБазы.ЗаписатьДанные(МенеджерЗначения);
КонецЕсли;
ОчиститьКонстанту(Константы.УдалитьПровайдерЭП);
ОчиститьКонстанту(Константы.УдалитьТипПровайдераЭП);
ОчиститьКонстанту(Константы.УдалитьАлгоритмПодписи);
ОчиститьКонстанту(Константы.УдалитьАлгоритмХеширования);
ОчиститьКонстанту(Константы.УдалитьАлгоритмШифрования);
ОбработатьПутиНаСерверахLinux(Программа);
ОбработатьПутиНаКлиентахLinux(Программа);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Работа с XMLDSig
// Подписывает сообщение, подставляя в шаблон SOAP данные подписи.
//
// Параметры:
// КонвертSOAP - Строка - шаблон формируемого сообщения в формате SOAP
// ДанныеАлгоритмаПодписания - Структура:
// XPathПодписываемыйТег - Строка - запрос для получения тега подписи.
// XPathSignedInfo - Строка - запрос для получения тега подписываемой информации.
// OIDАлгоритмаХеширования - Строка - идентификатор алгоритма хеширования.
// ИмяАлгоритмаПодписи - Строка - имя алгоритма подписи.
// АлгоритмХеширования - Строка - алгоритм хеширования в конверте SOAP.
// АлгоритмПодписи - Строка - алгоритм подписи в конверте SOAP.
// СертификатКриптографии - СертификатКриптографии - используемый сертификат криптографии.
// МенеджерКриптографии - МенеджерКриптографии - используемый менеджер криптографии.
//
// Возвращаемое значение:
// Строка - шаблон SOAP, со вставленными данными подписи.
//
Функция Подписать(Знач КонвертSOAP, ДанныеАлгоритмаПодписания, СертификатКриптографии, МенеджерКриптографии) Экспорт
XPathПодписываемыйТег = ДанныеАлгоритмаПодписания.XPathПодписываемыйТег;
XPathSignedInfo = ДанныеАлгоритмаПодписания.XPathSignedInfo;
Пароль = МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу;
ОбъектКомпоненты = ОбъектВнешнейКомпонентыXMLDSig();
СвойстваКриптопровайдера = СвойстваКриптопровайдера(МенеджерКриптографии);
ОбъектКомпоненты.ПутьККриптопровайдеру = СвойстваКриптопровайдера.Путь;
КонвертSOAP = СтрЗаменить(
КонвертSOAP,
"%BinarySecurityToken%",
СертификатКриптографииBase64(СертификатКриптографии.Выгрузить()));
ПроверитьВыбратьАлгоритмПодписи(ОбъектКомпоненты,
СертификатКриптографииBase64(СертификатКриптографии.Выгрузить()),
ДанныеАлгоритмаПодписания);
DigestValue = Hash(
ОбъектКомпоненты,
C14N(ОбъектКомпоненты, КонвертSOAP, XPathПодписываемыйТег),
ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования,
СвойстваКриптопровайдера.Тип);
КонвертSOAP = СтрЗаменить(КонвертSOAP, "%DigestValue%", DigestValue);
КонвертSOAP = СтрЗаменить(КонвертSOAP, "%SignatureMethod%", ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмПодписи);
КонвертSOAP = СтрЗаменить(КонвертSOAP, "%DigestMethod%", ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмХеширования);
SignatureValue = Sign(
ОбъектКомпоненты,
C14N(ОбъектКомпоненты, КонвертSOAP, XPathSignedInfo),
СертификатКриптографии,
Пароль);
КонвертSOAP = СтрЗаменить(КонвертSOAP, "%SignatureValue%", SignatureValue);
Возврат КонвертSOAP;
КонецФункции
// В параметре возвращается сертификат, с помощью которого была произведена подпись (если сертификат включен в данные подписи).
// Если проверка подписи завершилась неудачно, генерируется исключительная ситуация.
Функция ПроверитьПодпись(Знач КонвертSOAP, ДанныеАлгоритмаПодписания, МенеджерКриптографии) Экспорт
XPathПодписываемыйТег = ДанныеАлгоритмаПодписания.XPathПодписываемыйТег;
XPathSignedInfo = ДанныеАлгоритмаПодписания.XPathSignedInfo;
ОбъектКомпоненты = ОбъектВнешнейКомпонентыXMLDSig();
СвойстваКриптопровайдера = СвойстваКриптопровайдера(МенеджерКриптографии);
ОбъектКомпоненты.ПутьККриптопровайдеру = СвойстваКриптопровайдера.Путь;
СертификатКриптографииBase64 = ЭлектроннаяПодписьСлужебныйКлиентСервер.НайтиВXML(КонвертSOAP, "wsse:BinarySecurityToken");
ПроверитьВыбратьАлгоритмПодписи(ОбъектКомпоненты, СертификатКриптографииBase64, ДанныеАлгоритмаПодписания);
ПодписьВерна = VerifySign(
ОбъектКомпоненты,
C14N(ОбъектКомпоненты, КонвертSOAP, XPathSignedInfo),
ЭлектроннаяПодписьСлужебныйКлиентСервер.НайтиВXML(КонвертSOAP, "SignatureValue"),
СертификатКриптографииBase64,
СвойстваКриптопровайдера.Тип);
DigestValue = Hash(
ОбъектКомпоненты,
C14N(ОбъектКомпоненты, КонвертSOAP, XPathПодписываемыйТег),
ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования,
СвойстваКриптопровайдера.Тип);
ХешСовпадает = Ложь;
Если DigestValue = ЭлектроннаяПодписьСлужебныйКлиентСервер.НайтиВXML(КонвертSOAP, "DigestValue") Тогда
ХешСовпадает = Истина;
КонецЕсли;
Если ХешСовпадает И ПодписьВерна Тогда
ДвоичныеДанные = Base64Значение(СертификатКриптографииBase64);
ДатаПодписания = ЭлектроннаяПодпись.ДатаПодписания(ДвоичныеДанные);
Если Не ЗначениеЗаполнено(ДатаПодписания) Тогда
ДатаПодписания = Неопределено;
КонецЕсли;
ВозвращаемоеЗначение = Новый Структура;
ВозвращаемоеЗначение.Вставить("Сертификат", Новый СертификатКриптографии(ДвоичныеДанные));
ВозвращаемоеЗначение.Вставить("ДатаПодписания", ДатаПодписания);
Возврат ВозвращаемоеЗначение;
Иначе
Если ПодписьВерна Тогда
ВызватьИсключение НСтр("ru = 'Подпись не верна (SignatureValue корректно, отличается DigestValue).'")
Иначе
ВызватьИсключение НСтр("ru = 'Подпись не верна (SignatureValue некорректно.'");
КонецЕсли;
КонецЕсли;
КонецФункции
Функция ОбъектВнешнейКомпонентыXMLDSig()
ОбъектКомпоненты = ОбщегоНазначения.ПодключитьКомпонентуИзМакета("XMLDSignAddIn",
"Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Макет.КомпонентаXMLDSig");
Если ОбъектКомпоненты = Неопределено Тогда
ВызватьИсключение НСтр("ru='Не удалось подключить внешнюю компоненту XMLDSig.'");
КонецЕсли;
Возврат ОбъектКомпоненты;
КонецФункции
Функция СвойстваКриптопровайдера(МенеджерКриптографии)
ИнформацияМодуляКриптографии = МенеджерКриптографии.ПолучитьИнформациюМодуляКриптографии();
ИмяКриптопровайдера = ИнформацияМодуляКриптографии.Имя;
ОписаниеПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.ОписаниеПрограммыПоИмениКриптопровайдера(ИмяКриптопровайдера,
ЭлектроннаяПодпись.ОбщиеНастройки().ОписанияПрограмм);
Если ОписаниеПрограммы = Неопределено Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не удалось определить тип криптопровайдера %1'"), ИмяКриптопровайдера);
КонецЕсли;
Свойства = Новый Структура("Тип, Путь", ОписаниеПрограммы.ТипПрограммы, "");
Если ОбщегоНазначения.ЭтоLinuxСервер() Тогда
ПутиКПрограммамНаСерверахLinux = ПутиКПрограммамНаСерверахLinux(ИмяКомпьютера());
Свойства.Путь = ПутиКПрограммамНаСерверахLinux.Получить(ОписаниеПрограммы.Ссылка);
Иначе
Свойства.Путь = "";
КонецЕсли;
Возврат Свойства;
КонецФункции
Функция GetSignOIDFromCert(ОбъектКомпоненты, СертификатКриптографииBase64)
Попытка
OIDАлгоритмаПодписи = ОбъектКомпоненты.GetSignOIDFromCert(СертификатКриптографииBase64);
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода GetSignOIDFromCert компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если OIDАлгоритмаПодписи = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода GetSignOIDFromCert компоненты XMLDSig.'") + Символы.ПС + ОбъектКомпоненты.GetLastError();
КонецЕсли;
Возврат OIDАлгоритмаПодписи;
КонецФункции
Функция C14N(ОбъектКомпоненты, КонвертSOAP, XPath)
Попытка
КаноникализированныйТекстXML = ОбъектКомпоненты.C14N(
КонвертSOAP,
XPath);
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода C14N компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если КаноникализированныйТекстXML = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода C14N компоненты XMLDSig.'") + Символы.ПС + ОбъектКомпоненты.GetLastError();
КонецЕсли;
Возврат КаноникализированныйТекстXML;
КонецФункции
Функция Hash(ОбъектКомпоненты, КаноникализированныйТекстXML, OIDАлгоритмаХеширования, ТипКриптопровайдера)
Попытка
DigestValue = ОбъектКомпоненты.Hash(
КаноникализированныйТекстXML,
OIDАлгоритмаХеширования,
ТипКриптопровайдера);
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода Hash компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если DigestValue = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода Hash компоненты XMLDSig.'") + Символы.ПС + ОбъектКомпоненты.GetLastError();
КонецЕсли;
Возврат DigestValue;
КонецФункции
Функция Sign(ОбъектКомпоненты, КаноникализированныйТекстXMLSignedInfo, СертификатКриптографии, ПарольДоступаКЗакрытомуКлючу)
Попытка
SignatureValue = ОбъектКомпоненты.Sign(
КаноникализированныйТекстXMLSignedInfo,
СертификатКриптографииBase64(СертификатКриптографии.Выгрузить()),
ПарольДоступаКЗакрытомуКлючу);
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода Sign компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если SignatureValue = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода Sign компоненты XMLDSig.'") + Символы.ПС + ОбъектКомпоненты.GetLastError();
КонецЕсли;
Возврат SignatureValue;
КонецФункции
Функция VerifySign(ОбъектКомпоненты, КаноникализированныйТекстXMLSignedInfo, SignatureValue, СертификатКриптографииBase64, ТипКриптопровайдера)
Попытка
ПодписьВерна = ОбъектКомпоненты.VerifySign(
КаноникализированныйТекстXMLSignedInfo,
SignatureValue,
СертификатКриптографииBase64,
ТипКриптопровайдера);
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода VerifySign компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
Если ПодписьВерна = Неопределено Тогда
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода VerifySign компоненты XMLDSig.'") + Символы.ПС + ОбъектКомпоненты.GetLastError();
КонецЕсли;
Возврат ПодписьВерна;
КонецФункции
Процедура ПроверитьВыбратьАлгоритмПодписи(ОбъектКомпоненты, СертификатКриптографииBase64, ДанныеАлгоритмаПодписания)
OIDАлгоритмаПодписи = GetSignOIDFromCert(ОбъектКомпоненты, СертификатКриптографииBase64);
OIDАлгоритмовПодписи = СтрРазделить(ДанныеАлгоритмаПодписания.OIDАлгоритмаПодписи, Символы.ПС);
OIDАлгоритмовХеширования = СтрРазделить(ДанныеАлгоритмаПодписания.OIDАлгоритмаХеширования, Символы.ПС);
АлгоритмыПодписи = СтрРазделить(ДанныеАлгоритмаПодписания.АлгоритмПодписи, Символы.ПС);
АлгоритмыХеширования = СтрРазделить(ДанныеАлгоритмаПодписания.АлгоритмХеширования, Символы.ПС);
ДанныеАлгоритмаПодписания.Вставить("OIDВыбранногоАлгоритмаПодписи", Неопределено);
ДанныеАлгоритмаПодписания.Вставить("OIDВыбранногоАлгоритмаХеширования", Неопределено);
ДанныеАлгоритмаПодписания.Вставить("ВыбранныйАлгоритмПодписи", Неопределено);
ДанныеАлгоритмаПодписания.Вставить("ВыбранныйАлгоритмХеширования", Неопределено);
Для Индекс = 0 По OIDАлгоритмовПодписи.Количество() - 1 Цикл
Если OIDАлгоритмаПодписи = OIDАлгоритмовПодписи[Индекс] Тогда
ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаПодписи = OIDАлгоритмовПодписи[Индекс];
ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаХеширования = OIDАлгоритмовХеширования[Индекс];
ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмПодписи = АлгоритмыПодписи[Индекс];
ДанныеАлгоритмаПодписания.ВыбранныйАлгоритмХеширования = АлгоритмыХеширования[Индекс];
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеЗаполнено(ДанныеАлгоритмаПодписания.OIDВыбранногоАлгоритмаПодписи) Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Алгоритм подписи сертификата криптографии отличается от алгоритма %1.'"),
ДанныеАлгоритмаПодписания.ИмяАлгоритмаПодписи);
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Вспомогательные процедуры и функции.
// Для процедуры обновления ПеренестиНастройкиМенеджераКриптографии.
Процедура ОчиститьКонстанту(Константа)
Если Не ЗначениеЗаполнено(Константа.Получить()) Тогда
Возврат;
КонецЕсли;
МенеджерЗначения = Константа.СоздатьМенеджерЗначения();
МенеджерЗначения.Значение = Неопределено;
ОбновлениеИнформационнойБазы.ЗаписатьДанные(МенеджерЗначения);
КонецПроцедуры
// Для процедуры обновления ПеренестиНастройкиМенеджераКриптографии.
Процедура ОбработатьПутиНаСерверахLinux(Программа)
// Обработка серверных путей
НаборЗаписей = РегистрыСведений.ПутиКПрограммамЭлектроннойПодписиИШифрованияНаСерверахLinux.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Программа.Установить(Справочники.ПрограммыЭлектроннойПодписиИШифрования.ПустаяСсылка());
НаборЗаписей.Прочитать();
Если НаборЗаписей.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если ЗначениеЗаполнено(Программа) Тогда
НаборЗаписейПрограммы = РегистрыСведений.ПутиКПрограммамЭлектроннойПодписиИШифрованияНаСерверахLinux.СоздатьНаборЗаписей();
НаборЗаписейПрограммы.Отбор.Программа.Установить(Программа);
НаборЗаписейПрограммы.Прочитать();
Таблица = НаборЗаписейПрограммы.Выгрузить(, "ИмяКомпьютера, ПутьКПрограмме");
Отбор = Новый Структура("ИмяКомпьютера, ПутьКПрограмме");
Для каждого Запись Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(Отбор, Запись);
Строки = Таблица.НайтиСтроки(Отбор);
Если Строки.Количество() = 0 Тогда
НоваяЗапись = НаборЗаписейПрограммы.Добавить();
ЗаполнитьЗначенияСвойств(НоваяЗапись, Запись);
НоваяЗапись.Программа = Программа;
КонецЕсли;
КонецЦикла;
Если НаборЗаписейПрограммы.Модифицированность() Тогда
ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборЗаписейПрограммы);
КонецЕсли;
КонецЕсли;
НаборЗаписей.Очистить();
ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборЗаписей);
КонецПроцедуры
// Для процедуры обновления ПеренестиНастройкиМенеджераКриптографии.
Процедура ОбработатьПутиНаКлиентахLinux(Программа)
// Обработка клиентских путей
ПользователиИБ = ПользователиИнформационнойБазы.ПолучитьПользователей();
КлючПодсистемы = "ЭЦП"; // Не заменять на "ЭП". Используется для обратной совместимости.
СтарыйКлючНастроек = "ПутьМодуляКриптографии";
НовыйКлючНастроек = "ПутиКПрограммамЭлектроннойПодписиИШифрования";
Для каждого ПользовательИБ Из ПользователиИБ Цикл
Путь = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(КлючПодсистемы, СтарыйКлючНастроек,,,
ПользовательИБ.Имя);
Если Не ЗначениеЗаполнено(Путь) Тогда
Продолжить;
КонецЕсли;
Настройки = Новый Соответствие;
Настройки.Вставить(Программа, Путь);
ОбщегоНазначения.ХранилищеОбщихНастроекСохранить(КлючПодсистемы, НовыйКлючНастроек, Настройки,,
ПользовательИБ.Имя)
КонецЦикла;
КонецПроцедуры
// Для процедуры обновления ПеренестиНастройкиМенеджераКриптографии.
Функция СтараяПрограмма()
ИмяПрограммы = СокрЛП(Константы.УдалитьПровайдерЭП.Получить());
ТипПрограммы = Константы.УдалитьТипПровайдераЭП.Получить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА КАК ЗначениеИстина
|ИЗ
| РегистрСведений.ПутиКПрограммамЭлектроннойПодписиИШифрованияНаСерверахLinux КАК Пути
|ГДЕ
| Пути.Программа = ЗНАЧЕНИЕ(Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.ПустаяСсылка)";
Если Не ЗначениеЗаполнено(ИмяПрограммы)
И Не ЗначениеЗаполнено(ТипПрограммы)
И Запрос.Выполнить().Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИмяПрограммы", ИмяПрограммы);
Запрос.УстановитьПараметр("ТипПрограммы", ТипПрограммы);
Запрос.Текст =
"ВЫБРАТЬ
| Программы.Ссылка КАК Ссылка
|ИЗ
| Справочник.ПрограммыЭлектроннойПодписиИШифрования КАК Программы
|ГДЕ
| Программы.ИмяПрограммы = &ИмяПрограммы
| И Программы.ТипПрограммы = &ТипПрограммы";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
ПрограммаОбъект = Справочники.ПрограммыЭлектроннойПодписиИШифрования.СоздатьЭлемент();
ПрограммаОбъект.Наименование = ИмяПрограммы;
ПрограммаОбъект.ИмяПрограммы = ИмяПрограммы;
ПрограммаОбъект.ТипПрограммы = ТипПрограммы;
Иначе
ПрограммаОбъект = РезультатЗапроса.Выгрузить()[0].Ссылка.ПолучитьОбъект();
КонецЕсли;
ПрограммаОбъект.АлгоритмПодписи = Константы.УдалитьАлгоритмПодписи.Получить();
ПрограммаОбъект.АлгоритмХеширования = Константы.УдалитьАлгоритмХеширования.Получить();
ПрограммаОбъект.АлгоритмШифрования = Константы.УдалитьАлгоритмШифрования.Получить();
Возврат ПрограммаОбъект;
КонецФункции
// Для процедуры ОбновитьСписокСертификатов.
Процедура ОбработатьДобавленныеСертификаты(ТаблицаСвойствСертификатов, КромеУжеДобавленных, ОтборПоОрганизации = Неопределено)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Отпечатки", ТаблицаСвойствСертификатов.Скопировать(, "Отпечаток"));
Запрос.Текст =
"ВЫБРАТЬ
| Отпечатки.Отпечаток
|ПОМЕСТИТЬ Отпечатки
|ИЗ
| &Отпечатки КАК Отпечатки
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Сертификаты.Отпечаток,
| Сертификаты.Наименование КАК Представление,
| ЛОЖЬ КАК ЭтоЗаявление,
| Сертификаты.Организация
|ИЗ
| Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК Сертификаты
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Отпечатки КАК Отпечатки
| ПО Сертификаты.Отпечаток = Отпечатки.Отпечаток";
Если Метаданные.Обработки.Найти("ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата") <> Неопределено Тогда
ОбработкаЗаявлениеНаВыпускНовогоКвалифицированногоСертификата =
ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(
"Обработка.ЗаявлениеНаВыпускНовогоКвалифицированногоСертификата");
ОбработкаЗаявлениеНаВыпускНовогоКвалифицированногоСертификата.ДополнитьЗапросПриДобавленииСертификатов(
Запрос.Текст);
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Строка = ТаблицаСвойствСертификатов.Найти(Выборка.Отпечаток, "Отпечаток");
Если КромеУжеДобавленных Тогда
Если Строка <> Неопределено Тогда // Защита от ошибки в данных (дубли сертификатов).
ТаблицаСвойствСертификатов.Удалить(Строка);
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(ОтборПоОрганизации) Тогда
Если Строка <> Неопределено И Выборка.Организация <> ОтборПоОрганизации Тогда // Защита от ошибки в данных (дубли сертификатов).
ТаблицаСвойствСертификатов.Удалить(Строка);
КонецЕсли;
Иначе
Строка.Представление = Выборка.Представление;
Строка.ЭтоЗаявление = Выборка.ЭтоЗаявление;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// Для процедуры ОбновитьСписокСертификатов.
Процедура ОбновитьЗначение(СтароеЗначение, НовоеЗначение, ПропускатьНеопределенныеЗначения = Ложь)
Если НовоеЗначение = Неопределено И ПропускатьНеопределенныеЗначения Тогда
Возврат;
КонецЕсли;
Если СтароеЗначение <> НовоеЗначение Тогда
СтароеЗначение = НовоеЗначение;
КонецЕсли;
КонецПроцедуры
// Для процедуры СохраненныеСвойстваСертификата.
Процедура ЗаполнитьРеквизит(СохраненныеСвойства, ПараметрыРеквизитов, ИмяРеквизита)
Если ПараметрыРеквизитов.Свойство(ИмяРеквизита)
И ПараметрыРеквизитов[ИмяРеквизита].ЗначениеЗаполнения <> Неопределено Тогда
СохраненныеСвойства[ИмяРеквизита] = ПараметрыРеквизитов[ИмяРеквизита].ЗначениеЗаполнения;
КонецЕсли;
КонецПроцедуры
// Для процедуры НастроитьФормуПодписанияШифрованияРасшифровки.
Процедура ЗаполнитьОтборОтпечатков(Форма)
Параметры = Форма.Параметры;
Отбор = Новый Соответствие;
Если ТипЗнч(Параметры.СертификатыШифрования) = Тип("Массив") Тогда
Описания = Новый Соответствие;
Отпечатки = Новый Соответствие;
ПредставленияОтпечатков = Новый Соответствие;
Для каждого Описание Из Параметры.СертификатыШифрования Цикл
Если Описания[Описание] <> Неопределено Тогда
Продолжить;
КонецЕсли;
Описания.Вставить(Описание, Истина);
Сертификаты = СертификатыШифрованияИзОписания(Описание);
Для каждого Свойства Из Сертификаты Цикл
Значение = Отпечатки[Свойства.Отпечаток];
Значение = ?(Значение = Неопределено, 1, Значение + 1);
Отпечатки.Вставить(Свойства.Отпечаток, Значение);
ПредставленияОтпечатков.Вставить(Свойства.Отпечаток, Свойства.Представление);
КонецЦикла;
КонецЦикла;
КоличествоЭлементовДанных = Параметры.СертификатыШифрования.Количество();
Для каждого КлючИЗначение Из Отпечатки Цикл
Если КлючИЗначение.Значение = КоличествоЭлементовДанных Тогда
Отбор.Вставить(КлючИЗначение.Ключ, ПредставленияОтпечатков[КлючИЗначение.Ключ]);
КонецЕсли;
КонецЦикла;
ИначеЕсли Параметры.СертификатыШифрования <> Неопределено Тогда
Сертификаты = СертификатыШифрованияИзОписания(Параметры.СертификатыШифрования);
Для каждого Свойства Из Сертификаты Цикл
Отбор.Вставить(Свойства.Отпечаток, Свойства.Представление);
КонецЦикла;
КонецЕсли;
Форма.ОтборОтпечатков = ПоместитьВоВременноеХранилище(Отбор, Форма.УникальныйИдентификатор);
КонецПроцедуры
// Для процедуры ЗаполнитьОтборОтпечатков.
Функция СертификатыШифрованияИзОписания(Описание)
Если ТипЗнч(Описание) = Тип("Строка") Тогда
Возврат ПолучитьИзВременногоХранилища(Описание);
КонецЕсли;
Сертификаты = Новый Массив;
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СертификатыШифрования.Представление,
| СертификатыШифрования.Отпечаток,
| СертификатыШифрования.Сертификат
|ИЗ
| РегистрСведений.СертификатыШифрования КАК СертификатыШифрования
|ГДЕ
| СертификатыШифрования.ЗашифрованныйОбъект = &ЗашифрованныйОбъект";
Запрос.УстановитьПараметр("ЗашифрованныйОбъект", Описание);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
СвойстваСертификата = Новый Структура("Отпечаток, Представление, Сертификат");
ЗаполнитьЗначенияСвойств(СвойстваСертификата, ВыборкаДетальныеЗаписи);
СвойстваСертификата.Сертификат = СвойстваСертификата.Сертификат.Получить();
Сертификаты.Добавить(СвойстваСертификата);
КонецЦикла;
Возврат Сертификаты;
КонецФункции
Функция ДвоичныеДанныеСтроки(ДанныеСтроки)
ВременныйФайл = ПолучитьИмяВременногоФайла();
ЗаписьТекста = Новый ЗаписьТекста(ВременныйФайл, КодировкаТекста.UTF8);
ЗаписьТекста.Записать(ДанныеСтроки);
ЗаписьТекста.Закрыть();
ДвоичныеДанныеСертификата = Новый ДвоичныеДанные(ВременныйФайл);
УдалитьФайлы(ВременныйФайл);
Возврат ДвоичныеДанныеСертификата;
КонецФункции
// Для процедур НастроитьФормуПодписанияШифрованияРасшифровки, СертификатПриИзмененииНаСервере.
Процедура ЗаполнитьСуществующиеСертификатыПользователя(СписокВыбора, ОтпечаткиСертификатовНаКлиенте,
ОтборСертификатов, ОтборОтпечатков = Неопределено)
СписокВыбора.Очистить();
Если ЭлектроннаяПодпись.СоздаватьЭлектронныеПодписиНаСервере() Тогда
МенеджерКриптографии = МенеджерКриптографии("ПолучениеСертификатов", Ложь);
Если МенеджерКриптографии <> Неопределено Тогда
ТипХранилища = ТипХранилищаСертификатовКриптографии.ПерсональныеСертификаты;
МассивСертификатов = МенеджерКриптографии.ПолучитьХранилищеСертификатов(ТипХранилища).ПолучитьВсе();
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьОтпечаткиСертификатов(
ОтпечаткиСертификатовНаКлиенте, МассивСертификатов, ДобавкаВремени(), ТекущаяДатаСеанса());
КонецЕсли;
КонецЕсли;
Если ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Тогда
МодульХранилищеСертификатов = ОбщегоНазначения.ОбщийМодуль("ХранилищеСертификатов");
МассивСертификатов = МодульХранилищеСертификатов.Получить("ПерсональныеСертификаты");
ЭлектроннаяПодписьСлужебныйКлиентСервер.ДобавитьОтпечаткиСертификатов(
ОтпечаткиСертификатовНаКлиенте, МассивСертификатов, ДобавкаВремени(), ТекущаяДатаСеанса());
КонецЕсли;
ОтборПоОрганизации = Ложь;
Если ТипЗнч(ОтборСертификатов) = Тип("СписокЗначений") Тогда
Если ОтборСертификатов.Количество() > 0 Тогда
ТекущийСписок = Новый СписокЗначений;
Для каждого ЭлементСписка Из ОтборСертификатов Цикл
Свойства = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
ЭлементСписка.Значение, "Ссылка, Наименование, Отпечаток, Пользователь");
Если ОтпечаткиСертификатовНаКлиенте.Найти(Свойства.Отпечаток) <> Неопределено Тогда
ТекущийСписок.Добавить(Свойства.Ссылка, Свойства.Наименование,
Свойства.Пользователь = Пользователи.АвторизованныйПользователь());
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементСписка Из ТекущийСписок Цикл
Если ЭлементСписка.Пометка Тогда
СписокВыбора.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление);
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементСписка Из ТекущийСписок Цикл
Если Не ЭлементСписка.Пометка Тогда
СписокВыбора.Добавить(ЭлементСписка.Значение, ЭлементСписка.Представление);
КонецЕсли;
КонецЦикла;
Возврат;
КонецЕсли;
ИначеЕсли Метаданные.ОпределяемыеТипы.Организация.Тип.СодержитТип(ТипЗнч(ОтборСертификатов)) Тогда
ОтборПоОрганизации = Истина;
КонецЕсли;
Если ОтборОтпечатков <> Неопределено Тогда
Отбор = ПолучитьИзВременногоХранилища(ОтборОтпечатков);
Для каждого Отпечаток Из ОтпечаткиСертификатовНаКлиенте Цикл
Если Отбор[Отпечаток] = Неопределено Тогда
Продолжить;
КонецЕсли;
СписокВыбора.Добавить(Отпечаток, Отбор[Отпечаток]);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Параметры.Вставить("Отпечатки", СписокВыбора.ВыгрузитьЗначения());
Запрос.Текст =
"ВЫБРАТЬ
| Сертификаты.Ссылка КАК Ссылка,
| Сертификаты.Наименование КАК Наименование,
| Сертификаты.Отпечаток
|ИЗ
| Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК Сертификаты
|ГДЕ
| Сертификаты.Отпечаток В(&Отпечатки)";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЭлементСписка = СписокВыбора.НайтиПоЗначению(Выборка.Отпечаток);
Если ЭлементСписка <> Неопределено Тогда
ЭлементСписка.Значение = Выборка.Ссылка;
ЭлементСписка.Представление = Выборка.Наименование;
КонецЕсли;
КонецЦикла;
СписокВыбора.СортироватьПоПредставлению();
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь());
Запрос.Параметры.Вставить("Отпечатки", ОтпечаткиСертификатовНаКлиенте);
Запрос.Текст =
"ВЫБРАТЬ
| Сертификаты.Ссылка КАК Ссылка,
| Сертификаты.Наименование КАК Наименование
|ИЗ
| Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования КАК Сертификаты
|ГДЕ
| Сертификаты.Программа <> ЗНАЧЕНИЕ(Справочник.ПрограммыЭлектроннойПодписиИШифрования.ПустаяСсылка)
| И Сертификаты.Пользователь = &Пользователь
| И Сертификаты.Отозван = ЛОЖЬ
| И Сертификаты.Отпечаток В(&Отпечатки)
| И ИСТИНА
|
|УПОРЯДОЧИТЬ ПО
| Наименование";
Если ОтборПоОрганизации Тогда
Запрос.Текст = СтрЗаменить(Запрос.Текст, "ИСТИНА", "Сертификаты.Организация = &Организация");
Запрос.УстановитьПараметр("Организация", ОтборСертификатов);
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
СписокВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
КонецПроцедуры
Процедура ЗаполнитьДополнительныеСвойстваСертификата(Форма)
Если Не ЗначениеЗаполнено(Форма.Сертификат) Тогда
Возврат;
КонецЕсли;
ЗначенияРеквизитов = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Форма.Сертификат,
"УсиленнаяЗащитаЗакрытогоКлюча, Отпечаток, Программа,
|ДействителенДо, ПользовательОповещенОСрокеДействия, ДанныеСертификата");
Попытка
ДвоичныеДанныеСертификата = ЗначенияРеквизитов.ДанныеСертификата.Получить();
Сертификат = Новый СертификатКриптографии(ДвоичныеДанныеСертификата);
Исключение
ИнформацияОбОшибке = ИнформацияОбОшибке();
Сертификат = Форма.Сертификат;
Форма.Сертификат = Неопределено;
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'При получении данных сертификата ""%1""
|из информационной базы возникла ошибка:
|%2'"),
Сертификат,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
КонецПопытки;
Форма.СертификатАдрес = ПоместитьВоВременноеХранилище(ДвоичныеДанныеСертификата, Форма.УникальныйИдентификатор);
Форма.СертификатОтпечаток = ЗначенияРеквизитов.Отпечаток;
Форма.СертификатПрограмма = ЗначенияРеквизитов.Программа;
Форма.ВыполнятьВМоделиСервиса = ЗначенияРеквизитов.Программа.ЭтоПрограммаОблачногоСервиса;
Форма.СертификатДействителенДо = ЗначенияРеквизитов.ДействителенДо;
Форма.СертификатУсиленнаяЗащитаЗакрытогоКлюча = ЗначенияРеквизитов.УсиленнаяЗащитаЗакрытогоКлюча;
Форма.ОповеститьОбОкончанииСрокаДействия =
Не ЗначенияРеквизитов.ПользовательОповещенОСрокеДействия
И ДобавитьМесяц(ТекущаяДатаСеанса(), 1) > Форма.СертификатДействителенДо;
Форма.СертификатНаСервереОписаниеОшибки = Новый Структура;
Если Не ЭлектроннаяПодпись.СоздаватьЭлектронныеПодписиНаСервере() Тогда
Возврат;
КонецЕсли;
ПолучитьСертификатПоОтпечатку(Форма.СертификатОтпечаток,
Истина, Ложь, Форма.СертификатПрограмма, Форма.СертификатНаСервереОписаниеОшибки);
КонецПроцедуры
// Для функции МенеджерКриптографии.
Функция НовыйМенеджерКриптографии(Программа, Ошибки, ИмяКомпьютера)
ОписанияПрограмм = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииОписанияПрограмм(
Программа, Ошибки, ЭлектроннаяПодпись.ОбщиеНастройки().ОписанияПрограмм);
Если ОписанияПрограмм = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ЭтоLinux = ОбщегоНазначения.ЭтоLinuxСервер();
Если ЭтоLinux Тогда
ПутиКПрограммамНаСерверахLinux = ПутиКПрограммамНаСерверахLinux(ИмяКомпьютера);
Иначе
ПутиКПрограммамНаСерверахLinux = Неопределено;
КонецЕсли;
Менеджер = Неопределено;
Для каждого ОписаниеПрограммы Из ОписанияПрограмм Цикл
СвойстваПрограммы = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииСвойстваПрограммы(
ОписаниеПрограммы, ЭтоLinux, Ошибки, Истина, ПутиКПрограммамНаСерверахLinux);
Если СвойстваПрограммы = Неопределено Тогда
Продолжить;
КонецЕсли;
Попытка
ИнформацияМодуля = СредстваКриптографии.ПолучитьИнформациюМодуляКриптографии(
СвойстваПрограммы.ИмяПрограммы,
СвойстваПрограммы.ПутьКПрограмме,
СвойстваПрограммы.ТипПрограммы);
Исключение
ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииДобавитьОшибку(Ошибки,
ОписаниеПрограммы.Ссылка, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()),
Истина, Истина, Истина);
Продолжить;
КонецПопытки;
Если ИнформацияМодуля = Неопределено Тогда
ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииПрограммаНеНайдена(
ОписаниеПрограммы, Ошибки, Истина);
Менеджер = Неопределено;
Продолжить;
КонецЕсли;
Если Не ЭтоLinux Тогда
ИмяПрограммыПолученное = ИнформацияМодуля.Имя;
ИмяПрограммыСовпадает = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииИмяПрограммыСовпадает(
ОписаниеПрограммы, ИмяПрограммыПолученное, Ошибки, Истина);
Если Не ИмяПрограммыСовпадает Тогда
Менеджер = Неопределено;
Продолжить;
КонецЕсли;
КонецЕсли;
Попытка
Менеджер = Новый МенеджерКриптографии(
СвойстваПрограммы.ИмяПрограммы,
СвойстваПрограммы.ПутьКПрограмме,
СвойстваПрограммы.ТипПрограммы);
Исключение
ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииДобавитьОшибку(Ошибки,
ОписаниеПрограммы.Ссылка, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()),
Истина, Истина, Истина);
Продолжить;
КонецПопытки;
АлгоритмыУстановлены = ЭлектроннаяПодписьСлужебныйКлиентСервер.МенеджерКриптографииАлгоритмыУстановлены(
ОписаниеПрограммы, Менеджер, Ошибки);
Если Не АлгоритмыУстановлены Тогда
Продолжить;
КонецЕсли;
Прервать; // Требуемый менеджер криптографии получен.
КонецЦикла;
Возврат Менеджер;
КонецФункции
Функция ИспользоватьЭлектроннуюПодписьВМоделиСервиса() Экспорт
Если Не ОбщегоНазначения.ПодсистемаСуществует("ТехнологияСервиса.РаботаВМоделиСервиса.ЭлектроннаяПодписьВМоделиСервиса") Тогда
Возврат Ложь;
КонецЕсли;
МодульЭлектроннаяПодписьВМоделиСервисаКлиентСервер =
ОбщегоНазначения.ОбщийМодуль("ЭлектроннаяПодписьВМоделиСервисаКлиентСервер");
Возврат МодульЭлектроннаяПодписьВМоделиСервисаКлиентСервер.ИспользованиеВозможно();
КонецФункции
Функция ПутиКПрограммамНаСерверахLinux(ИмяКомпьютера)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ИмяКомпьютера", ИмяКомпьютера);
Запрос.Текст =
"ВЫБРАТЬ
| ПутиКПрограмме.Программа,
| ПутиКПрограмме.ПутьКПрограмме
|ИЗ
| РегистрСведений.ПутиКПрограммамЭлектроннойПодписиИШифрованияНаСерверахLinux КАК ПутиКПрограмме
|ГДЕ
| ПутиКПрограмме.ИмяКомпьютера = &ИмяКомпьютера";
ПутиКПрограммамНаСерверахLinux = Новый Соответствие;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПутиКПрограммамНаСерверахLinux.Вставить(Выборка.Программа, Выборка.ПутьКПрограмме);
КонецЦикла;
Возврат ПутиКПрограммамНаСерверахLinux;
КонецФункции
// Для функции ПолучитьСоответствиеФайловИПодписей.
Функция НайтиИменаФайловПодписей(ИмяФайлаДанных, ИменаФайловПодписей)
ИменаПодписей = Новый Массив;
СтруктураИмени = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(ИмяФайлаДанных);
ИмяБезРасширения = СтруктураИмени.ИмяБезРасширения;
Для Каждого ИмяФайлаПодписи Из ИменаФайловПодписей Цикл
Если СтрНайти(ИмяФайлаПодписи, ИмяБезРасширения) > 0 Тогда
ИменаПодписей.Добавить(ИмяФайлаПодписи);
КонецЕсли;
КонецЦикла;
Для Каждого ИмяФайлаПодписи Из ИменаПодписей Цикл
ИменаФайловПодписей.Удалить(ИменаФайловПодписей.Найти(ИмяФайлаПодписи));
КонецЦикла;
Возврат ИменаПодписей;
КонецФункции
// Для функций Подписать и Sign.
// Преобразует сертификат криптографии в корректно отформатированную строку в формате Base64.
//
// Параметры:
// ДанныеСертификата - ДвоичныеДанные - данные сертификата, которые подлежат преобразованию.
//
// Возвращаемое значение:
// Строка - преобразованный в строку в формате Base64 сертификат.
//
Функция СертификатКриптографииBase64(ДанныеСертификата)
СтрокаBase64 = Base64Строка(ДанныеСертификата);
Значение = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
Значение = СтрЗаменить(Значение, Символы.ПС, "");
Возврат Значение;
КонецФункции
#КонецОбласти