metadata

package
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2024 License: BSD-2-Clause Imports: 19 Imported by: 4

Documentation

Overview

Package metadata provides certificate transparency log and operator metadata. The used format is based on Google's v3 schema and related documentation:

The goal is to have exported types that are easy to (un)marshal correctly, notably including not having to do further parsing after unmarshalling. The enforced value contraints are thoroughly documented in each type description.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Email

type Email string

Email is an item in the "email" array.

The following value constraints are enforced while (un)marshalling:

  • Valid according to the JSON Schema "email" format (Draft-07). TODO: fixme, the current implementation only checks that there's at least one "@".

func (*Email) MarshalJSON

func (e *Email) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "email" string

func (*Email) UnmarshalJSON

func (e *Email) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals an item in the "email" array

type ErrLoad

type ErrLoad struct {
	ReadMetadata      bool
	ReadSignature     bool
	VerifiedSignature bool

	Message   []byte // Available if ReadMetadata is true
	Signature []byte // Available if ReadSignature is true
	GotError  error  // The error that caused Load() to stop
}

ErrLoad is an error while loading a signed metadata object. If reading and signature verification succeeded, the cause of the error is unmarshalling.

func (ErrLoad) Error

func (e ErrLoad) Error() string

Error formats an error message as a string

type HTTPSource

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

HTTPSource implements the Load interface for signed metadata objects that are locatable via URLs. The following signature schemes are supported:

Use NewHTTPSource() to configure a new HTTP source with HTTPSourceOptions.

func NewHTTPSource

func NewHTTPSource(opts HTTPSourceOptions) HTTPSource

NewHTTPSource configures a new HTTP source based on the provided options

func (*HTTPSource) Load

func (s *HTTPSource) Load(ctx context.Context) ([]byte, []byte, Metadata, error)

Load implements the Loader interface

type HTTPSourceOptions

type HTTPSourceOptions struct {
	PublicKey    crypto.PublicKey
	MetadataURL  string
	SignatureURL string

	// Name is an optional name of a hardcoded parameter set that overrides
	// any specified public key, metadata URL, and signature URL.
	//
	// The supported parameter sets are: "google".
	Name string

	// UserAgent is an optional HTTP user agent (Default: ctio.HTTPUserAgent)
	UserAgent string

	// Timeout is an optional HTTP request timeout (Default: ctio.HTTPTimeout)
	Timeout time.Duration

	// Client is an optional HTTP client (Default: http.Client{})
	Client http.Client
}

HTTPSourceOptions are options to configure an HTTP source

type Loader

type Loader interface {
	// Load loads a signed metadata object from a source.  The raw metadata
	// and signature are returned so that they may be persisted.  A non-nil
	// error requires successful signature verification and unmarshalling.
	Load(ctx context.Context) ([]byte, []byte, Metadata, error)
}

Loader is an interface that wraps the Load method. Implementations of this interface must configure a public key as well as a location of the signed metadata object. Examples of locations include web URLs and system files.

type Log

type Log struct {
	Key LogKey
	MMD LogMMD
	URL LogURL

	// Optional
	Description *string
	Type        *LogType
	Shard       *LogShard
	State       *LogState
	History     *[]PreviousOperator
	DNS         *LogDNSName
}

Log is an item in the "logs" array.

The following value constraints are enforced while (un)marshalling:

  • Log ID is a hash of the public key (RFC 6962, §3.2)
  • Previous operator items are unique
  • All nested types are valid if present, see separate type documentation

func (*Log) MarshalJSON

func (l *Log) MarshalJSON() ([]byte, error)

MarshalJSON marshals an item in the "logs" array

func (*Log) UnmarshalJSON

func (l *Log) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals an item in the "logs" array

type LogDNSName

type LogDNSName string

LogDNSName implements the "dns" string.

The following value constraints are enforced while (un)marshalling:

  • Valid according to the JSON Schema "hostname" format (Draft-07). TODO: fixme, the current implementation only enforces that the string is non-empty.

func (*LogDNSName) MarshalJSON

func (n *LogDNSName) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "dns" string

func (*LogDNSName) UnmarshalJSON

func (n *LogDNSName) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the "dns" string

type LogKey

type LogKey struct {
	Public crypto.PublicKey
}

LogKey implements the the "key" string.

The following value constraints are enforced while (un)marshalling:

  • Base64-encoded DER-encoded SubjectPublicKeyInfo (RFC 5280, §4.1.2.7)
  • Public key is ECDSA P-256 or RSA >=2048 bits (RFC 6962, §2.1.4)

func (*LogKey) ID

func (k *LogKey) ID() ([sha256.Size]byte, error)

ID outputs a key ID which is also the log's ID (RFC 6962, §3.2)

func (*LogKey) MarshalJSON

func (k *LogKey) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "key" string

func (*LogKey) UnmarshalJSON

func (k *LogKey) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals the "key" string

type LogMMD

type LogMMD uint64

LogMMD implements the "mmd" number.

The following value constraints are enforced while (un)marshalling:

  • Number is larger than zero
  • If no "mmd" key is provided, default to 24h

func (*LogMMD) MarshalJSON

func (m *LogMMD) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "mmd" number

func (*LogMMD) UnmarshalJSON

func (m *LogMMD) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the "mmd" number

type LogShard

type LogShard struct {
	Start time.Time
	End   time.Time
}

LogShard implements the "temporal_interval" object.

The following value constraints are enforced while (un)marshalling:

  • Start is non-zero on "date-time" JSON Schema format (Draft-07)
  • End is non-zero on "date-time" JSON Schema format (Draft-07)
  • Start must be before end because the expressed interval is [start, end)

