Documentation
¶
Overview ¶
Package metaserver implements the canonical HTTP Message Signature profile used by Atrinik metaserver publishers. It constructs and verifies the signed bytes; HTTP clients and servers remain responsible for strict field parsing, request limits, replay state, and publication authorization.
Index ¶
- Constants
- Variables
- func DirectoryETag(snapshot *metaserverv1.DirectorySnapshot) (string, error)
- func DirectoryFreshAt(snapshot *metaserverv1.DirectorySnapshot, now uint64) bool
- func DirectoryJSONSHA256(snapshot *metaserverv1.DirectorySnapshot) (string, error)
- func DirectoryServerCompatible(server *metaserverv1.DirectoryServer, protocolMajor uint32, ...) bool
- func MarshalDirectoryJSON(snapshot *metaserverv1.DirectorySnapshot) ([]byte, error)
- func MarshalGamePublishJSON(request *GamePublishRequest) ([]byte, error)
- func ParseDirectoryJSON(input []byte) (*metaserverv1.DirectorySnapshot, error)
- func Sign(privateKey *ecdsa.PrivateKey, signatureBase string) ([]byte, error)
- func ValidDirectoryStrongETag(value string) bool
- func ValidateDirectory(snapshot *metaserverv1.DirectorySnapshot) error
- func ValidateGamePublish(request *GamePublishRequest) error
- func VerifyCertificateSignature(certificateDER []byte, serverID string, signatureBase string, signature []byte) error
- type Components
- type DirectoryError
- type DirectoryErrorCode
- type GamePublishError
- type GamePublishErrorCode
- type GamePublishRequest
- type Parameters
- type Profile
Constants ¶
const ( DirectorySchema = "atrinik-directory-v1" MaximumDirectoryBodyBytes = 262_144 MaximumDirectoryServers = 512 MaximumDirectoryLifetimeSeconds = 14_400 MaximumDirectoryFutureSkew = 300 MaximumDirectoryUnixSeconds = 253_402_300_799 MaximumDirectoryNameBytes = 80 MaximumDirectoryDescriptionBytes = 512 MaximumDirectoryRegionBytes = 32 MaximumDirectoryContentIDBytes = 64 MaximumDirectoryPlayers = 100_000 MaximumDirectoryETagBytes = 128 )
const ( SignatureLabel = "atrinik" SignatureAlgorithm = "ecdsa-p256-sha256" ContentType = "application/json" MaximumBodyBytes = 4096 MaximumCertificateDERBytes = 2048 MaximumClockSkew = 300 ClassicSignatureTag = "atrinik-classic-publish-v1" GameSignatureTag = "atrinik-game-publish-v1" SignatureValidity = MaximumClockSkew )
const GamePublishSchema = "atrinik-game-publish-v1"
Variables ¶
Functions ¶
func DirectoryETag ¶ added in v1.2.0
func DirectoryETag(snapshot *metaserverv1.DirectorySnapshot) (string, error)
DirectoryETag retains the former application-derived label for source compatibility. Deprecated: HTTP origins select an opaque strong ETag; consumers must not require this value on the wire.
func DirectoryFreshAt ¶ added in v1.2.0
func DirectoryFreshAt(snapshot *metaserverv1.DirectorySnapshot, now uint64) bool
DirectoryFreshAt reports whether a previously validated snapshot is fresh at now. It fails closed for nil or structurally invalid snapshots.
func DirectoryJSONSHA256 ¶ added in v1.5.3
func DirectoryJSONSHA256(snapshot *metaserverv1.DirectorySnapshot) (string, error)
DirectoryJSONSHA256 returns lowercase SHA-256 of canonical JSON bytes, including their final LF. It is a body-integrity value, not an HTTP ETag.
func DirectoryServerCompatible ¶ added in v1.2.0
func DirectoryServerCompatible( server *metaserverv1.DirectoryServer, protocolMajor uint32, protocolMinor uint32, contentID string, contentRevisionSHA256 []byte, ) bool
DirectoryServerCompatible applies the exact GP1/content filter. Invalid server models never match.
func MarshalDirectoryJSON ¶ added in v1.2.0
func MarshalDirectoryJSON(snapshot *metaserverv1.DirectorySnapshot) ([]byte, error)
MarshalDirectoryJSON validates and renders a snapshot as canonical bytes. The returned allocation is owned by the caller and always ends in one LF.
func MarshalGamePublishJSON ¶ added in v1.3.0
func MarshalGamePublishJSON(request *GamePublishRequest) ([]byte, error)
MarshalGamePublishJSON validates and renders one canonical GP1 publisher body. The returned allocation has no trailing LF or insignificant bytes.
func ParseDirectoryJSON ¶ added in v1.2.0
func ParseDirectoryJSON(input []byte) (*metaserverv1.DirectorySnapshot, error)
ParseDirectoryJSON validates one complete canonical JSON snapshot. Failure returns no partial model and does not mutate caller-owned state.
func Sign ¶
func Sign(privateKey *ecdsa.PrivateKey, signatureBase string) ([]byte, error)
Sign signs a canonical signature base and returns the RFC 9421 P-256 signature encoding: unsigned, zero-padded r followed by s.
func ValidDirectoryStrongETag ¶ added in v1.5.3
ValidDirectoryStrongETag reports whether value is the bounded opaque strong HTTP validator accepted by the directory contract.
func ValidateDirectory ¶ added in v1.2.0
func ValidateDirectory(snapshot *metaserverv1.DirectorySnapshot) error
ValidateDirectory enforces semantic bounds without reading a clock or retaining references. The snapshot remains caller-owned and mutable.
func ValidateGamePublish ¶ added in v1.3.0
func ValidateGamePublish(request *GamePublishRequest) error
ValidateGamePublish enforces semantic bounds, certificate identity, and the P-256 key requirement without consulting a clock or retaining references.
Types ¶
type Components ¶
type Components struct {
Path string
ContentDigest string
SignatureInput string
SignatureBase string
}
Components contains every canonical value needed to send or verify one signed request. SignatureBase intentionally excludes a trailing newline.
func Build ¶
func Build(parameters Parameters, body []byte) (Components, error)
Build constructs the strict Atrinik RFC 9421 and RFC 9530 profile for the exact body bytes. Callers must send those bytes unchanged.
type DirectoryError ¶ added in v1.2.0
type DirectoryError struct {
Code DirectoryErrorCode
}
DirectoryError reports only a stable class so malformed public input cannot enter diagnostics. Callers may compare Code or use DirectoryErrorCodeOf.
func (*DirectoryError) Error ¶ added in v1.2.0
func (err *DirectoryError) Error() string
type DirectoryErrorCode ¶ added in v1.2.0
type DirectoryErrorCode string
DirectoryErrorCode is a stable, bounded conformance failure class. It never contains input data.
const ( DirectoryInvalidJSON DirectoryErrorCode = "invalid_json" DirectoryNonCanonicalJSON DirectoryErrorCode = "noncanonical_json" DirectoryUnsupportedSchema DirectoryErrorCode = "unsupported_schema" DirectoryBodyTooLarge DirectoryErrorCode = "body_too_large" DirectoryTooManyServers DirectoryErrorCode = "too_many_servers" DirectoryInvalidGeneration DirectoryErrorCode = "invalid_generation" DirectoryInvalidFreshness DirectoryErrorCode = "invalid_freshness" DirectoryInvalidIdentity DirectoryErrorCode = "invalid_identity" DirectoryInvalidText DirectoryErrorCode = "invalid_text" DirectoryInvalidRegion DirectoryErrorCode = "invalid_region" DirectoryInvalidProtocol DirectoryErrorCode = "invalid_protocol" DirectoryInvalidContent DirectoryErrorCode = "invalid_content" DirectoryInvalidPlayers DirectoryErrorCode = "invalid_players" DirectoryInvalidStatus DirectoryErrorCode = "invalid_status" DirectoryInvalidEndpoint DirectoryErrorCode = "invalid_endpoint" DirectoryUnorderedServers DirectoryErrorCode = "unordered_servers" )
func DirectoryErrorCodeOf ¶ added in v1.2.0
func DirectoryErrorCodeOf(err error) (DirectoryErrorCode, bool)
DirectoryErrorCodeOf returns a bounded error class and false for unrelated errors.
type GamePublishError ¶ added in v1.3.0
type GamePublishError struct {
Code GamePublishErrorCode
}
GamePublishError reports only a stable class so malformed authenticated input cannot enter diagnostics.
func (*GamePublishError) Error ¶ added in v1.3.0
func (err *GamePublishError) Error() string
type GamePublishErrorCode ¶ added in v1.3.0
type GamePublishErrorCode string
GamePublishErrorCode is a stable, bounded conformance failure class. It never contains rejected input.
const ( GamePublishInvalidJSON GamePublishErrorCode = "invalid_json" GamePublishNonCanonicalJSON GamePublishErrorCode = "noncanonical_json" GamePublishUnsupportedSchema GamePublishErrorCode = "unsupported_schema" GamePublishBodyTooLarge GamePublishErrorCode = "body_too_large" GamePublishInvalidIdentity GamePublishErrorCode = "invalid_identity" GamePublishInvalidCertificate GamePublishErrorCode = "invalid_certificate" GamePublishInvalidText GamePublishErrorCode = "invalid_text" GamePublishInvalidRegion GamePublishErrorCode = "invalid_region" GamePublishInvalidProtocol GamePublishErrorCode = "invalid_protocol" GamePublishInvalidContent GamePublishErrorCode = "invalid_content" GamePublishInvalidPlayers GamePublishErrorCode = "invalid_players" GamePublishInvalidStatus GamePublishErrorCode = "invalid_status" GamePublishInvalidEndpoint GamePublishErrorCode = "invalid_endpoint" )
func GamePublishErrorCodeOf ¶ added in v1.3.0
func GamePublishErrorCodeOf(err error) (GamePublishErrorCode, bool)
GamePublishErrorCodeOf returns a bounded error class and false for unrelated errors.
type GamePublishRequest ¶ added in v1.3.0
type GamePublishRequest struct {
CertificateDER []byte
Server *metaserverv1.DirectoryServer
Public bool
}
GamePublishRequest is one authenticated GP1 publication body after strict canonical JSON validation. CertificateDER and Server remain caller-owned when passed to MarshalGamePublishJSON; ParseGamePublishJSON returns new allocations owned by the caller.
func ParseGamePublishJSON ¶ added in v1.3.0
func ParseGamePublishJSON(input []byte) (*GamePublishRequest, error)
ParseGamePublishJSON validates one complete canonical GP1 publisher body. Failure returns no partial model and does not mutate caller-owned state.