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
- func IsWellFormedBackupCode(code string) bool
- func NewBackupCodes() ([]string, error)
- func OutcomeNames() []string
- func ParseCostClassPrefix(prefix string) (domain.PasswordCostClass, error)
- func WallClockCostMeter(_ domain.PasswordCostClass, verify func()) time.Duration
- type Admission
- type CalibratedClass
- type ClassNotReadableError
- type CostMeter
- type Declared
- type Envelope
- type EnvelopeObserver
- type EnvelopeTrigger
- type Hasher
- type NopEnvelopeObserver
- type Observer
- type Outcome
- type Presented
- type Result
- type SetCandidate
- type SetMatch
- type Verifier
- func (v *Verifier) Aligned() bool
- func (v *Verifier) Capacity() int
- func (v *Verifier) InspectSet(stored domain.LoginVerifier) Result
- func (v *Verifier) MatchSet(stored domain.LoginVerifier, c SetCandidate) SetMatch
- func (v *Verifier) MeetsDeclared(stored domain.LoginVerifier, declared Declared) (bool, error)
- func (v *Verifier) ProcessorSlots() int
- func (v *Verifier) SetCandidate(ctx context.Context, stored domain.LoginVerifier, presented string) (SetCandidate, error)
- func (v *Verifier) SetDecoy(decoy domain.LoginVerifier) error
- func (v *Verifier) SetSize(stored domain.LoginVerifier) (int, bool)
- func (v *Verifier) Verify(ctx context.Context, stored domain.LoginVerifier, presented string) (Result, error)
- func (v *Verifier) VerifyPresented(ctx context.Context, stored domain.LoginVerifier, presented Presented) (Result, error)
- func (v *Verifier) WithCapacity(work func()) bool
Constants ¶
const ( // BackupCodeCount — кодов в наборе. BackupCodeCount = 10 // BackupCodeLength — знаков в коде; алфавит Crockford base32 (32 знака) — // 50 бит случайности на код. BackupCodeLength = 10 )
Величины-контракты набора (Р6). Ручками не являются: у величины нет владельца, кроме этой строки.
Variables ¶
This section is empty.
Functions ¶
func IsWellFormedBackupCode ¶
IsWellFormedBackupCode — форма кода набора (Н12): ровно BackupCodeLength знаков алфавита Crockford, регистр букв безразличен. Судится ДО сверки транспортом: малоформенный код — отказ формы с именем поля, не попытка.
func NewBackupCodes ¶
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 ¶
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 — объявленный формат вновь заводимых значений и его параметры.
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 ¶
func (e *Envelope) Admit(ctx context.Context, class domain.PasswordCostClass, trigger EnvelopeTrigger) (Admission, error)
Admit — класс входит в огибающую: известный — поиск по ключу; новый — калибровка, и потолок поднимается, если класс дороже текущего. Одновременные допуски одного нового класса дают ОДНУ калибровку. Калибровка, прерванная паникой меры, класса не держит: ждавшие её получают отказ, следующий допуск калибрует заново.
func (*Envelope) Ceiling ¶
func (e *Envelope) Ceiling() (CalibratedClass, bool)
Ceiling — класс-потолок и его стоимость; false — классов нет.
func (*Envelope) Classes ¶
func (e *Envelope) Classes() []CalibratedClass
Classes — все калиброванные классы, по ключу.
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 ¶
NewHasher — хешер с объявлением, уже прошедшим страж старта. Незаданное или негодное объявление отвергается ЗДЕСЬ тем же правилом (`Declared.Validate`), чтобы хешер, собранный мимо стража, не написал ни одного значения.
func (*Hasher) Hash ¶
func (h *Hasher) Hash(password string) (domain.LoginVerifier, error)
Hash — значение объявленного формата для пароля. Пустой пароль отвергается: «пустого пароля» у полосы не бывает, правило пароля отвергает его раньше, и второе объявление здесь — только страховка от вызова мимо правила.
type NopEnvelopeObserver ¶
type NopEnvelopeObserver struct{}
NopEnvelopeObserver — приёмник, ничего не считающий; для проб не о наблюдаемости.
func (NopEnvelopeObserver) ClassCalibrated ¶
func (NopEnvelopeObserver) ClassCalibrated(domain.PasswordCostClass, time.Duration, EnvelopeTrigger)
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 ¶
IsOurError — исход, названный НАШЕЙ ошибкой: повреждение данных либо расхождение настройки с перечнем. Ни «не совпал», ни «материала нет», ни исчерпание ёмкости ею не являются — первое есть вход человека, второе законное состояние личности, третье нагрузка.
func (Outcome) IsTerminal ¶
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) 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 ¶
New — проверяющий с объявленной ёмкостью и приёмником исходов.
Оба довода обязательны: ёмкость без умолчания (PWV-15), приёмник — потому что мягкий проход законен только пока он слышен, а проверяющий без счётчиков молчит обо всех шести отказах разом.
func (*Verifier) Aligned ¶
Aligned отвечает, выровнена ли полоса «материала нет»: стоит ли выравнивающее значение (SetDecoy). Вызывающий, чей контракт требует, чтобы отказ по отсутствию материала стоил столько же, сколько отказ по несовпадению, спрашивает это при сборке, а не узнаёт по времени ответа.
func (*Verifier) Capacity ¶
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 ¶
MeetsDeclared — отвечает ли хранимое значение объявленному формату и объявленным параметрам (PWV-11, строки 11.2 и 11.4).
«Объявленный формат» и «объявленные параметры» — ОДНО требование: значение объявленного формата, у которого хотя бы один параметр ниже объявленного, отвечающим не считается, иначе оно осталось бы лежать навсегда.
Значение, которого продукт не читает, отвечает ОТКАЗОМ, а не «да» либо «нет»: молчаливое «отвечает» оставило бы его лежать, молчаливое «не отвечает» послало бы полосу входа переписывать неразобранное.
func (*Verifier) ProcessorSlots ¶ added in v0.6.0
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 ¶
WithCapacity исполняет работу, занимая одно место ёмкости; отвечает, удалось ли место занять. Нужен полосе входа Ф3 и пробам ёмкости.