func (*LogShard) MarshalJSON

func (s *LogShard) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "temporal_interval" object

func (*LogShard) UnmarshalJSON

func (s *LogShard) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON umarshals the "temporal_interval" object

type LogState

type LogState struct {
	Name      LogStateName
	EnteredAt time.Time

	// Available in the read-only state
	ReadOnlySize     uint64
	ReadOnlyRootHash [sha256.Size]byte
}

LogState implements the "state" object.

The following value constraints are enforced while (un)marshalling:

  • Must have exactly one named state which is known
  • EnteredAt is non-zero on "date-time" JSON Schema format (Draft-07)
  • The read-only state also has a tree head which contains a size >= zero as well as a root hash which is exactly 44 characters long
  • The root hash is in base64 (undocumented but evident from real metadata)
  • A size of zero requires that the root hash is SHA256(""), and all other sizes require a different root hash (RFC 6962, §2.1)

func (*LogState) MarshalJSON

func (s *LogState) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "state" object

func (*LogState) UnmarshalJSON

func (s *LogState) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals the "state" object

type LogStateName

type LogStateName int

LogStateName is the name of a log state in the Google Chrome life cycle, see: https://googlechrome.github.io/CertificateTransparency/log_states.html

const (
	LogStatePending LogStateName = iota + 1
	LogStateQualified
	LogStateUsable
	LogStateReadOnly
	LogStateRetired
	LogStateRejected
)

Of note is that the pending state can reach all other states; the qualified state can reach all but the pending state; the usable state can reach all but the pending and qualified states; ...; and the rejected state is a sink.

func (*LogStateName) ValidFrom

func (n *LogStateName) ValidFrom(another LogStateName) error

ValidFrom checks if a named state is a valid transition from another one

type LogType

type LogType string

LogType implements the "log_type" string.

The following value constraints are enforced while (un)marshalling:

  • Is a valid string enumeration
const (
	LogTypeTest LogType = "test"
	LogTypeProd LogType = "prod"
)

The supported log types are test and production

func (*LogType) MarshalJSON

func (t *LogType) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "log_type" string

func (*LogType) UnmarshalJSON

func (t *LogType) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the "log_type" string

type LogURL

type LogURL string

LogURL implements the "url" string.

The following value constraints are enforced while (un)marshalling:

  • Valid according to the JSON Schema "uri" format (Draft-07)
  • Is a base URL (a good definition is available in RFC 9162, §4.1)

The current implementation only enforces that the specified base URL is on the format "https://<str>/" for any non-empty <str> (TODO: fixme). A proper implementation should require that <str> is a server prefix on the format "<hostname>[:<port>][<path>]". Further details can be found in RFC 6962.

func (*LogURL) MarshalJSON

func (u *LogURL) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "url" string

func (*LogURL) UnmarshalJSON

func (u *LogURL) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the "url" string

type Metadata

type Metadata struct {
	Version   Version
	CreatedAt time.Time
	Operators []Operator
}

Metadata is a versioned and timestamped metadata object that contains information about operators and their certificate transparency logs.

The following value constraints are enforced while (un)marshalling:

  • CreatedAt is non-zero on "date-time" JSON Schema format (Draft-07)
  • Operators are required on the wire (but may be [])
  • Operator names are unique (criteria added by this package)
  • Log public keys are unique (RFC 9162, §4.1)
  • Log URLs are unique (criteria added by this package)
  • All nested types are valid, see separate type documentation

func (*Metadata) MarshalJSON

func (m *Metadata) MarshalJSON() ([]byte, error)

MarshalJSON marshals the top-most metadata object

func (*Metadata) UnmarshalJSON

func (m *Metadata) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals the top-most metadata object

type Operator

type Operator struct {
	Name   string
	Emails []Email
	Logs   []Log
}

Operator is an item in the "operators" array.

The following value constraints are enforced while (un)marshalling:

  • Name is required on the wire (but may be "")
  • At least one email address is provided
  • There are no duplicate email addresses
  • Logs are required on the wire (but may be [])
  • Log public keys are unique (RFC 9162, §4.1)
  • Log URLs are unique (criteria added by this package)
  • All nested types are valid, see separate type documentation

func (*Operator) MarshalJSON

func (o *Operator) MarshalJSON() ([]byte, error)

MarshalJSON marshals an item in the "operators" array

func (*Operator) UnmarshalJSON

func (o *Operator) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals an item in the "operators" array

type PreviousOperator

type PreviousOperator struct {
	Name string
	End  time.Time
}

PreviousOperator is an item in the "previous_operator" array.

The following value constraints are enforced while (un)marshalling:

  • Name is required on the wire (but may be "")
  • End is non-zero on "date-time" JSON Schema format (Draft-07)

func (*PreviousOperator) MarshalJSON

func (o *PreviousOperator) MarshalJSON() ([]byte, error)

MarshalJSON marshals an item in the "previous_operators" array

func (*PreviousOperator) UnmarshalJSON

func (o *PreviousOperator) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON unmarshals an item in the "previous_operators" array

type Version

type Version struct {
	Major uint64
	Minor uint64
}

Version implements the "version" string. Note that this is the metadata content version, i.e., not the version of the metadata format which is v3.

The following value constraints are enforced while (un)marshalling:

The current implementation parses <major> and <minor> with a strconv. This is not the same parser as the JSON type "number" (TODO: fixme).

func (*Version) MarshalJSON

func (v *Version) MarshalJSON() ([]byte, error)

MarshalJSON marshals the "version" string

func (*Version) UnmarshalJSON

func (v *Version) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the "version" string

Jump to

Keyboard shortcuts

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