asserts

package
v0.9.4 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: GPL-3.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MaxBodySize      = 2 * 1024 * 1024
	MaxHeadersSize   = 128 * 1024
	MaxSignatureSize = 128 * 1024
)

Maximum assertion component sizes.

View Source
const MediaType = "application/x.ubuntu.assertion"

MediaType is the media type for encoded assertions on the wire.

View Source
const RevisionNotKnown = -1

Variables

View Source
var (
	AlwaysMatchAttributes = &AttributeConstraints{matcher: fixedAttrMatcher{nil}}
	NeverMatchAttributes  = &AttributeConstraints{matcher: fixedAttrMatcher{errors.New("not allowed")}}
)
View Source
var (
	BaseDeclarationType = &AssertionType{"base-declaration", []string{"series"}, nil, assembleBaseDeclaration, 0}
)

Understood assertion types.

View Source
var MetaHeaders = [...]string{
	"type",
	"format",
	"authority-id",
	"revision",
	"body-length",
	"sign-key-sha3-384",
}

MetaHeaders is a list of headers in assertions which are about the assertion itself.

Functions

func Encode

func Encode(assert Assertion) []byte

Encode serializes an assertion.

func HeadersFromPrimaryKey

func HeadersFromPrimaryKey(assertType *AssertionType, primaryKey []string) (headers map[string]string, err error)

HeadersFromPrimaryKey constructs a headers mapping from the primaryKey values and the assertion type, it errors if primaryKey does not cover all the non-optional primary key headers or provides too many values.

func HeadersFromSequenceKey

func HeadersFromSequenceKey(assertType *AssertionType, sequenceKey []string) (headers map[string]string, err error)

HeadersFromSequenceKey constructs a headers mapping from the sequenceKey values and the sequence forming assertion type, it errors if sequenceKey has the wrong length; the length must be one less than the primary key of the given assertion type.

func InitBuiltinBaseDeclaration

func InitBuiltinBaseDeclaration(headers []byte) error

InitBuiltinBaseDeclaration initializes the builtin base-declaration based on headers (or resets it if headers is nil).

func MockOptionalPrimaryKey

func MockOptionalPrimaryKey(assertType *AssertionType, key, defaultValue string) (restore func())

func PrimaryKeyFromHeaders

func PrimaryKeyFromHeaders(assertType *AssertionType, headers map[string]string) (primaryKey []string, err error)

PrimaryKeyFromHeaders extracts the tuple of values from headers corresponding to a primary key under the assertion type, it errors if there are missing primary key headers unless they are optional in which case it fills in their default values.

func ReducePrimaryKey

func ReducePrimaryKey(assertType *AssertionType, primaryKey []string) []string

ReducePrimaryKey produces a primary key prefix by omitting any suffix of optional primary key headers default values. Too short or long primary keys are returned as is.

func TypeNames

func TypeNames() []string

TypeNames returns a sorted list of known assertion type names.

Types

type Assertion

type Assertion interface {
	// Type returns the type of this assertion
	Type() *AssertionType
	// Format returns the format iteration of this assertion
	Format() int
	// SupportedFormat returns whether the assertion uses a supported
	// format iteration. If false the assertion might have been only
	// partially parsed.
	SupportedFormat() bool
	// Revision returns the revision of this assertion
	Revision() int
	// AuthorityID returns the authority responsible for this
	// assertion
	AuthorityID() string

	// Header retrieves the header with name
	Header(name string) any

	// Headers returns the complete headers
	Headers() map[string]any

	// HeaderString retrieves the string value of header with name or ""
	HeaderString(name string) string

	// Body returns the body of this assertion
	Body() []byte

	// Signature returns the signed content and its unprocessed signature
	Signature() (content, signature []byte)

	// SignKeyID returns the key id for the key that signed this assertion.
	SignKeyID() string

	// Prerequisites returns references to the prerequisite assertions for the validity of this one.
	Prerequisites() []*Ref

	// Ref returns a reference representing this assertion.
	Ref() *Ref

	// At returns an AtRevision referencing this assertion at its revision.
	At() *AtRevision
}

Assertion represents an assertion through its general elements.

func Assemble

func Assemble(headers map[string]any, body, content, signature []byte) (Assertion, error)

Assemble assembles an assertion from its components.

func Decode

func Decode(serializedAssertion []byte) (Assertion, error)

Decode parses a serialized assertion.

The expected serialisation format looks like:

HEADER ("\n\n" BODY?)? "\n\n" SIGNATURE

where:

HEADER is a set of header entries separated by "\n"
BODY can be arbitrary text,
SIGNATURE is the signature

