feat(cryptocli): Go-клиент через PKCS#11 — КриптоПро CSP, Рутокен, etc.
Заменили stub-клиент на полноценный PKCS#11 wrapper через
github.com/miekg/pkcs11. Поддерживает любой PKCS#11-совместимый
провайдер: КриптоПро CSP (libcppkcs11.so), Рутокен ЭЦП 2.0
(librtpkcs11ecp.so), Валидата, ViPNet и др.
internal/cryptocli/client.go:
- cryptocli.Client с конфигом {Provider, ModulePath, PIN, SlotID}
- Health() — Initialize → GetInfo → GetSlotList(WithToken=true) →
GetTokenInfo для каждого слота. Возвращает HealthInfo с
Cryptoki/library версиями, manufacturer и списком подключённых
токенов (label, model, serial)
- DefaultModulePath() — путь до .so для каждого провайдера (CSP,
Рутокен, Валидата, ViPNet)
- Если провайдер=stub или модуль не найден — клиент возвращает
понятную ошибку, lk-gateway переходит в режим без криптографии
В admin/setup wizard:
- В карточке «Криптография» появилась кнопка «Проверить подключение СКЗИ»
→ POST /admin/setup/crypto/check → cryptocli.Health() → flash с
результатом сверху страницы (список токенов или диагностика)
- Поле "UDS-сокет" помечено как legacy (для старого Java crypto-service),
основное поле — «Путь к модулю PKCS#11» с дефолтами и подсказками
- Расширен список провайдеров: добавлен «rutoken»
internal/cryptocli/client_test.go:
- Тесты Stub, MissingModule, EmptyPath, DefaultModulePath
- Старые тесты на UDS-сокет удалены (теперь PKCS#11)
Зависимость: github.com/miekg/pkcs11 v1.1.2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/cryptocli"
|
||||
)
|
||||
|
||||
// setupHandlers — обработчики /admin/setup/*.
|
||||
@@ -37,11 +39,43 @@ func registerSetup(mux *http.ServeMux, a *admin, rc *RuntimeConfig, svc *Service
|
||||
})
|
||||
mux.HandleFunc("/admin/setup/postgres", h.savePostgres)
|
||||
mux.HandleFunc("/admin/setup/crypto", h.saveCrypto)
|
||||
mux.HandleFunc("/admin/setup/crypto/check", h.checkCrypto)
|
||||
mux.HandleFunc("/admin/setup/nsd", h.saveNSD)
|
||||
mux.HandleFunc("/admin/setup/lk", h.saveLK)
|
||||
mux.HandleFunc("/admin/setup/test-run", h.testRun)
|
||||
}
|
||||
|
||||
// checkCrypto — POST /admin/setup/crypto/check. Запускает Health()
|
||||
// текущего провайдера PKCS#11 без изменения настроек.
|
||||
func (h *setupHandlers) checkCrypto(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
s := h.rc.Snapshot()
|
||||
cli := cryptocli.New(cryptocli.Config{
|
||||
Provider: cryptocli.Provider(s.Crypto.Provider),
|
||||
ModulePath: s.Crypto.JCPPath, // унаследовано — теперь путь к PKCS#11 .so
|
||||
})
|
||||
defer cli.Close()
|
||||
info, err := cli.Health(r.Context())
|
||||
if err != nil {
|
||||
setupFlash(w, r, "СКЗИ: проверка не прошла — "+err.Error())
|
||||
return
|
||||
}
|
||||
msg := fmt.Sprintf("СКЗИ %s: %s", info.Provider, info.Message)
|
||||
if info.CryptokiVersion != "" {
|
||||
msg += fmt.Sprintf(" (PKCS#11 v%s, %s)", info.CryptokiVersion, info.ManufacturerID)
|
||||
}
|
||||
if len(info.Tokens) > 0 {
|
||||
msg += ". Токены:"
|
||||
for _, t := range info.Tokens {
|
||||
msg += fmt.Sprintf(" «%s» (%s);", t.Label, t.Model)
|
||||
}
|
||||
}
|
||||
setupFlash(w, r, msg)
|
||||
}
|
||||
|
||||
// SetupData — данные для шаблона admin_setup.html.
|
||||
type SetupData struct {
|
||||
page
|
||||
|
||||
Reference in New Issue
Block a user