ervu-sign-module/README.md

177 lines
9.3 KiB
Markdown
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.

## Краткое описание
В модуле реализованы следующие функции:
- подпись данных
- проверка подписи маркера доступа
- проверка подписанного сообщения, содержащего отсоединённую (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
```