# dss

## Описание

Сервис dss-service реализует работу с электронными подписями в облаке. Имеется собственная реализация (ОЭП от Лексемы) с использованием КриптоПро CSP для НЭП и интеграция с СКБ Контур.

!!! note
    Опциональный элемент системы. API доступно только внутри инфраструктуры серверной части lexema8. 

## Подключение сервиса 

Перед подключением требуется выполнить обновление базы данных для создания необходимых таблиц.
В режиме процесса создания проекта поддерживается только операционная система Linux. 

## Настройки для интеграции с СКБ Контур

При работе с боевыми площадками необходимо получить у СКБ Контур tls-сертификат (для доступа к API), купить лицензию КриптоПро, настроить приложение stunnel-msspi.
Пример настройки:

```
{
  applications: {
    dss: {
      protocol: 'http',
      host: 'dss-service',
      port: 3076,
      script: 'ecosoft-lexema8-dss-service',
      kontur: {
        cryptoApiUrl: 'http://localhost:8200/v3',
        cryptoApiHost: 'cloud.kontur-ca.ru:443'
        certificateReleasingUrl: 'http://localhost:8201/CC',
        certificateReleasingHost: 'reg.kontur-ca.ru:443',
        callbackUrl: 'http://dss.lexema.ru/api/v2.0/dss/kontur/response'
      }
    }
  }
}
```

**Примечания**
- host зависит от названия контейнера в файле docker-compose.yml.
- в свойстве cryptoApiUrl хост и порт берется из настроек stunnel-msspi (свойство accept из раздела [Crypto API]).
- в свойстве certificateReleasingUrl хост и порт берется из настроек stunnel-msspi (свойство accept из раздела [Certificate Releasing]).
- к свойству callbackUrl такие же требования, как при подключении сервиса в режиме разработки. Дополнительно нужно настроить список разрешенных адресов, которые могут обращаться по адресу callbackUrl. Для этого можно использовать Web Application Firewall. В качестве разрешенного адреса указывается cloud.kontur-ca.ru.
- свойство key указывать не нужно.

**stunnel-msspi**
Настройки stunnel-msspi должны находится в проекте с конфигурационными файлами в папке ./dss.
Пример stunnel-msspi:
```
output = /var/log/stunnel.log
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7

[Crypto API]
connect = cloudtest.kontur-ca.ru:443
client = yes
accept = localhost:8200
cert = 384d821774cb0e826d390ba34ddb7ae790415fe8
verify = 2

[Certificate Releasing]
connect = reg.kontur-ca.ru:443
client = yes
accept = localhost:8201
cert = 384d821774cb0e826d390ba34ddb7ae790415fe8
verify = 2
```

**Примечания:**
- cert - отпечаток tls-сертификата.
- для работы stunnel-msspi нужна лицензия КриптоПро. Для правильной установки лицензии обратитесь к системному администратору.

## Настройки для подключения ОЭП от Лексемы

Пример настройки:

```
{
  applications: {
    dss: {
      protocol: 'http',
      host: 'dss-service',
      port: 3076,
      script: 'ecosoft-lexema8-dss-service',
      lexema: {}
    }
  }
}
```
Дополнительно для работы в производственном окружении необходимо:
- Cгенерировать внешнюю гамму. Можно использовать биологический генератор, как в примере подключения сервиса в режиме разработки, либо использовать другие программные средства. Для подключения гаммы обратитесь к системному администратору.
- Установить лицензию КриптоПро. Для правильной установки лицензии обратитесь к системному администратору.
  
**Примечания:**
- Сгенерированной гаммы хватает на ограниченное количество ключей. Необходимо генерировать заново, если вся гамма была использована.
- Генерацией гаммы должен заниматься ответственный за безопасность хранения приватных ключей ЭП.
- Сертификаты и приватные ключи ЭП хранятся на сервере, где разворачивается dss-service.
- Если используется корневой сертификат, то файл (сертификата) должен иметь формат pfx.

## Установка сертификатов и лицензии Криптопро