Both BODY and HEADER must be UTF8.

A header entry for a single line value (no '\n' in it) looks like:

NAME ": " SIMPLEVALUE

The format supports multiline text values (with '\n's in them) and lists or maps, possibly nested, with string scalars in them.

For those a header entry looks like:

NAME ":\n" MULTI(baseindent)

where MULTI can be

* (baseindent + 4)-space indented value (multiline text)

* entries of a list each of the form:

" "*baseindent "  -"  ( " " SIMPLEVALUE | "\n" MULTI )

* entries of map each of the form:

" "*baseindent "  " NAME ":"  ( " " SIMPLEVALUE | "\n" MULTI )

baseindent starts at 0 and then grows with nesting matching the previous level introduction (e.g. the " "*baseindent " -" bit) length minus 1.

In general the following headers are mandatory:

type
authority-id (except for on the wire/self-signed assertions like serial-request)

Further for a given assertion type all the primary key headers must be non empty and must not contain '/'.

The following headers expect string representing integer values and if omitted otherwise are assumed to be 0:

revision (a positive int)
body-length (expected to be equal to the length of BODY)
format (a positive int for the format iteration of the type used)

Times are expected to be in the RFC3339 format: "2006-01-02T15:04:05Z07:00".

type AssertionType

type AssertionType struct {
	// Name of the type.
	Name string
	// PrimaryKey holds the names of the headers that constitute the
	// unique primary key for this assertion type.
	PrimaryKey []string
	// OptionalPrimaryKeyDefaults holds the default values for
	// optional primary key headers.
	// Optional primary key headers can be added to types defined
	// in previous versions of workshopd, as long as they are added at
	// the end of the old primary key together with a default value set in
	// this map. So they must form a contiguous suffix of PrimaryKey with
	// each member having a default value set in this map.
	// Optional primary key headers are not supported for sequence
	// forming types.
	OptionalPrimaryKeyDefaults map[string]string
	// contains filtered or unexported fields
}

AssertionType describes a known assertion type with its name and metadata.

func Type

func Type(name string) *AssertionType

Type returns the AssertionType with name or nil

func (*AssertionType) AcceptablePrimaryKey

func (at *AssertionType) AcceptablePrimaryKey(key []string) bool

AcceptablePrimaryKey returns whether the given key could be an acceptable primary key for this type, allowing for the omission of optional primary key headers.

func (*AssertionType) MaxSupportedFormat

func (at *AssertionType) MaxSupportedFormat() int

MaxSupportedFormat returns the maximum supported format iteration for the type.

func (*AssertionType) SequenceForming

func (at *AssertionType) SequenceForming() bool

SequencingForming returns true if the assertion type has a positive integer >= 1 as the last component (preferably called "sequence") of its primary key over which the assertions of the type form sequences, usually without gaps, one sequence per sequence key (the primary key prefix omitting the sequence number). See SequenceMember.

type AtRevision

type AtRevision struct {
	Ref
	Revision int
}

AtRevision represents an assertion at a given revision, possibly not known (RevisionNotKnown).

func (*AtRevision) String

func (at *AtRevision) String() string

type AtSequence

type AtSequence struct {
	Type        *AssertionType
	SequenceKey []string
	Sequence    int
	Pinned      bool
	Revision    int
}

AtSequence references a sequence forming assertion at a given sequence point, possibly <=0 (meaning not specified) and revision, possibly not known (RevisionNotKnown). Setting Pinned = true means pinning at the given sequence point (which must be set, i.e. > 0). Pinned sequence forming assertion will be updated to the latest revision at the specified sequence point.

func (*AtSequence) String

func (at *AtSequence) String() string

func (*AtSequence) Unique

func (at *AtSequence) Unique() string

Unique returns a unique string representing the sequence by its sequence key that can be used as a key in maps.

type AttrMatchContext

type AttrMatchContext interface {
	PlugAttr(arg string) (any, error)
	SlotAttr(arg string) (any, error)
}

AttrMatchContext has contextual helpers for evaluating attribute constraints.

type Attrer

type Attrer interface {
	Lookup(path string) (any, bool)
}

Attrer reflects part of the Attrer interface (see interfaces.Attrer).

type AttributeConstraints

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

AttributeConstraints implements a set of constraints on the attributes of a slot or plug.

func (*AttributeConstraints) Check

func (c *AttributeConstraints) Check(attrer Attrer, helper AttrMatchContext) error

Check checks whether attrs don't match the constraints.

type BaseDeclaration

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

BaseDeclaration holds a base-declaration assertion, declaring the policies (to start with interface ones) applying to all sdks of a series.

func BuiltinBaseDeclaration

