passwordverify

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package passwordverify — проверяющий пароля, следующий за ХРАНИМЫМ значением (фаза Ф2, часть П2, задача `kacho#1268`).

Санкция — приёмка ID-PW-1 `docs/engineering/acceptance/password-verifier-follows-the-stored-value.md`; перечень форматов, потолки и пол объявлены в `internal/domain` (`password_hash_format.go`) и здесь не переобъявляются.

Что этот пакет делает и чего НЕ делает

Делает: выбирает проверяющего по признаку ХРАНИМОГО значения, разбирает тело с областью допустимости формата ДО вычисления, сверяет параметры с потолком ДО вычисления, считает и сверяет постоянным временем, ограничивает число одновременных проверок объявленной ёмкостью и отдаёт исход ТИПОМ.

НЕ делает: не читает настройку «что писать» — «как читать» решает значение, и слить эти вопросы значило бы завести два правила об одном поле; не ходит в хранилище; не знает ни полосы входа, ни её отказов, ни её частоты; не переписывает значений. Подключение ко входу и переписывание — фаза Ф3 (`kacho#1269`).

Index

Constants

View Source
const (
	// BackupCodeCount — кодов в наборе.
	BackupCodeCount = 10
	// BackupCodeLength — знаков в коде; алфавит Crockford base32 (32 знака) —
	// 50 бит случайности на код.
	BackupCodeLength = 10
)

Величины-контракты набора (Р6). Ручками не являются: у величины нет владельца, кроме этой строки.

Variables

This section is empty.

Functions

func IsWellFormedBackupCode

func IsWellFormedBackupCode(code string) bool

IsWellFormedBackupCode — форма кода набора (Н12): ровно BackupCodeLength знаков алфавита Crockford, регистр букв безразличен. Судится ДО сверки транспортом: малоформенный код — отказ формы с именем поля, не попытка.

func NewBackupCodes

func NewBackupCodes() ([]string, error)

NewBackupCodes — десять кодов по десять знаков алфавита без визуально смешиваемых знаков, из криптографического источника случайности.

func OutcomeNames

func OutcomeNames() []string

OutcomeNames — имена исходов строками: набор клеток счётчика собирается из них, а не из второго перечня.

func ParseCostClassPrefix

func ParseCostClassPrefix(prefix string) (domain.PasswordCostClass, error)

ParseCostClassPrefix — класс стоимости из префикса переписи.

Наследуемый формат: `$2a$<две цифры>`; объявленный: `$argon2id$v=19$m=<КиБ>,t=<проходы>,p=<параллельность>`. Всё прочее — отказ: пустой префикс (признак вне перечня), чужая версия разметки, лишний сегмент (соль, которой здесь быть не должно), негодное число.

func WallClockCostMeter

func WallClockCostMeter(_ domain.PasswordCostClass, verify func()) time.Duration

WallClockCostMeter — мера по монотонным часам процесса; её берёт композиционный корень. Часы читаются до начала прогона и после его конца: мера не короче прогона при любой задержке планировщика (TestWallClockCostMeter_MeasuresTheWholeRunItCalls).

Types

type Admission

type Admission struct {
	Cost       time.Duration
	Floor      time.Duration
	Calibrated bool
}

Admission — исход допуска класса: его стоимость, потолок после допуска и то, калибровался ли класс этим допуском (известный — нет).

type CalibratedClass

type CalibratedClass struct {
	Class domain.PasswordCostClass
	Cost  time.Duration
}

CalibratedClass — класс и его калиброванная стоимость.

type ClassNotReadableError

type ClassNotReadableError struct {
	Class   domain.PasswordCostClass
	Outcome Outcome
}

ClassNotReadableError — класс проверяющий не читает: исход разбора назван.

func (*ClassNotReadableError) Error

func (e *ClassNotReadableError) Error() string

type CostMeter

type CostMeter func(class domain.PasswordCostClass, verify func()) time.Duration

CostMeter — мера ОДНОГО прогона калибровки: зовёт verify синхронно ровно один раз и отдаёт стоимость этого прогона. Прогон исполняется в ёмкости проверяющего. Класс — довод меры, а не её результат: настенные часы его не читают, мера пробы по нему назначает стоимость.

type Declared

type Declared struct {
	Format domain.PasswordHashFormat
	Params map[domain.PasswordHashCostParam]uint32
}

Declared — объявленный формат вновь заводимых значений и его параметры.

func (Declared) Validate

func (d Declared) Validate() error

Validate — объявленное принадлежит области, которую задаёт перечень.

Отказ называет ручку, причину и границу: отказ, не называющий их, не восстанавливает следующий шаг оператора.

type Envelope

type Envelope struct {
	// contains filtered or unexported fields
}