Все сертификаты необходимо паместить в tar архив с именем certificates.tar и положить в папку dss в вашем deploy-проекте. в эту же папку добавьте файл import-cert.sh. Внутри файла пропишите команду для установки лицензии для криптпро, а также установку необходимых сертификатов. Сертификаты из архива будут автоматически распакованы в папку /root/certificates/.
пример файла import-cert.sh

```
# Установка лицензии криптопро
/opt/cprocsp/sbin/amd64/cpconfig -license -set <ENTRY_LICENSE>
/opt/cprocsp/sbin/amd64/cpconfig -license -view

# Пример установки сертификата для интеграции с Контур
/opt/cprocsp/bin/amd64/certmgr -install -pfx -file /root/certificates/tls.pfx  -pin <ENTRY_YOU_PIN> -silent

# Пример установки установки корневого сертификата, который используется при использовании ОЭЦП от лексемы
/opt/cprocsp/bin/amd64/certmgr -install -pfx -store mRoot -file /root/certificates/root.pfx  -pin <ENTRY_YOU_PIN> -silent
```

# Особенности работы сервиса при интеграции с СКБ Контур

## Выпуск тестового пользовательского сертификата

Для работы в тестовом окружении необходимо получить тестовый сертификат. В качестве ключа используется ключ доступа к тестовому серверу из примера подключения сервиса в режиме разработки.

## Обновление статуса при запуске сервиса

При запуске сервиса автоматически запрашиваются статусы операций, которые находились в процессе выполнения. В зависимости от полученного статуса в базе сохраняется новый статус операции и подпись (если операция была успешно завершена).

## Обработка подписей на сервере

Если необходимо обрабатывать результат операции на сервере после того, как придет ответ от СКБ Контур на маршрут, указанный конфигурационном файле в свойстве callbackUrl, то необходимо в проект подключить сервис scheduler и создать для него задачу Для задачи необходимо написать прикладную функцию, в которой будет обрабатываться результат операции. В составе типового решения КЭДО Lexema-ECM интеграция с СКБ Контур по умолчанию выключена.

### Настройка конфигурационного файла

Для выполнения созданной задачи сервисом scheduler необходимо в соответствующем разделе конфигурационного файла добавить свойство taskId - идентификатор созданной задачи.
Пример:

```
{
  applications: {
    "dss": {
      "kontur"{
        taskId: 1
      }     
    }
  }
}
```

# Особенности работы ОЭП от Лексемы

Поддерживается:
- Создание сертификатов НЭП с сроком действия 18 месяцев. Можно подключать корневой сертификат для выпуска пользовательских.
- Удаление сертификата.
- Подписание файла.
- Проверка подписи.

## Создание сертификатов

По умолчанию пользователь может создать сертификат только самому себе. Если нужна возможность, чтобы пользователь мог создавать сертификаты другим пользователям, то необходимо создать в системе роль DssAdmin (если ее нет) и назначить ему эту роль. После этого в методе создания сертификата можно передавать идентификатор пользователя, для которого необходимо создать сертификат.

## Использование корневого сертификата

При необходимости можно использовать корневой сертификат. В этом случае пользовательские сертификаты будут подписываться корневым. Это дает дополнительную возможность убедиться в подлинности пользовательского сертификата за счет проверки подписи.

Можно использовать один общий сертификат (настраивается в конфигурационном файле), который будет использоваться для всех организаций, либо делать привязку сертификата для конкретной организации. Привязка к организации настраивается на форме редактирования компании (поле отпечаток сертификата).

При выпуске сертификата будет использоваться сертификат, который привязан к организации, иначе сертификат по умолчанию, который указан в конфигурационном файле. Если не заданно в конфигурационном файле, то будет создан самоподписанный сертификат.

# Заполнение поля Subject (информация о владельце) сертификата

При создании сертификата в Subject сертификата автоматически добавляются следующие поля:
- SN - Фамилия пользователя
- G - Имя и отчество
- CN - Фамилия, имя и отчество
- E - email пользователя
Эти данные о пользователе загружаются из системной таблицы.

## Добавление дополнительных полей в сертификат