func BuiltinBaseDeclaration() *BaseDeclaration

BuiltinBaseDeclaration exposes the initialized builtin base-declaration assertion. This is used by overlord/assertstate, other code should use assertstate.BaseDeclaration.

func (*BaseDeclaration) At

func (ab *BaseDeclaration) At() *AtRevision

At returns an AtRevision referencing this assertion at its revision.

func (*BaseDeclaration) AuthorityID

func (ab *BaseDeclaration) AuthorityID() string

AuthorityID returns the authority-id a.k.a the authority responsible for the assertion.

func (*BaseDeclaration) Body

func (ab *BaseDeclaration) Body() []byte

Body returns the body of the assertion.

func (*BaseDeclaration) Format

func (ab *BaseDeclaration) Format() int

Format returns the assertion format iteration.

func (*BaseDeclaration) Header

func (ab *BaseDeclaration) Header(name string) any

Header returns the value of an header by name.

func (*BaseDeclaration) HeaderString

func (ab *BaseDeclaration) HeaderString(name string) string

HeaderString retrieves the string value of header with name or ""

func (*BaseDeclaration) Headers

func (ab *BaseDeclaration) Headers() map[string]any

Headers returns the complete headers.

func (*BaseDeclaration) PlugRule

func (basedcl *BaseDeclaration) PlugRule(interfaceName string) *PlugRule

PlugRule returns the plug-side rule about the given interface if one was included in the plugs stanza of the declaration, otherwise it returns nil.

func (*BaseDeclaration) Prerequisites

func (ab *BaseDeclaration) Prerequisites() []*Ref

Prerequisites returns references to the prerequisite assertions for the validity of this one.

func (*BaseDeclaration) Ref

func (ab *BaseDeclaration) Ref() *Ref

Ref returns a reference representing this assertion.

func (*BaseDeclaration) Revision

func (ab *BaseDeclaration) Revision() int

Revision returns the assertion revision.

func (*BaseDeclaration) Series

func (basedcl *BaseDeclaration) Series() string

Series returns the series whose sdks are governed by the declaration.

func (*BaseDeclaration) SignKeyID

func (ab *BaseDeclaration) SignKeyID() string

SignKeyID returns the key id for the key that signed this assertion.

func (*BaseDeclaration) Signature

func (ab *BaseDeclaration) Signature() (content, signature []byte)

Signature returns the signed content and its unprocessed signature.

func (*BaseDeclaration) SlotRule

func (basedcl *BaseDeclaration) SlotRule(interfaceName string) *SlotRule

SlotRule returns the slot-side rule about the given interface if one was included in the slots stanza of the declaration, otherwise it returns nil.

func (*BaseDeclaration) SupportedFormat

func (ab *BaseDeclaration) SupportedFormat() bool

SupportedFormat returns whether the assertion uses a supported format iteration. If false the assertion might have been only partially parsed.

func (*BaseDeclaration) Timestamp

func (basedcl *BaseDeclaration) Timestamp() time.Time

Timestamp returns the time when the base-declaration was issued.

func (*BaseDeclaration) Type

func (ab *BaseDeclaration) Type() *AssertionType

Type returns the assertion type.

type Decoder

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

Decoder parses a stream of assertions bundled by separating them with double newlines.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder returns a Decoder to parse the stream of assertions from the reader.

func NewDecoderWithTypeMaxBodySize

func NewDecoderWithTypeMaxBodySize(r io.Reader, typeMaxBodySize map[*AssertionType]int) *Decoder

NewDecoderWithTypeMaxBodySize returns a Decoder to parse the stream of assertions from the reader enforcing optional per type max body sizes or the default one as fallback.

func (*Decoder) Decode

func (d *Decoder) Decode() (Assertion, error)

Decode parses the next assertion from the stream. It returns the error io.EOF at the end of a well-formed stream.

type Encoder

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

Encoder emits a stream of assertions bundled by separating them with double newlines.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns a Encoder to emit a stream of assertions to a writer.

func (*Encoder) Encode

func (enc *Encoder) Encode(assert Assertion) error

Encode emits the assertion into the stream with the required separator. Errors here are always about writing given that Encode() itself cannot error.

func (*Encoder) WriteContentSignature

func (enc *Encoder) WriteContentSignature(content, signature []byte) error

WriteContentSignature writes the content and signature of an assertion into the stream with all the required separators.

func (*Encoder) WriteEncoded

func (enc *Encoder) WriteEncoded(encoded []byte) error

WriteEncoded writes the encoded assertion into the stream with the required separator.

type NameConstraints

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