Envelope — огибающая по потолку.

func NewEnvelope

func NewEnvelope(verifier *Verifier, observer EnvelopeObserver, meter CostMeter) (*Envelope, error)

NewEnvelope — огибающая над проверяющим. Все три довода обязательны: без проверяющего калибровать нечем, без приёмника потолок невидим, без меры стоимость класса нечем узнать.

func (*Envelope) Admit

Admit — класс входит в огибающую: известный — поиск по ключу; новый — калибровка, и потолок поднимается, если класс дороже текущего. Одновременные допуски одного нового класса дают ОДНУ калибровку. Калибровка, прерванная паникой меры, класса не держит: ждавшие её получают отказ, следующий допуск калибрует заново.

func (*Envelope) Ceiling

func (e *Envelope) Ceiling() (CalibratedClass, bool)

Ceiling — класс-потолок и его стоимость; false — классов нет.

func (*Envelope) Classes

func (e *Envelope) Classes() []CalibratedClass

Classes — все калиброванные классы, по ключу.

func (*Envelope) Floor

func (e *Envelope) Floor() time.Duration

Floor — потолок: раньше него ни один исход входа не уходит. Ноль — ни один класс ещё не допущен.

type EnvelopeObserver

type EnvelopeObserver interface {
	ClassCalibrated(class domain.PasswordCostClass, cost time.Duration, trigger EnvelopeTrigger)
	EnvelopeFloorObserved(floor time.Duration, ceiling domain.PasswordCostClass)
}

EnvelopeObserver — приёмник событий огибающей: калибровка класса (с его стоимостью и поводом) и смена потолка.

type EnvelopeTrigger

type EnvelopeTrigger string

EnvelopeTrigger — повод калибровки класса.

const (
	// EnvelopeTriggerStartup — старт процесса: перепись хранилища и ручка.
	EnvelopeTriggerStartup EnvelopeTrigger = "startup"
	// EnvelopeTriggerRead — полоса входа встретила класс, которого огибающая
	// не знала.
	EnvelopeTriggerRead EnvelopeTrigger = "read"
)

func EnvelopeTriggers

func EnvelopeTriggers() []EnvelopeTrigger

EnvelopeTriggers — словарь поводов копией: клетки счётчика заводятся из него, и вызывающий его не расширяет.

type Hasher

type Hasher struct {
	// contains filtered or unexported fields
}

Hasher — хешер объявленного формата.

func NewHasher

func NewHasher(declared Declared) (*Hasher, error)

NewHasher — хешер с объявлением, уже прошедшим страж старта. Незаданное или негодное объявление отвергается ЗДЕСЬ тем же правилом (`Declared.Validate`), чтобы хешер, собранный мимо стража, не написал ни одного значения.

func (*Hasher) Declared

func (h *Hasher) Declared() Declared

Declared — объявление, которым хешер пишет.

func (*Hasher) Hash

func (h *Hasher) Hash(password string) (domain.LoginVerifier, error)

Hash — значение объявленного формата для пароля. Пустой пароль отвергается: «пустого пароля» у полосы не бывает, правило пароля отвергает его раньше, и второе объявление здесь — только страховка от вызова мимо правила.

func (*Hasher) HashSet

func (h *Hasher) HashSet(codes []string) (domain.LoginVerifier, error)

HashSet — материал набора кодов объявленным форматом: одна соль, по элементу на код. Каждый код обязан быть годной формы; пустой набор не чеканится.

type NopEnvelopeObserver

type NopEnvelopeObserver struct{}

NopEnvelopeObserver — приёмник, ничего не считающий; для проб не о наблюдаемости.

func (NopEnvelopeObserver) ClassCalibrated

func (NopEnvelopeObserver) EnvelopeFloorObserved

func (NopEnvelopeObserver) EnvelopeFloorObserved(time.Duration, domain.PasswordCostClass)

type Observer

type Observer interface {
	VerificationObserved(outcome Outcome)
}

Observer — приёмник исходов. У КАЖДОГО исхода свой счётчик: слитые в один, повреждение данных и перегрузка читались бы как поток неверных паролей, а проверка, не отказавшая ни разу, была бы неотличима от мёртвой.

Клетки заводятся ДО первого события — их набор берётся из OutcomeNames.

type Outcome

type Outcome string

Outcome — исход одной проверки.