Если необходимо в поле Subject сертификата добавить дополнительные поля, то следует написать прикладной запрос, который должен вернуть требуемые атрибуты.
Список поддерживаемых атрибутов, который должен вернуть запрос:
- FirstName - Имя пользователя. Добавляется в поле G сертификата.
- LastName - Фамилия пользователя. Добавляется в поле SN сертификата.
- MiddleName - Отчество пользователя. Добавляется в поле G сертификата.
- Email - Почта пользователя. Добавляется в поле E сертификата.
- Organization - Организация. Добавляется в поле O сертификата.
- Position - Должность пользователя. Добавляется в поле T сертификата.
- OrganizationINN - ИНН организации. Добавляется в поле "Неструктурированное имя" сертификата.
- OrganizationKPP - КПП организации. Добавляется в поле "Неструктурированное имя" сертификата.
- OrganizationOGRN - ОГРН организации. Добавляется в поле "Неструктурированное имя" сертификата.
Пример заполнения поля "Неструктурированное имя" в сертификате: INN=12345678/KPP=948931/OGRN=524535.

Для созданного запроса необходимо добавить роль DssService (эту роль необходимо создать, если ее нет). Пример описания запроса:

```
{
  "rights": {
    "read": ["DssAdmin"]
  },
  "select": {
    "text": "./loadAttributes.sql",
    "parameters": ["userId", "bigint"]
  },
  "parameters": {
    "userId": "bigint",
    "orgId": "bigint"
  }
}
```

Запрос принимает идентификатор пользователя из системной таблицы lex.User, а также идентификатор организации из таблицы lex.Organization
Созданный запрос необходимо добавить в файл внешних зависимостей exteranl-manual.json (если это необходимо) и в конфигурационный файл (раздел applications.dss.lexema.loadUserAttributesQuery). Пример конфигурационного файла:

```
dss: {
  ...
  lexema: {
    loadUserAttributesQuery: './digitalSignature/loadAttributes.query.json'
  }
  ...
```

# Описание системных моделей

## Модель для хранения подписей от СКБ Контур

Описание свойств модели:
- Id - идентификатор подписи.
- FileId - идентификатор файла из системной таблицы lex.File, который подписывается.
- OperationId - идентификатор операции, который создается на стороне СКБ Контур.
- Status - статус операции. Значение статуса соответствует значениям из документации от СКБ Контур (берется текстовое значение, а не числовое).
- Signature - подпись файла в формате base64.
- KonturFileId - идентификатор файла, который создается на стороне СКБ Контур.
- CUser - логин пользователя, который создал операцию подписи.
- WUser - логин пользователя, который обновил подпись. 
- CHost - хост пользователя, который создал операцию подписи.
- WHost - хост пользователя, который обновил подпись.

## Модель для хранения сертификатов пользователей

Описание свойств модели:
- Id - идентификатор сертификата пользователя.
- User - идентификатор пользователя.
- Value - сертификат в формате base64.
- DisableConfirmOperation - флаг, отвечающий за отключение подтверждения операции подписания сертификатом.
- ValidFrom - дата начала действия сертификата.
- ValidTo - дата окончания действия сертификата.
- Provider - провайдер (lexema или kontur).
- Qualified - определяет является ли сертификат квалифицированным.
- CertificateThumbprint - отпечаток сертификата.
- CUser - логин пользователя, который создал запись в таблице.
- WUser - логин пользователя, который обновил запись в таблице.
- CHost - хост пользователя, который создал запись в таблице.
- WHost - хост пользователя, который обновил запись в таблице.

При необходимости можно унаследоваться от этой модели и добавить новые поля, а также назначить необходимые роли. Для добавления сертификатов в систему необходимо прикладными средствами создать форму. Доступ к модели или запросам (которые будут работать с таблицей, где хранятся сертификаты) необходимо давать администратору приложения. Доступ на чтение данных можно дать для обычных пользователей (загружая только те поля, которые нужны на клиенте), если это необходимо.

## Настройка сервиса