NameConstraints implements a set of constraints on the names of slots or plugs. See https://forum.snapcraft.io/t/plug-slot-rules-plug-names-slot-names-constraints/12439

func (*NameConstraints) Check

func (nc *NameConstraints) Check(whichName, name string, special map[string]string) error

Check checks whether name doesn't match the constraints.

type PlugConnectionConstraints

type PlugConnectionConstraints struct {
	PlugSdkTypes []string
	SlotSdkTypes []string

	PlugNames *NameConstraints
	SlotNames *NameConstraints

	PlugAttributes *AttributeConstraints
	SlotAttributes *AttributeConstraints

	// SlotsPerPlug defaults to 1 for auto-connection, can be * (any)
	SlotsPerPlug SideArityConstraint
	// PlugsPerSlot is always * (any) (for now)
	PlugsPerSlot SideArityConstraint
}

PlugConnectionConstraints specifies a set of constraints on an interface plug for a snap relevant to its connection or auto-connection.

type PlugInstallationConstraints

type PlugInstallationConstraints struct {
	PlugSdkTypes []string

	PlugNames *NameConstraints

	PlugAttributes *AttributeConstraints
}

PlugInstallationConstraints specifies a set of constraints on an interface plug relevant to the installation of snap.

type PlugRule

type PlugRule struct {
	Interface string

	AllowInstallation []*PlugInstallationConstraints
	DenyInstallation  []*PlugInstallationConstraints

	AllowConnection []*PlugConnectionConstraints
	DenyConnection  []*PlugConnectionConstraints

	AllowAutoConnection []*PlugConnectionConstraints
	DenyAutoConnection  []*PlugConnectionConstraints
}

PlugRule holds the rule of what is allowed, wrt installation and connection, for a plug of a specific interface for a sdk.

type Ref

type Ref struct {
	Type       *AssertionType
	PrimaryKey []string
}

Ref expresses a reference to an assertion.

func (*Ref) Resolve

func (ref *Ref) Resolve(find func(assertType *AssertionType, headers map[string]string) (Assertion, error)) (Assertion, error)

Resolve resolves the reference using the given find function.

func (*Ref) String

func (ref *Ref) String() string

func (*Ref) Unique

func (ref *Ref) Unique() string

Unique returns a unique string representing the reference that can be used as a key in maps.

type SequenceMember

type SequenceMember interface {
	Assertion

	// Sequence returns the sequence number of this assertion.
	Sequence() int
}

SequenceMember is implemented by assertions of sequence forming types.

type SideArityConstraint

type SideArityConstraint struct {
	// N can be:
	// =>1
	// 0 means default and is used only internally during rule
	// compilation or on deny- rules where these constraints are
	// not applicable
	// -1 represents *, that means any (number of)
	N int
}

SideArityConstraint specifies a constraint for the overall arity of the set of connected slots for a given plug or the set of connected plugs for a given slot. It is used to express parsed slots-per-plug and plugs-per-slot constraints. See https://forum.snapcraft.io/t/plug-slot-declaration-rules-greedy-plugs/12438

func (SideArityConstraint) Any

func (ac SideArityConstraint) Any() bool

Any returns whether this represents the * (any number of) constraint.

type SlotConnectionConstraints

type SlotConnectionConstraints struct {
	SlotSdkTypes []string
	PlugSdkTypes []string

	SlotNames *NameConstraints
	PlugNames *NameConstraints

	SlotAttributes *AttributeConstraints
	PlugAttributes *AttributeConstraints

	// SlotsPerPlug defaults to 1 for auto-connection, can be * (any)
	SlotsPerPlug SideArityConstraint
	// PlugsPerSlot is always * (any) (for now)
	PlugsPerSlot SideArityConstraint
}

SlotConnectionConstraints specifies a set of constraints on an interface slot for a sdk relevant to its connection or auto-connection.

type SlotInstallationConstraints

type SlotInstallationConstraints struct {
	SlotSdkTypes   []string
	SlotAttributes *AttributeConstraints
	SlotNames      *NameConstraints
}

SlotInstallationConstraints specifies a set of constraints on an interface slot relevant to the installation of SDK.

type SlotRule

type SlotRule struct {
	Interface string

	AllowInstallation []*SlotInstallationConstraints
	DenyInstallation  []*SlotInstallationConstraints

	AllowConnection []*SlotConnectionConstraints
	DenyConnection  []*SlotConnectionConstraints

	AllowAutoConnection []*SlotConnectionConstraints
	DenyAutoConnection  []*SlotConnectionConstraints
}

SlotRule holds the rule of what is allowed, wrt installation and connection, for a slot of a specific interface for a SDK.

Jump to

Keyboard shortcuts

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