## Краткое описание В модуле реализованы следующие функции: - подпись данных - проверка подписи маркера доступа - проверка подписанного сообщения, содержащего отсоединённую (detached) подпись ## Подпись данных Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: text/plain). C помощью ДСЧ генерирует state - набор случайных символов, генерируется по стандарту UUID. В строку, полученную в теле запроса, добавляет state. В ответе возвращает подпись полученной строки в формате urlSafeBase64 (параметр "signature") и сгенерированный state (параметр "state") (Content-Type: application/json). Пример выполнения запроса: ``` $ /opt/cprocsp/bin/amd64/curl -v http://127.0.0.1/sign -H "Content-Type: text/plain" -d "test" * Trying 127.0.0.1:80... * Connected to 127.0.0.1 (127.0.0.1) port 80 > POST /sign HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/8.4.0 > Accept: */* > Content-Type: text/plain > Content-Length: 4 > < HTTP/1.1 200 OK < Server: nginx/1.24.0 < Date: Tue, 20 Aug 2024 12:00:25 GMT < Content-Type: application/json < Transfer-Encoding: chunked < Connection: keep-alive < { "signature": "urlSafeBase64_of_signed_string_test_with_state", "state": "7c327cb7-7916-4255-bc46-85fbc5ad7d5f" } ``` ## Проверка подписи маркера доступа Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: text/plain). Проверяет подпись маркера доступа, полученного в теле запроса. В ответе возвращает один из следующих статус-кодов: - `200 OK` - подпись валидна - `401 Unauthorized` - подпись невалидна (в теле ответа возвращается код ошибки от криптопровайдера) - `500 Internal Server Error` - внутренняя ошибка сервера (подробнее см. в `Обработка ошибок`) Пример выполнения запроса: ``` $ /opt/cprocsp/bin/amd64/curl -v http://127.0.0.1/verify -H "Content-Type: text/plain" -d "some_valid_access_token" * Trying 127.0.0.1:80... * Connected to 127.0.0.1 (127.0.0.1) port 80 > POST /sign HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/8.4.0 > Accept: */* > Content-Type: text/plain > Content-Length: 4 > < HTTP/1.1 200 OK < Server: nginx/1.24.0 < Date: Wed, 16 Oct 2024 09:55:46 GMT < Transfer-Encoding: chunked < Connection: keep-alive < ``` ### Проверка подписанного сообщения, содержащего отсоединённую подпись Приложение принимает POST-запрос по протоколу FastCGI (Content-Type: multipart/form-data). Проверяет подписанное сообщение, содержащее отсоединённую (detached) подпись. В ответе возвращает один из следующих статус-кодов: - `200 OK` - подпись валидна, в ответе возвращает поля "Subject" и "Issuer" из свойств сертификата, которым было подписано сообщение - `401 Unauthorized` - подпись невалидна (в теле ответа возвращается код ошибки от криптопровайдера) - `500 Internal Server Error` - внутренняя ошибка сервера (подробнее см. в `Обработка ошибок`) Пример выполнения запроса: ``` $ /opt/cprocsp/bin/amd64/curl -v http://127.0.0.1/msg/verify_detached \ -F "data=@data.csv;type=application/octet-stream" \ -F "sign=@data.csv.sig;type=application/octet-stream" * Trying 127.0.0.1:80... * TCP_NODELAY set * Connected to 127.0.0.1 (127.0.0.1) port 80 (#0) > POST /msg/verify_detached HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/7.65.3-DEV > Accept: */* > Content-Length: 2770 > Content-Type: multipart/form-data; boundary=------------------------d4c9f889765b7342 > < HTTP/1.1 200 OK < Server: nginx/1.24.0 < Date: Tue, 26 Aug 2025 08:58:18 GMT < Content-Type: application/json < Transfer-Encoding: chunked < Connection: keep-alive < { "signer_subject":"C=RU, O=Организация, OU=Отдел тестирования отсоединенной подписи, CN=Фамилия Имя Отчество", "issuer_name": "C=RU, O=УЦ, CN=GOST CA Root" } ``` ## Обработка ошибок В случае ошибки сервер возвращает ответ со статус-кодом `500 Internal Server Error` и телом в формате JSON, содержащим поле `error_code`. Пример ответа: ```json { "error_code": "CERT_TRUST_REVOCATION_STATUS_UNKNOWN" } ``` ### Возможные коды ошибок (`error_code`) | Код | Описание | |-----------------------------------------|----------| | `CERT_TRUST_REVOCATION_STATUS_UNKNOWN` | Неизвестен статус отзыва сертификата или одного из сертификатов в цепочке (проблема с CRL) | | `CERT_TRUST_IS_UNTRUSTED_ROOT` | Сертификат или цепочка сертификатов основана на ненадежном корневом сертификате | | `CERT_TRUST_IS_NOT_TIME_VALID` | Этот сертификат или один из сертификатов в цепочке сертификатов является недопустимым по времени | ## Сборка из исходников Инструкции по сборке из исходников см. "Инструкция по сборке.md" Примечание. Чтобы задать произвольное имя конфигурационного файла, при сборке приложения необходимо задать параметр CONFIG_NAME. Пример: ``` cmake -DCONFIG_NAME=/opt/ervu-sign-module.conf .. ``` ## Установка Инструкции по установке см. "Инструкция по установке.md" ## Настройка Приложение настраивается в конфигурационном файле, заданном на этапе сборки (по умолчанию, /etc/ervu-sign-module.conf). - В секции **\[main\]** задать общие настройки: worker_processes = 10 *\# количество воркеров (значение по умолчанию: 10)* cp_file = libcapi20.so *\# путь до файла библиотеки криптопровайдера* cp_name = Crypto-Pro GOST R 34.10-2012 KC2 CSP *\# название криптопровайдера* cp_type = 80 *\# тип криптопровайдера* - В секции **\[fcgi\]** задать настройки fcgi-сервера: fcgi_listen_port = 9009 *\# значение по умолчанию: 9009, должно совпадать со значением в nginx.conf* fcgi_listen_host = 127.0.0.1 *\# значение по умолчанию: 127.0.0.1, должно совпадать со значением в nginx.conf* fcgi_thread_pool_size = 1 *\# значение по умолчанию: 1* - В секции **\[sign\]** задать настройки модуля подписания: location = /sign *\# значение по умолчанию: /sign* sign_cert_thumbprint = sha1_thumbprint_of_signer_cert *\# SHA1 отпечаток сертификата, которым ИС подписывает секрет* sign_cert_password = \*\*\*\* *\# пароль от контейнера* - В секции **\[verify\]** задать настройки проверки подписи маркера доступа: location = /verify *\# значение по умолчанию: /verify* esia_cert_thumbprint = sha1_thumbprint_of_esia_cert0,sha1_thumbprint_of_esia_cert1 *\# список SHA1 отпечатков сертификатов ЕСИА, указанных через запятую (без пробелов)* - В секции **\[verify_detached\]** задать настройки проверки подписанного сообщения, содержащего отсоединённую подпись: location = /msg/verify_detached *\# значение по умолчанию: /msg/verify_detached* ## Логирование времени обработки запросов ***Для включения*** логирования времени обработки запросов необходимо задать переменную окружения SIGN_LOG_TIME: ``` export SIGN_LOG_TIME=on ``` ***Для отключения*** логирования времени обработки запросов необходимо удалить переменную окружения SIGN_LOG_TIME: ``` unset SIGN_LOG_TIME ```