const (
	// OutcomeMatched — предъявленный пароль сошёлся с хранимым значением.
	OutcomeMatched Outcome = "matched"
	// OutcomeMismatched — не сошёлся. Это вход ЧЕЛОВЕКА, а не наша ошибка.
	OutcomeMismatched Outcome = "mismatched"
	// OutcomeFormatNotInRegistry — признак формата в перечень не входит.
	// Ошибка данных либо настройки: повтор того же запроса не даст иного.
	OutcomeFormatNotInRegistry Outcome = "format-not-in-registry"
	// OutcomeBodyNotParsable — признак известен, тело негодно: разметка
	// повреждена либо параметр лежит за областью допустимости формата.
	OutcomeBodyNotParsable Outcome = "body-not-parsable"
	// OutcomeParamsAboveCeiling — параметры стоимости выше потолка записи.
	// Цену попытки назначал бы чужой источник, поэтому вычисление не
	// начинается вовсе.
	OutcomeParamsAboveCeiling Outcome = "params-above-ceiling"
	// OutcomeMaterialMissing — проверочного материала нет. ЗАКОННОЕ состояние
	// личности, а не повреждение: отсутствие не приводится к пустому значению
	// и не сравнивается с ним.
	OutcomeMaterialMissing Outcome = "material-missing"
	// OutcomeCapacityExhausted — ёмкость проверки занята целиком. Единственный
	// преходящий исход: та же проверка после освобождения обязана пройти.
	OutcomeCapacityExhausted Outcome = "capacity-exhausted"
)

func Outcomes

func Outcomes() []Outcome

Outcomes — копия словаря: вызывающий не может его расширить.

func (Outcome) IsOurError

func (o Outcome) IsOurError() bool

IsOurError — исход, названный НАШЕЙ ошибкой: повреждение данных либо расхождение настройки с перечнем. Ни «не совпал», ни «материала нет», ни исчерпание ёмкости ею не являются — первое есть вход человека, второе законное состояние личности, третье нагрузка.

func (Outcome) IsTerminal

func (o Outcome) IsTerminal() bool

IsTerminal — повтор того же запроса не может дать иного исхода, поэтому политики повтора у него нет. Преходящ ровно один исход — исчерпание ёмкости.

type Presented

type Presented interface {
	Reveal() string
}

Presented — предъявленное значение, отдающее себя ОДНИМ методом.

Так предъявленный секрет отдаёт тип фундамента (`oauthceremony.PresentedSecret`): печать его значения не выдаёт, значение отдаёт только Reveal. Выход принимается здесь, а не у вызывающего: этот файл — единственное место, где выход с таким именем разрешён гейтом `TestLoginVerifierStaysInside`, и предъявленное значение не становится строкой нигде, кроме сверки.

type Result

type Result struct {
	// Outcome — исход. Единственное, что решает вызывающий.
	Outcome Outcome
	// Format — формат, по которому читали. Пуст, когда признак в перечень не
	// вошёл: называть формат, которого перечень не знает, значило бы выдать
	// догадку за факт.
	Format domain.PasswordHashFormat
	// Params — параметры стоимости разобранного значения. Пусты, когда тело не
	// разобрано.
	Params map[domain.PasswordHashCostParam]uint32
}

Result — исход одной проверки.

Материала не несёт и нести не может: наружу уходит исход, признак формата, по которому читали, и параметры стоимости — числа, а не части значения.

type SetCandidate

type SetCandidate struct {
	// contains filtered or unexported fields
}

SetCandidate — хеш предъявленного кода солью и параметрами набора, вычисленный до замка строки; либо отказ вычислить (ёмкость, материал).

func (SetCandidate) Element

func (c SetCandidate) Element() string

Element — значение элемента набора, совпадающее с хранимым при верном коде; адаптер снимает его из набора по значению. Пусто, когда кандидата нет.

func (SetCandidate) Format

func (c SetCandidate) Format(f fmt.State, _ rune)

Format — заглушка на любом глаголе форматирования.

func (SetCandidate) Ready

func (c SetCandidate) Ready() bool

Ready — кандидат вычислен.

func (SetCandidate) Refusal

func (c SetCandidate) Refusal() Outcome

Refusal — почему не вычислен (пусто, когда Ready).

func (SetCandidate) String

func (c SetCandidate) String() string

String — заглушка; кандидат в журнал не печатается.

type SetMatch

type SetMatch struct {
	// Outcome — совпал · не совпал · материала нет · наши отказы разбора.
	Outcome Outcome
	// Remaining — элементов в наборе ДО потребления (0 у исчерпанного);
	// осмысленно, когда набор читается.
	Remaining int
}

SetMatch — исход сравнения кандидата с набором под замком.

type Verifier

type Verifier struct {
	// contains filtered or unexported fields
}

Verifier — проверяющий пароля.

Настройки «что писать» он не принимает ВОВСЕ, и это главное его свойство: «как читать» решает хранимое значение (Р1). Прими он формат настройкой — смена настройки молча сделала бы нечитаемой уже лежащую популяцию.

func New

func New(capacity int, observer Observer) (*Verifier, error)

