You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
4.6 KiB
92 lines
4.6 KiB
// Package datekeys is the reference Go implementation of the DateKeys Protocol
|
|
// Specification v0.8.1 (spec/DateKeys_Protocol_Specification_v0.8.1.md).
|
|
//
|
|
// The protocol objects live in subpackages:
|
|
//
|
|
// - datekey: DateKey resolution and the canonical dk1_ form (spec §14-§19).
|
|
// - profile: Provider Profiles and the pinned Quicknet profile (spec §10-§13).
|
|
// - provider, provider/drand: release sources and local BLS verification (spec §45-§52).
|
|
// - capsule: the DateKeyCap .dkc container (spec §20-§39, §61-§63).
|
|
// - accesskey: the DateKeys Access Key .dkk credential (spec §40-§44).
|
|
// - extension: the generic extension mechanism (spec §54).
|
|
//
|
|
// This package holds the normative error catalogue of spec §69. Every protocol
|
|
// failure returned by this module wraps exactly one of these sentinels, so
|
|
// callers can match them with [errors.Is] and extract the code with [Code].
|
|
package datekeys
|
|
|
|
import "errors"
|
|
|
|
// Error is a normative DateKeys error (spec §69). Values are compared by
|
|
// identity; use [errors.Is] against the exported sentinels.
|
|
type Error struct {
|
|
code string
|
|
}
|
|
|
|
// Error returns the normative code, for example "ERR_INVALID_MAGIC".
|
|
func (e *Error) Error() string { return e.code }
|
|
|
|
// Code returns the normative code, for example "ERR_INVALID_MAGIC".
|
|
func (e *Error) Code() string { return e.code }
|
|
|
|
// Normative errors, spec §69.
|
|
var (
|
|
// ErrInvalidMagic: the object does not start with DKC1 or DKK1 (spec §22, §40).
|
|
ErrInvalidMagic = &Error{"ERR_INVALID_MAGIC"}
|
|
// ErrUnsupportedVersion: an unknown framing or schema version (spec §22, §70).
|
|
ErrUnsupportedVersion = &Error{"ERR_UNSUPPORTED_VERSION"}
|
|
// ErrInvalidFlags: FLAGS or RESERVED are not zero (spec §22, §40).
|
|
ErrInvalidFlags = &Error{"ERR_INVALID_FLAGS"}
|
|
// ErrNonCanonicalCBOR: the bytes are not the unique deterministic CBOR
|
|
// encoding of a valid instance of the normative schema (spec §58, §58.1).
|
|
ErrNonCanonicalCBOR = &Error{"ERR_NON_CANONICAL_CBOR"}
|
|
// ErrUnknownProfile: the DateKey names a profile that is not pinned locally (spec §13).
|
|
ErrUnknownProfile = &Error{"ERR_UNKNOWN_PROFILE"}
|
|
// ErrProfileMismatch: a chain hash or profile does not match the pinned profile (spec §35, §63).
|
|
ErrProfileMismatch = &Error{"ERR_PROFILE_MISMATCH"}
|
|
// ErrDateKeyInvalid: a DateKey that cannot be decoded or validated (spec §18, §19).
|
|
ErrDateKeyInvalid = &Error{"ERR_DATEKEY_INVALID"}
|
|
// ErrDateKeyNonCanonical: a valid DateKey in a non-canonical encoding (spec §19).
|
|
ErrDateKeyNonCanonical = &Error{"ERR_DATEKEY_NON_CANONICAL"}
|
|
// ErrRoundMismatch: a round that differs from the locally resolved one (spec §17, §63).
|
|
ErrRoundMismatch = &Error{"ERR_ROUND_MISMATCH"}
|
|
// ErrReleaseUnavailable: the release is not published yet or no source delivered it (spec §45-§50).
|
|
ErrReleaseUnavailable = &Error{"ERR_RELEASE_UNAVAILABLE"}
|
|
// ErrReleaseInvalid: a release that fails local verification (spec §51).
|
|
ErrReleaseInvalid = &Error{"ERR_RELEASE_INVALID"}
|
|
// ErrAccessRequired: the policy requires an access credential and none was supplied (spec §33).
|
|
ErrAccessRequired = &Error{"ERR_ACCESS_REQUIRED"}
|
|
// ErrAccessInvalid: the supplied credentials do not open this capsule (spec §33, §38).
|
|
ErrAccessInvalid = &Error{"ERR_ACCESS_INVALID"}
|
|
// ErrPolicyStructureMismatch: the cryptographic structure does not match the
|
|
// declared access policy or the stanza rules of V1 (spec §25, §29, §32, §33, §36).
|
|
ErrPolicyStructureMismatch = &Error{"ERR_POLICY_STRUCTURE_MISMATCH"}
|
|
// ErrHeaderBinding: header_binding does not match PRELUDE || PUBLIC_HEADER (spec §26).
|
|
ErrHeaderBinding = &Error{"ERR_HEADER_BINDING"}
|
|
// ErrIntegrity: truncation, corruption or failed authentication of framing or age data (spec §4, §55).
|
|
ErrIntegrity = &Error{"ERR_INTEGRITY"}
|
|
// ErrExtensionCriticalUnknown: a critical extension this implementation does not know (spec §54).
|
|
ErrExtensionCriticalUnknown = &Error{"ERR_EXTENSION_CRITICAL_UNKNOWN"}
|
|
)
|
|
|
|
// All returns every normative error in the order of spec §69.
|
|
func All() []*Error {
|
|
return []*Error{
|
|
ErrInvalidMagic, ErrUnsupportedVersion, ErrInvalidFlags, ErrNonCanonicalCBOR,
|
|
ErrUnknownProfile, ErrProfileMismatch, ErrDateKeyInvalid, ErrDateKeyNonCanonical,
|
|
ErrRoundMismatch, ErrReleaseUnavailable, ErrReleaseInvalid, ErrAccessRequired,
|
|
ErrAccessInvalid, ErrPolicyStructureMismatch, ErrHeaderBinding, ErrIntegrity,
|
|
ErrExtensionCriticalUnknown,
|
|
}
|
|
}
|
|
|
|
// Code returns the normative code of the first DateKeys error in err's tree,
|
|
// or "" if err does not wrap one.
|
|
func Code(err error) string {
|
|
var e *Error
|
|
if errors.As(err, &e) {
|
|
return e.code
|
|
}
|
|
return ""
|
|
}
|