- **protocol** - используемый веб-протокол (по умолчанию '`http`').
- **host** - имя хоста (по умолчанию '`localhost`').
- **port** - порт для запуска (по умолчанию - `3076`).
- **route** - используемый маршрут (по умолчанию '`/api/v2.0/dss`').
- **timeout** - количество миллисекунд бездействия, после которого считается, что время ожидания истекло (по умолчанию `120`). В режиме продакшена может потребоваться дополнительно настроить таймаут для веб-сервера (nginx).
- **script** - путь к модулю, запускающему сервис (рекомендуемое '`ecosoft-lexema8-dss-service`').
- **kontur** - настройки для интеграции с СКБ Контур.
- **key** - ключ для доступа к тестовой площадке контура.
- **cryptoApiUrl** - адрес, по которому доступно Crypto API контура. При работе с тестовой площадкой по http указывается '`http://cloudtest.kontur-ca.ru/v3`'. При работе с тестовой или боевой площадками по https указывается адрес, по которому доступен stunnel-msspi.
- **certificateReleasingUrl** - адрес, по которому доступно Certificate Releasing API контура. При работе с тестовой площадкой по http указывается '`http://test.kontur-ca.ru/CC`'. При работе с боевой площадкой по https указывается адрес, по которому доступен stunnel-msspi.
- **cryptoApiHost** - добавляет http-заголовок host для запросов, которые обращаются к Crypto API. Свойство задается, если сервис работает в связке с stunnel-msspi. При работе с тестовой площадкой указывается '`cloudtest.kontur-ca.ru:443`', при работе с боевой площадкой '`cloud.kontur-ca.ru:443`'.
- **certificateReleasingHost** - добавляет http-заголовок host для запросов, которые обращаются к Сertificate Releasing API. Свойство задается, если сервис работает в связке с stunnel-msspi. При работе с боевой площадкой указывается '`reg.kontur-ca.ru:443`'.
- **callbackUrl** - полный адрес к маршруту, на который придет POST-запрос с результатом операции от СКБ Контур. Шаблон адреса: `[protocol]://[domain]/api/v2.0/kontur/dss/response`.
- **taskId** - идентификатор задачи, который выполнится сервисом shceduler после обработки POST-запроса от СКБ Контур маршрутом callbackUrl (по умолчанию `null`).
- **disableConfirmOperation** - отключает подтверждение операции по смс для сертификатов НЭП по умолчанию `false`. Если настройка включена, то работа с сертификатами КЭП становится невозможной.
- **lexema** - Настройки для подключения ОЭП от Лексемы. Для подключения достаточно указать пустой объект `{}`, если не используются дополнительные настройки.
- **certificateValidityPeriod** - Задает срок действия сертификата в днях (по умолчанию `1825`).
- **loadUserAttributesQuery** - путь к запросу, который возвращает атрибуты, используемые для заполнения поля Subject (информация о владельце) сертификата.
- **confirmCodeLifeTime** - время действия кода для подтверждения операции в секундах (по умолчанию `60`).
- **attemptsLimitForConfirmCode** - лимит попыток ввода кода для подтверждения операции (по умолчанию `3`). Если указано `0`, то количество попыток неограничено.
- **disableConfirmOperation** - отключает подтверждение операции по коду (по умолчанию `false`).
- **containerStorage** - тип хранилища данных для контейнера закрытого ключа (по умолчанию `REGISTRY`). Настройка используется для ОС Windows. Доступные значения: `REGISTRY`, `HDIMAGE`.
- **rootCertificate** - Задает настройки корневых сертификатов, которые используются для выпуска пользовательских сертификатов. В режиме разработки сертификаты рекомендуется устанавливать в корневые доверенные сертификаты пользователя, а в режиме производства в корневые доверенные сертификаты компьютера. Если корневые сертификаты не используются, то это свойство не нужно задавать.
- **thumbprint** - отпечаток корневого сертификата, который будет использоваться по умолчанию. Имеет меньший приоритет, чем сертификат, который привязан к организации. Можно не задавать.
- **store** - хранилище для корневых сертификатов (рекомендуемое значение в режиме разработки '`uRoot`' - поиск в корневых довер