New — проверяющий с объявленной ёмкостью и приёмником исходов.

Оба довода обязательны: ёмкость без умолчания (PWV-15), приёмник — потому что мягкий проход законен только пока он слышен, а проверяющий без счётчиков молчит обо всех шести отказах разом.

func (*Verifier) Aligned

func (v *Verifier) Aligned() bool

Aligned отвечает, выровнена ли полоса «материала нет»: стоит ли выравнивающее значение (SetDecoy). Вызывающий, чей контракт требует, чтобы отказ по отсутствию материала стоил столько же, сколько отказ по несовпадению, спрашивает это при сборке, а не узнаёт по времени ответа.

func (*Verifier) Capacity

func (v *Verifier) Capacity() int

Capacity — объявленная ёмкость: сколько проверок идут одновременно. Её читает полоса, делящая проверяющего с полосой входа (сверка секрета клиента церемонии), чтобы занимать не больше своей доли.

func (*Verifier) InspectSet

func (v *Verifier) InspectSet(stored domain.LoginVerifier) Result

InspectSet — разбор материала набора без сверки: формат и параметры (числа); исход «не совпал» означает «читается» (как у MeetsDeclared).

func (*Verifier) MatchSet

func (v *Verifier) MatchSet(stored domain.LoginVerifier, c SetCandidate) SetMatch

MatchSet — сравнение кандидата с КАЖДЫМ элементом набора постоянным временем; остаток — число элементов до потребления.

func (*Verifier) MeetsDeclared

func (v *Verifier) MeetsDeclared(stored domain.LoginVerifier, declared Declared) (bool, error)

MeetsDeclared — отвечает ли хранимое значение объявленному формату и объявленным параметрам (PWV-11, строки 11.2 и 11.4).

«Объявленный формат» и «объявленные параметры» — ОДНО требование: значение объявленного формата, у которого хотя бы один параметр ниже объявленного, отвечающим не считается, иначе оно осталось бы лежать навсегда.

Значение, которого продукт не читает, отвечает ОТКАЗОМ, а не «да» либо «нет»: молчаливое «отвечает» оставило бы его лежать, молчаливое «не отвечает» послало бы полосу входа переписывать неразобранное.

func (*Verifier) ProcessorSlots added in v0.6.0

func (v *Verifier) ProcessorSlots() int

ProcessorSlots — мест вычисления: меньшее из процессоров процесса и ёмкости.

func (*Verifier) SetCandidate

func (v *Verifier) SetCandidate(ctx context.Context, stored domain.LoginVerifier, presented string) (SetCandidate, error)

SetCandidate — см. шапку раздела. Занимает ёмкость проверяющего (та же, что у пароля — PWV-15): «материала нет» платит ту же цену над холостым значением (PWV-06, Ф12-33). Ошибка — конец вызова до места вычисления, как у Verifier.Verify.

func (*Verifier) SetDecoy

func (v *Verifier) SetDecoy(decoy domain.LoginVerifier) error

SetDecoy — значение объявленного класса записи, которым выравнивается полоса «материала нет» (Ф3-31, PWV-06). Ставится композиционным корнем ОДИН раз: хешер объявленного класса пишет его от случайного пароля при старте, и стоимость его проверки равна стоимости проверки всякого значения того же класса. Пустое значение отвергается — «выравнивать нечем» не есть решение.

func (*Verifier) SetSize

func (v *Verifier) SetSize(stored domain.LoginVerifier) (int, bool)

SetSize — элементов в наборе (остаток); ok=false — материал не читается как набор.

func (*Verifier) Verify

func (v *Verifier) Verify(ctx context.Context, stored domain.LoginVerifier, presented string) (Result, error)

Verify — проверка предъявленного пароля против хранимого значения.

Ошибка — только конец вызова (контекст ctx) раньше, чем проверке досталось место вычисления (kaname#892): проверка не состоялась, исхода у неё нет, и приёмник исходов её не слышит — словарь исходов закрыт, и конец вызова в него не входит. Место ёмкости, взятое до очереди, отдаётся.

func (*Verifier) VerifyPresented

func (v *Verifier) VerifyPresented(ctx context.Context, stored domain.LoginVerifier, presented Presented) (Result, error)

VerifyPresented — Verifier.Verify для значения, отдающего себя методом: тот же исход, та же ёмкость, тот же приёмник и то же выравнивание полосы «материала нет».

func (*Verifier) WithCapacity

func (v *Verifier) WithCapacity(work func()) bool

WithCapacity исполняет работу, занимая одно место ёмкости; отвечает, удалось ли место занять. Нужен полосе входа Ф3 и пробам ёмкости.

Jump to

Keyboard shortcuts

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