enroll

package
v0.0.0-...-9c5e272 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package enroll реализует bootstrap-энроллмент агента (Этап 3): агент сам генерит ключевую пару и CSR, получает по одноразовому токену подписанный сервером сертификат (CN=device_id ставит сервер, ADR-1) и раскладывает mTLS-материал на диск. Контракт — docs/enrollment.md (REST POST /api/v1/enroll).

Приватный ключ НИКОГДА не покидает устройство: сервер получает только CSR (публичный ключ). Канал энроллмента — server-auth TLS, доверие к серверу до получения CA обеспечивается CA-бандлом из установочного пакета (пин), запрос аутентифицируется одноразовым токеном.

Index

Constants

This section is empty.

Variables

View Source
var ErrCAPinMismatch = errors.New("CA-бандл не прошёл пин-проверку")

ErrCAPinMismatch — бандл не сошёлся с -ca-sha256. Это не «сеть моргнула»: либо MITM, либо пин в параметрах установщика протух (CA переиздали, команду не обновили). Деградировать на CA с диска по этой ошибке нельзя.

View Source
var ErrNoCASource = errors.New("для энроллмента нужен CA-бандл: задайте -ca <файл> или -ca-url <url>")

ErrNoCASource — источника CA нет вовсе: ни файла -ca на диске, ни -ca-url. Отдельная ошибка, чтобы вызывающий отличал «проверять нечем» от «проверили и не сошлось» (cmd/agent на первом сохраняет идемпотентность, на втором падает).

Functions

func FetchPinnedCA

func FetchPinnedCA(caURL, caSHA256 string) ([]byte, error)

FetchPinnedCA скачивает CA-бандл по URL и сверяет с пином. В отличие от LoadCABundle НЕ смотрит на диск: только так видно переиздание CA на сервере — лежащий на диске ca.crt остался бы старым и «подтвердил» бы старую идентичность.

func LeafSignedByCA

func LeafSignedByCA(leaf *x509.Certificate, caCerts []*x509.Certificate) error

LeafSignedByCA — ядро проверки «этот leaf выписан этим CA»: подпись + EKU, без часов. Всё «почему без часов» — в доке certChainsToCA выше; коротко: любой выбор CurrentTime ломается (time.Now() — на съехавших назад часах, leaf.NotBefore — на CA моложе минуты).

Экспортировано, потому что ровно та же проверка нужна cmd/agent для УЖЕ УСТАНОВЛЕННОЙ идентичности (reusableIdentity): вопрос там тот же, и второй реализации у него быть не должно — своя копия уже разошлась с этой и принесла ту самую ошибку с часами.

func LoadCABundle

func LoadCABundle(caFile, caURL, caSHA256 string) ([]byte, error)

LoadCABundle — экспорт loadCABundle для cmd/agent: тем же бандлом, которым Run пинит enroll-запрос, проверяется и издатель уже лежащей на диске идентичности (иначе агент после переиздания CA молча оставил бы чужой серт).

func ParseCACerts

func ParseCACerts(pemBytes []byte) ([]*x509.Certificate, error)

ParseCACerts разбирает CA-бандл в сертификаты БЕЗ проверки сроков: единственный потребитель — сверка издателя (LeafSignedByCA), которой часы противопоказаны. Срок годности CA проверяет validateCABundle на пути энроллмента.

func Run

func Run(ctx context.Context, req Request, log *slog.Logger) (string, error)

Run выполняет энроллмент и раскладывает cert/key/ca на диск. Возвращает device_id.

func ValidateCABundle

func ValidateCABundle(pemBytes []byte) ([]*x509.Certificate, error)

ValidateCABundle — экспорт validateCABundle для cmd/agent: CA, дотянутый по -ca-url на reused-пути (relocateForService), проходит ту же проверку пригодности («это вообще CA?»), что и бандл на свежем энроллменте. Пин отвечает только за целостность байт — лист-сертификат вместо CA он не поймает.

Types

type Request

type Request struct {
	EnrollURL string // полный URL эндпоинта, напр. https://host:8081/api/v1/enroll
	Token     string // одноразовый enrollment-токен (UUID v4)
	CAFile    string // CA-бандл из пакета: пин TLS enroll-эндпоинта
	CAURL     string // откуда скачать CA-бандл, если CAFile нет на диске (TOFU)
	CASHA256  string // ожидаемый hex sha256 CA-бандла: пин против MITM на TOFU-шаге

	CertOut string // куда записать выданный сертификат (agent.crt)
	KeyOut  string // куда записать локально сгенерённый ключ (agent.key)
	CAOut   string // куда записать CA для рантайма (ca.crt)
	// ReleaseKeyOut — куда записать base64 release-pubkey из enroll-ответа (для
	// самообновления универсального агента без вшитого ключа). Пусто — не пишем.
	ReleaseKeyOut string

	Hostname string // справочно для UI
	OS       string
	Arch     string

	// HTTPClient — для тестов; в проде nil → клиент строится с пином CAFile.
	HTTPClient *http.Client
}

Request — параметры энроллмента.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL