Skip to content

Latest commit

 

History

History
138 lines (100 loc) · 7.27 KB

12-testing.md

File metadata and controls

138 lines (100 loc) · 7.27 KB

12. Тестирование

Проверки реализованы как bash-скрипты в tests/. Go-тестов (*_test.go) в проекте нет - всё, что проверяется, требует живой базы, поднятых слушателей и реальных криптографических операций, поэтому тесты работают против запущенного приложения.

Скрипт Что проверяет
tests/crl/test_crl.sh CRL: CDP, подписант, содержимое, окно валидности, цепочка
tests/ocsp/test_ocsp.sh OCSP: AIA, POST и GET, кэширование, unauthorized, статус Sub CA
tests/est/test_est.sh EST: полный цикл enroll → reenroll, блокировка по max_uses
tests/revocation/test_revocation.sh Сквозная сверка: база ↔ CRL ↔ OCSP

Общие свойства

Все скрипты сами находят корень проекта, поднимаясь вверх по дереву до go.mod, поэтому запускаются откуда угодно:

./tests/ocsp/test_ocsp.sh
cd tests/ocsp && ./test_ocsp.sh

Настройки переопределяются переменными окружения: DB, BASE_URL, CRL_URL, OCSP_URL, EST_URL. Временные файлы создаются в mktemp -d и удаляются по trap.

Требуется запущенное приложение - скрипты обращаются к живым эндпоинтам.

test_crl.sh

./tests/crl/test_crl.sh [<SERIAL>]

Восемь шагов: достаёт сертификат из базы, печатает CDP, Issuer и AKI, скачивает оба CRL, показывает их содержимое и наличие искомого серийного номера, сверяет AKI сертификата с AKI подписанта CRL, проверяет CDP в самом Sub CA и выполняет openssl verify -crl_check_all.

Отдельная функция check_crl_validity_window проверяет, что nextUpdate сдвинут относительно thisUpdate и совпадает с CAcrl.updateInterval. Это регрессионный тест: при чтении несуществующего ключа конфигурации интервал становится нулевым, и CRL оказывается просроченным в момент выпуска.

Диагностируемые ситуации:

Симптом Причина
AKI cert == AKI CRL signer: НЕТ Сертификат выпущен прежним Sub CA, который уже заменён
unable to get certificate CRL У Sub CA нет CDP - выпущен до внедрения
nextUpdate == thisUpdate Интервал не прочитался из конфигурации

test_ocsp.sh

./tests/ocsp/test_ocsp.sh [<SERIAL>]

Девять шагов: AIA в сертификате, POST-запрос с проверкой подписи ответа, GET-запрос с base64 в пути, сверка статусов между POST и GET, заголовки кэширования, запрос статуса Sub CA через Root CA (ветка scopeCoreSubCA) и проверка, что неизвестный серийный номер даёт unauthorized.

URL респондера берётся из AIA самого сертификата - так проверяется, что клиент действительно найдёт респондер самостоятельно.

test_est.sh

./tests/est/test_est.sh <username> <password> [<cn>]

Требует заранее созданного EST-пользователя (раздел Add EST users). Девять шагов: cacerts, генерация CSR, simpleenroll, проверка цепочки, simplereenroll по mTLS, сверка смены серийного номера, проверка статусов в est_certs (старый - 2, новый - 0), состояние учётной записи и, если max_uses исчерпан, - что повторный enroll возвращает 401.

Полный цикл проверяется на пользователе с MaxUses = 1. Скрипт использует один и тот же CN для обоих CSR, поэтому проверка неизменности Subject проходит штатно.

test_revocation.sh

./tests/revocation/test_revocation.sh [<SERIAL>]

Самый строгий скрипт: сверяет три источника и возвращает ненулевой код при расхождении, поэтому пригоден для CI.

Матрица ожиданий:

cert_status signing_ca_id В CRL В OCSP
2 revoked 0 - Core Sub CA да revoked
2 revoked -1 - Sub CA от Root да revoked
2 revoked >0 - внешний CA нет revoked
0 / 1 любой нет good

Третья строка фиксирует принятое решение: сертификаты внешних CA исключены из нашего CRL (он подписан другим ключом и для них неприменим), но обслуживаются через OCSP.

Дополнительно сверяются причина отзыва и момент времени - время из базы, CRL и OCSP приводится к unix-времени и сравнивается численно. Это снимает ложные расхождения из-за представления: база хранит 2026-08-14T09:45:12+04:00, протоколы показывают Aug 14 05:45:12 2026 GMT - один и тот же момент.

Скрипт также учитывает, что openssl дополняет серийный номер ведущим нулём до чётной длины, и сверяется с обоими вариантами записи.

Типовой сценарий проверки

# 1. Состояние до отзыва
./tests/revocation/test_revocation.sh <SERIAL>     # ожидается good

# 2. Отозвать сертификат через UI

# 3. Состояние после - CRL перегенерируется сразу, ждать тика не нужно
./tests/revocation/test_revocation.sh <SERIAL>     # ожидается revoked

# 4. Откатить отзыв через UI и проверить возврат
./tests/revocation/test_revocation.sh <SERIAL>     # снова good

Ручные проверки

# Целостность конфигурации (см. 02-configuration.md)
grep -rhoE 'viper\.Get[A-Za-z]+\("[^"]+"\)' --include="*.go" . \
  | grep -oE '"[^"]+"' | tr -d '"' | sort -u

# Сборка и статический анализ
go build ./... && go vet ./... && gofmt -l .

# Синтаксис тестовых скриптов
for f in tests/*/*.sh; do bash -n "$f" && echo "OK: $f"; done