in_toto

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2021 License: Apache-2.0 Imports: 30 Imported by: 197

Documentation

Overview

Package in_toto implements types and routines to verify a software supply chain according to the in-toto specification. See https://github.com/in-toto/docs/blob/master/in-toto-spec.md

Index

Examples

Constants

View Source
const (
	// StatementInTotoV01 is the statement type for the generalized link format
	// containing statements. This is constant for all predicate types.
	StatementInTotoV01 = "https://in-toto.io/Statement/v0.1"
	// PredicateSPDX represents a SBOM using the SPDX standard.
	// The SPDX mandates 'spdxVersion' field, so predicate type can omit
	// version.
	PredicateSPDX = "https://spdx.dev/Document"
	// PredicateLinkV1 represents an in-toto 0.9 link.
	PredicateLinkV1 = "https://in-toto.io/Link/v1"
	// PredicateProvenanceV01 represents a build provenance for an artifact.
	PredicateProvenanceV01 = "https://in-toto.io/Provenance/v0.1"
)
View Source
const ISO8601DateSchema = "2006-01-02T15:04:05Z"

ISO8601DateSchema defines the format string of a timestamp following the ISO 8601 standard.

View Source
const LinkNameFormat = "%s.%.8s.link"

LinkNameFormat represents a format string used to create the filename for a signed Link (wrapped in a Metablock). It consists of the name of the link and the first 8 characters of the signing key id. E.g.:

fmt.Sprintf(LinkNameFormat, "package",
"2f89b9272acfc8f4a0a0f094d789fdb0ba798b0fe41f2f5f417c12f0085ff498")
// returns "package.2f89b9272.link"
View Source
const LinkNameFormatShort = "%s.link"

LinkNameFormatShort is for links that are not signed, e.g.:

fmt.Sprintf(LinkNameFormatShort, "unsigned")
// returns "unsigned.link"
View Source
const PayloadType = "application/vnd.in-toto+json"

PayloadType is the payload type used for links and layouts.

View Source
const SublayoutLinkDirFormat = "%s.%.8s"

SublayoutLinkDirFormat represents the format of the name of the directory for sublayout links during the verification workflow.

Variables

View Source
var ErrCurveSizeSchemeMismatch = errors.New("the scheme does not match the curve size")

ErrCurveSizeSchemeMismatch gets returned, when the scheme and curve size are incompatible for example: curve size = "521" and scheme = "ecdsa-sha2-nistp224"

View Source
var ErrEmptyKeyField = errors.New("empty field in key")

ErrEmptyKeyField will be thrown if a field in our Key struct is empty.

View Source
var ErrFailedPEMParsing = errors.New("failed parsing the PEM block: unsupported PEM type")

ErrFailedPEMParsing gets returned when PKCS1, PKCS8 or PKIX key parsing fails

View Source
var ErrInspectionRunDirIsSymlink = errors.New("runDir is a symlink. This is a security risk")

ErrInspectionRunDirIsSymlink gets thrown if the runDir is a symlink

View Source
var ErrInvalidHexString = errors.New("invalid hex string")

ErrInvalidHexString will be thrown, if a string doesn't match a hex string.

View Source
var ErrInvalidKey = errors.New("invalid key")

ErrInvalidKey is returned when a given key is none of RSA, ECDSA or ED25519

View Source
var ErrInvalidPayloadType = errors.New("unknown payload type")

ErrInvalidPayloadType indicates that the envelope used an unkown payload type

View Source
var ErrInvalidSignature = errors.New("invalid signature")

ErrInvalidSignature is returned when the signature is invalid

View Source
var ErrKeyKeyTypeMismatch = errors.New("the given key does not match its key type")

ErrKeyKeyTypeMismatch will be thrown, if the specified keyType does not match the key

View Source
var ErrNoPEMBlock = errors.New("failed to decode the data as PEM block (are you sure this is a pem file?)")

ErrNoPEMBlock gets triggered when there is no PEM block in the provided file

View Source
var ErrNoPublicKey = errors.New("the given key is not a public key")

ErrNoPublicKey gets returned when the private key value is not empty.

View Source
var ErrSchemeKeyTypeMismatch = errors.New("the scheme and key type are not supported together")

ErrSchemeKeyTypeMismatch will be thrown, if the given scheme and key type are not supported together.

View Source
var ErrSymCycle = errors.New("symlink cycle detected")

ErrSymCycle signals a detected symlink cycle in our RecordArtifacts() function.

View Source
var ErrUnsupportedHashAlgorithm = errors.New("unsupported hash algorithm detected")

ErrUnsupportedHashAlgorithm signals a missing hash mapping in getHashMapping

View Source
var ErrUnsupportedKeyIDHashAlgorithms = errors.New("the given keyID hash algorithm is not supported")

ErrUnsupportedKeyIDHashAlgorithms will be thrown, if the specified KeyIDHashAlgorithms is not supported.

View Source
var ErrUnsupportedKeyType = errors.New("unsupported key type")

ErrUnsupportedKeyType is returned when we are dealing with a key type different to ed25519 or RSA

Functions

func EncodeCanonical

func EncodeCanonical(obj interface{}) ([]byte, error)

EncodeCanonical JSON canonicalizes the passed object and returns it as a byte slice. It uses the OLPC canonical JSON specification (see http://wiki.laptop.org/go/Canonical_JSON). If canonicalization fails the byte slice is nil and the second return value contains the error.

func InterfaceKeyStrings

func InterfaceKeyStrings(m map[string]interface{}) []string

InterfaceKeyStrings returns string keys of passed interface{} map in an unordered string slice.

func LoadLinksForLayout

func LoadLinksForLayout(layout Layout, linkDir string) (
	map[string]map[string]Metablock, error)

LoadLinksForLayout loads for every Step of the passed Layout a Metablock containing the corresponding Link. A base path to a directory that contains the links may be passed using linkDir. Link file names are constructed, using LinkNameFormat together with the corresponding step name and authorized functionary key ids. A map of link metadata is returned and has the following format:

{
	<step name> : {
		<key id>: Metablock,
		<key id>: Metablock,
		...
	},
	<step name> : {
	<key id>: Metablock,
	<key id>: Metablock,
	...
	}
	...
}

If a link cannot be loaded at a constructed link name or is invalid, it is ignored. Only a preliminary threshold check is performed, that is, if there aren't at least Threshold links for any given step, the first return value is an empty map of Metablock maps and the second return value is the error.

func RecordArtifact

func RecordArtifact(path string, hashAlgorithms []string) (map[string]interface{}, error)

RecordArtifact reads and hashes the contents of the file at the passed path using sha256 and returns a map in the following format:

{
	"<path>": {
		"sha256": <hex representation of hash>
	}
}

If reading the file fails, the first return value is nil and the second return value is the error. NOTE: For cross-platform consistency Windows-style line separators (CRLF) are normalized to Unix-style line separators (LF) before hashing file contents.

func RecordArtifacts

func RecordArtifacts(paths []string, hashAlgorithms []string, gitignorePatterns []string) (evalArtifacts map[string]interface{}, err error)

RecordArtifacts is a wrapper around recordArtifacts. RecordArtifacts initializes a set for storing visited symlinks, calls recordArtifacts and deletes the set if no longer needed. recordArtifacts walks through the passed slice of paths, traversing subdirectories, and calls RecordArtifact for each file. It returns a map in the following format:

{
	"<path>": {
		"sha256": <hex representation of hash>
	},
	"<path>": {
	"sha256": <hex representation of hash>
	},
	...
}

If recording an artifact fails the first return value is nil and the second return value is the error.

func ReduceStepsMetadata

func ReduceStepsMetadata(layout Layout,
	stepsMetadata map[string]map[string]Metablock) (map[string]Metablock,
	error)

ReduceStepsMetadata merges for each step of the passed Layout all the passed per-functionary links into a single link, asserting that the reported Materials and Products are equal across links for a given step. This function may be used at a time during the overall verification, where link threshold's have been verified and subsequent verification only needs one exemplary link per step. The function returns a map with one Metablock (link) per step:

{
	<step name> : Metablock,
	<step name> : Metablock,
	...
}

If links corresponding to the same step report different Materials or different Products, the first return value is an empty Metablock map and the second return value is the error.

func RunCommand

func RunCommand(cmdArgs []string, runDir string) (map[string]interface{}, error)

RunCommand executes the passed command in a subprocess. The first element of cmdArgs is used as executable and the rest as command arguments. It captures and returns stdout, stderr and exit code. The format of the returned map is:

{
	"return-value": <exit code>,
	"stdout": "<standard output>",
	"stderr": "<standard error>"
}

If the command cannot be executed or no pipes for stdout or stderr can be created the first return value is nil and the second return value is the error. NOTE: Since stdout and stderr are captured, they cannot be seen during the command execution.

func RunInspections

func RunInspections(layout Layout, runDir string) (map[string]Metablock, error)

RunInspections iteratively executes the command in the Run field of all inspections of the passed layout, creating unsigned link metadata that records all files found in the current working directory as materials (before command execution) and products (after command execution). A map with inspection names as keys and Metablocks containing the generated link metadata as values is returned. The format is:

{
	<inspection name> : Metablock,
	<inspection name> : Metablock,
	...
}

If executing the inspection command fails, or if the executed command has a non-zero exit code, the first return value is an empty Metablock map and the second return value is the error.

func UnpackRule

func UnpackRule(rule []string) (map[string]string, error)

UnpackRule parses the passed rule and extracts and returns the information required for rule processing. It can be used to verify if a rule has a valid format. Available rule formats are:

MATCH <pattern> [IN <source-path-prefix>] WITH (MATERIALS|PRODUCTS)
	[IN <destination-path-prefix>] FROM <step>,
CREATE <pattern>,
DELETE <pattern>,
MODIFY <pattern>,
ALLOW <pattern>,
DISALLOW <pattern>

Rule tokens are normalized to lower case before returning. The returned map has the following format:

{
	"type": "match" | "create" | "delete" |"modify" | "allow" | "disallow"
	"pattern": "<file name pattern>",
	"srcPrefix": "<path or empty string>", // MATCH rule only
	"dstPrefix": "<path or empty string>", // MATCH rule only
	"dstType": "materials" | "products">, // MATCH rule only
	"dstName": "<step name>", // Match rule only
}

If the rule does not match any of the available formats the first return value is nil and the second return value is the error.

func ValidateMetablock added in v0.2.0

func ValidateMetablock(mb Metablock) error

ValidateMetablock ensures that a passed Metablock object is valid. It indirectly validates the Link or Layout that the Metablock object contains.

func VerifyArtifacts

func VerifyArtifacts(items []interface{},
	itemsMetadata map[string]Metablock) error

VerifyArtifacts iteratively applies the material and product rules of the passed items (step or inspection) to enforce and authorize artifacts (materials or products) reported by the corresponding link and to guarantee that artifacts are linked together across links. In the beginning all artifacts are placed in a queue according to their type. If an artifact gets consumed by a rule it is removed from the queue. An artifact can only be consumed once in the course of processing the set of rules in ExpectedMaterials or ExpectedProducts.

Rules of type MATCH, ALLOW, CREATE, DELETE, MODIFY and DISALLOW are supported.

All rules except for DISALLOW consume queued artifacts on success, and leave the queue unchanged on failure. Hence, it is left to a terminal DISALLOW rule to fail overall verification, if artifacts are left in the queue that should have been consumed by preceding rules.

func VerifyLayoutExpiration

func VerifyLayoutExpiration(layout Layout) error

VerifyLayoutExpiration verifies that the passed Layout has not expired. It returns an error if the (zulu) date in the Expires field is in the past.

func VerifyLayoutSignatures

func VerifyLayoutSignatures(layoutMb Metablock,
	layoutKeys map[string]Key) error

VerifyLayoutSignatures verifies for each key in the passed key map the corresponding signature of the Layout in the passed Metablock's Signed field. Signatures and keys are associated by key id. If the key map is empty, or the Metablock's Signature field does not have a signature for one or more of the passed keys, or a matching signature is invalid, an error is returned.

func VerifyLinkSignatureThesholds

func VerifyLinkSignatureThesholds(layout Layout,
	stepsMetadata map[string]map[string]Metablock) (
	map[string]map[string]Metablock, error)

VerifyLinkSignatureThesholds verifies that for each step of the passed layout, there are at least Threshold links, validly signed by different authorized functionaries. The returned map of link metadata per steps contains only links with valid signatures from distinct functionaries and has the format:

{
	<step name> : {
	<key id>: Metablock,
	<key id>: Metablock,
	...
	},
	<step name> : {
	<key id>: Metablock,
	<key id>: Metablock,
	...
	}
	...
}

If for any step of the layout there are not enough links available, the first return value is an empty map of Metablock maps and the second return value is the error.

func VerifySignature

func VerifySignature(key Key, sig Signature, unverified []byte) error

VerifySignature will verify unverified byte data via a passed key and signature. Supported key types are:

  • rsa
  • ed25519
  • ecdsa

When encountering an RSA key, VerifySignature will decode the PEM block in the key and will call rsa.VerifyPSS() for verifying the RSA signature. When encountering an ed25519 key, VerifySignature will decode the hex string encoded public key and will use ed25519.Verify() for verifying the ed25519 signature. When the given key is an ecdsa key, VerifySignature will unmarshall the ASN1 object and will use the retrieved ecdsa components 'r' and 's' for verifying the signature. On success it will return nil. In case of an unsupported key type or any other error it will return an error.

Note that in-toto-golang has different requirements to an ecdsa key. In in-toto-golang we use the string 'ecdsa' as string for the key type. In the key scheme we use: ecdsa-sha2-nistp256.

func VerifyStepCommandAlignment

func VerifyStepCommandAlignment(layout Layout,
	stepsMetadata map[string]map[string]Metablock)

VerifyStepCommandAlignment (soft) verifies that for each step of the passed layout the command executed, as per the passed link, matches the expected command, as per the layout. Soft verification means that, in case a command does not align, a warning is issued.

func VerifySublayouts

func VerifySublayouts(layout Layout,
	stepsMetadataVerified map[string]map[string]Metablock,
	superLayoutLinkPath string) (map[string]map[string]Metablock, error)

VerifySublayouts checks if any step in the supply chain is a sublayout, and if so, recursively resolves it and replaces it with a summary link summarizing the steps carried out in the sublayout.

Types

type DigestSet added in v0.2.0

type DigestSet map[string]string

DigestSet contains a set of digests. It is represented as a map from algorithm name to lowercase hex-encoded value.

type Inspection

type Inspection struct {
	Type string   `json:"_type"`
	Run  []string `json:"run"`
	SupplyChainItem
}

Inspection represents an in-toto supply chain inspection, whose command in the Run field is executed during final product verification, generating unsigned link metadata. Materials and products used/produced by the inspection are constrained by the artifact rules in the inspection's ExpectedMaterials and ExpectedProducts fields.

type Key

type Key struct {
	KeyID               string   `json:"keyid"`
	KeyIDHashAlgorithms []string `json:"keyid_hash_algorithms"`
	KeyType             string   `json:"keytype"`
	KeyVal              KeyVal   `json:"keyval"`
	Scheme              string   `json:"scheme"`
}

Key represents a generic in-toto key that contains key metadata, such as an identifier, supported hash algorithms to create the identifier, the key type and the supported signature scheme, and the actual key value.

func (*Key) LoadKey

func (k *Key) LoadKey(path string, scheme string, KeyIDHashAlgorithms []string) error

LoadKey loads the key file at specified file path into the key object. It automatically derives the PEM type and the key type. Right now the following PEM types are supported:

  • PKCS1 for private keys
  • PKCS8 for private keys
  • PKIX for public keys

The following key types are supported and will be automatically assigned to the key type field:

  • ed25519
  • rsa
  • ecdsa

The following schemes are supported:

  • ed25519 -> ed25519
  • rsa -> rsassa-pss-sha256
  • ecdsa -> ecdsa-sha256-nistp256

Note that, this behavior is consistent with the securesystemslib, except for ecdsa. We do not use the scheme string as key type in in-toto-golang. Instead we are going with a ecdsa/ecdsa-sha2-nistp256 pair.

On success it will return nil. The following errors can happen:

  • path not found or not readable
  • no PEM block in the loaded file
  • no valid PKCS8/PKCS1 private key or PKIX public key
  • errors while marshalling
  • unsupported key types

func (*Key) LoadKeyReader

func (k *Key) LoadKeyReader(r io.Reader, scheme string, KeyIDHashAlgorithms []string) error

LoadKeyReader loads the key from a supplied reader. The logic matches LoadKey otherwise.

type KeyVal

type KeyVal struct {
	Private string `json:"private"`
	Public  string `json:"public"`
}

KeyVal contains the actual values of a key, as opposed to key metadata such as a key identifier or key type. For RSA keys, the key value is a pair of public and private keys in PEM format stored as strings. For public keys the Private field may be an empty string.

type Layout

type Layout struct {
	Type    string         `json:"_type"`
	Steps   []Step         `json:"steps"`
	Inspect []Inspection   `json:"inspect"`
	Keys    map[string]Key `json:"keys"`
	Expires string         `json:"expires"`
	Readme  string         `json:"readme"`
}

Layout represents the definition of a software supply chain. It lists the sequence of steps required in the software supply chain and the functionaries authorized to perform these steps. Functionaries are identified by their public keys. In addition, the layout may list a sequence of inspections that are executed during in-toto supply chain verification. A layout should be contained in a generic Metablock object, which provides functionality for signing and signature verification, and reading from and writing to disk.

func SubstituteParameters

func SubstituteParameters(layout Layout,
	parameterDictionary map[string]string) (Layout, error)

SubstituteParameters performs parameter substitution in steps and inspections in the following fields: - Expected Materials and Expected Products of both - Run of inspections - Expected Command of steps The substitution marker is '{}' and the keyword within the braces is replaced by a value found in the substitution map passed, parameterDictionary. The layout with parameters substituted is returned to the calling function.

type Link struct {
	Type        string                 `json:"_type"`
	Name        string                 `json:"name"`
	Materials   map[string]interface{} `json:"materials"`
	Products    map[string]interface{} `json:"products"`
	ByProducts  map[string]interface{} `json:"byproducts"`
	Command     []string               `json:"command"`
	Environment map[string]interface{} `json:"environment"`
}

Link represents the evidence of a supply chain step performed by a functionary. It should be contained in a generic Metablock object, which provides functionality for signing and signature verification, and reading from and writing to disk.

type LinkStatement added in v0.2.0

type LinkStatement struct {
	StatementHeader
	Predicate Link `json:"predicate"`
}

LinkStatement is the definition for an entire link statement.

type Metablock

type Metablock struct {
	// NOTE: Whenever we want to access an attribute of `Signed` we have to
	// perform type assertion, e.g. `metablock.Signed.(Layout).Keys`
	// Maybe there is a better way to store either Layouts or Links in `Signed`?
	// The notary folks seem to have separate container structs:
	// https://github.com/theupdateframework/notary/blob/master/tuf/data/root.go#L10-L14
	// https://github.com/theupdateframework/notary/blob/master/tuf/data/targets.go#L13-L17
	// I implemented it this way, because there will be several functions that
	// receive or return a Metablock, where the type of Signed has to be inferred
	// on runtime, e.g. when iterating over links for a layout, and a link can
	// turn out to be a layout (sublayout)
	Signed     interface{} `json:"signed"`
	Signatures []Signature `json:"signatures"`
}

Metablock is a generic container for signable in-toto objects such as Layout or Link. It has two fields, one that contains the signable object and one that contains corresponding signatures. Metablock also provides functionality for signing and signature verification, and reading from and writing to disk.

func GetSummaryLink(layout Layout, stepsMetadataReduced map[string]Metablock,
	stepName string) (Metablock, error)

GetSummaryLink merges the materials of the first step (as mentioned in the layout) and the products of the last step and returns a new link. This link reports the materials and products and summarizes the overall software supply chain. NOTE: The assumption is that the steps mentioned in the layout are to be performed sequentially. So, the first step mentioned in the layout denotes what comes into the supply chain and the last step denotes what goes out.

func InTotoRun

func InTotoRun(name string, runDir string, materialPaths []string, productPaths []string,
	cmdArgs []string, key Key, hashAlgorithms []string, gitignorePatterns []string) (Metablock, error)

InTotoRun executes commands, e.g. for software supply chain steps or inspections of an in-toto layout, and creates and returns corresponding link metadata. Link metadata contains recorded products at the passed productPaths and materials at the passed materialPaths. The returned link is wrapped in a Metablock object. If command execution or artifact recording fails the first return value is an empty Metablock and the second return value is the error.

func InTotoVerify

func InTotoVerify(layoutMb Metablock, layoutKeys map[string]Key,
	linkDir string, stepName string, parameterDictionary map[string]string) (
	Metablock, error)

InTotoVerify can be used to verify an entire software supply chain according to the in-toto specification. It requires the metadata of the root layout, a map that contains public keys to verify the root layout signatures, a path to a directory from where it can load link metadata files, which are treated as signed evidence for the steps defined in the layout, a step name, and a paramater dictionary used for parameter substitution. The step name only matters for sublayouts, where it's important to associate the summary of that step with a unique name. The verification routine is as follows:

1. Verify layout signature(s) using passed key(s) 2. Verify layout expiration date 3. Substitute parameters in layout 4. Load link metadata files for steps of layout 5. Verify signatures and signature thresholds for steps of layout 6. Verify sublayouts recursively 7. Verify command alignment for steps of layout (only warns) 8. Verify artifact rules for steps of layout 9. Execute inspection commands (generates link metadata for each inspection) 10. Verify artifact rules for inspections of layout

InTotoVerify returns a summary link wrapped in a Metablock object and an error value. If any of the verification routines fail, verification is aborted and error is returned. In such an instance, the first value remains an empty Metablock object.

NOTE: Artifact rules of type "create", "modify" and "delete" are currently not supported.

Example
package main

import (
	"fmt"
	"os"
)

/*
NOTE: The example code requires the following files to be in the current
working directory: `demo.layout` (root layout), `alice.pub` (layout
signature verification key), `write-code.776a00e2.link` and
`package.2f89b927.link` (link metadata files), and `foo.tar.gz` (target file of
final product). You can copy these files from
https://github.com/in-toto/in-toto-golang/tree/master/test/data.
*/

const LayoutPath = "demo.layout"
const LayoutKeyPath = "alice.pub"
const LinkDirectory = "."

func main() {
	// Load the layout verification key and create a map as is required by
	// InTotoVerify.  The layout represents the root of trust so it is a good
	// idea to sign it using multiple keys.
	var pubKey Key
	err := pubKey.LoadKey(LayoutKeyPath, "rsassa-pss-sha256", []string{"sha256", "sha512"})
	if err != nil {
		fmt.Printf("Unable to load public key: %s", err)
	}
	var layoutKeys = map[string]Key{
		pubKey.KeyID: pubKey,
	}

	// Perform in-toto software supply chain verification, using the provided
	// test data.
	var layoutMb Metablock
	if err := layoutMb.Load(LayoutPath); err != nil {
		fmt.Printf("Unable to load layout metadata: %s", err)
	}
	if err := validateLayout(layoutMb.Signed.(Layout)); err != nil {
		fmt.Printf("Invalid metadata found: %s", err)
	}
	if _, err := InTotoVerify(layoutMb, layoutKeys, LinkDirectory, "",
		make(map[string]string)); err != nil {
		fmt.Printf("In-toto verification failed: %s", err)
	} else {
		fmt.Println("In-toto verification succeeded!")
	}

	// During verification the inspection "untar" was executed, generating a
	// corresponding link metadata file "untar.link". You can safely remove it.
	err = os.Remove("untar.link")
	if err != nil {
		fmt.Printf("Unable to remove untar.link: %s", err)
	}
}
Output:

In-toto verification succeeded!

func InTotoVerifyWithDirectory added in v0.2.0

func InTotoVerifyWithDirectory(layoutMb Metablock, layoutKeys map[string]Key,
	linkDir string, runDir string, stepName string, parameterDictionary map[string]string) (
	Metablock, error)

InTotoVerifyWithDirectory provides the same functionality as IntotoVerify, but adds the possibility to select a local directory from where the inspections are run.

func (*Metablock) Dump

func (mb *Metablock) Dump(path string) error

Dump JSON serializes and writes the Metablock on which it was called to the passed path. It returns an error if JSON serialization or writing fails.

func (*Metablock) GetSignableRepresentation

func (mb *Metablock) GetSignableRepresentation() ([]byte, error)

GetSignableRepresentation returns the canonical JSON representation of the Signed field of the Metablock on which it was called. If canonicalization fails the first return value is nil and the second return value is the error.

func (*Metablock) Load

func (mb *Metablock) Load(path string) (err error)

Load parses JSON formatted metadata at the passed path into the Metablock object on which it was called. It returns an error if it cannot parse a valid JSON formatted Metablock that contains a Link or Layout.

func (*Metablock) Sign

func (mb *Metablock) Sign(key Key) error

Sign creates a signature over the signed portion of the metablock using the Key object provided. It then appends the resulting signature to the signatures field as provided. It returns an error if the Signed object cannot be canonicalized, or if the key is invalid or not supported.

func (*Metablock) VerifySignature

func (mb *Metablock) VerifySignature(key Key) error

VerifySignature verifies the first signature, corresponding to the passed Key, that it finds in the Signatures field of the Metablock on which it was called. It returns an error if Signatures does not contain a Signature corresponding to the passed Key, the object in Signed cannot be canonicalized, or the Signature is invalid.

type ProvenanceBuilder added in v0.2.0

type ProvenanceBuilder struct {
	ID string `json:"id"`
}

ProvenanceBuilder idenfifies the entity that executed the build steps.

type ProvenanceComplete added in v0.2.0

type ProvenanceComplete struct {
	Arguments   bool `json:"arguments"`
	Environment bool `json:"environment"`
	Materials   bool `json:"materials"`
}

ProvenanceComplete indicates wheter the claims in build/recipe are complete. For in depth information refer to the specifictaion: https://github.com/in-toto/attestation/blob/v0.1.0/spec/predicates/provenance.md

type ProvenanceMaterial added in v0.2.0

type ProvenanceMaterial struct {
	URI    string    `json:"uri"`
	Digest DigestSet `json:"digest,omitempty"`
}

ProvenanceMaterial defines the materials used to build an artifact.

type ProvenanceMetadata added in v0.2.0

type ProvenanceMetadata struct {
	// Use pointer to make sure that the abscense of a time is not
	// encoded as the Epoch time.
	BuildStartedOn  *time.Time         `json:"buildStartedOn,omitempty"`
	BuildFinishedOn *time.Time         `json:"buildFinishedOn,omitempty"`
	Completeness    ProvenanceComplete `json:"completeness"`
	Reproducible    bool               `json:"reproducible"`
}

ProvenanceMetadata contains metadata for the built artifact.

type ProvenancePredicate added in v0.2.0

type ProvenancePredicate struct {
	Builder   ProvenanceBuilder    `json:"builder"`
	Recipe    ProvenanceRecipe     `json:"recipe"`
	Metadata  ProvenanceMetadata   `json:"metadata"`
	Materials []ProvenanceMaterial `json:"materials,omitempty"`
}

ProvenancePredicate is the provenance predicate definition.

type ProvenanceRecipe added in v0.2.0

type ProvenanceRecipe struct {
	Type string `json:"type"`
	// DefinedInMaterial can be sent as the null pointer to indicate that
	// the value is not present.
	DefinedInMaterial *int        `json:"definedInMaterial,omitempty"`
	EntryPoint        string      `json:"entryPoint"`
	Arguments         interface{} `json:"arguments,omitempty"`
	Environment       interface{} `json:"environment,omitempty"`
}

ProvenanceRecipe describes the actions performed by the builder.

type ProvenanceStatement added in v0.2.0

type ProvenanceStatement struct {
	StatementHeader
	Predicate ProvenancePredicate `json:"predicate"`
}

ProvenanceStatement is the definition for an entire provenance statement.

type SPDXStatement added in v0.2.0

type SPDXStatement struct {
	StatementHeader
	Predicate interface{} `json:"predicate"`
}

SPDXStatement is the definition for an entire SPDX statement. Currently not implemented. Some tooling exists here: https://github.com/spdx/tools-golang, but this software is still in early state. This struct is the same as the generic Statement struct but is added for completeness

type SSLSigner added in v0.2.0

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

SSLSigner provides signature generation and validation based on the SSL Signing Spec: https://github.com/secure-systems-lab/signing-spec as describe by: https://github.com/MarkLodato/ITE/tree/media-type/ITE/5 It wraps the generic SSL envelope signer and enforces the correct payload type both during signature generation and validation.

func NewSSLSigner added in v0.2.0

func NewSSLSigner(p ...ssl.SignVerifier) (*SSLSigner, error)

func (*SSLSigner) SignPayload added in v0.2.0

func (s *SSLSigner) SignPayload(body []byte) (*ssl.Envelope, error)

func (*SSLSigner) Verify added in v0.2.0

func (s *SSLSigner) Verify(e *ssl.Envelope) error

type Set

type Set map[string]struct{}

Set represents a data structure for set operations. See `NewSet` for how to create a Set, and available Set receivers for useful set operations.

Under the hood Set aliases map[string]struct{}, where the map keys are the set elements and the map values are a memory-efficient way of storing the keys.

func NewSet

func NewSet(elems ...string) Set

NewSet creates a new Set, assigns it the optionally passed variadic string elements, and returns it.

func (Set) Add

func (s Set) Add(elem string)

Add adds the passed string to the set on which it was called, if the string is not a member of the set.

func (Set) Difference

func (s Set) Difference(s2 Set) Set

Difference creates and returns a new Set with the elements of the set on which it was called that are not in the passed set.

func (Set) Filter

func (s Set) Filter(pattern string) Set

Filter creates and returns a new Set with the elements of the set on which it was called that match the passed pattern. A matching error is treated like a non-match plus a warning is printed.

func (Set) Has

func (s Set) Has(elem string) bool

Has returns True if the passed string is member of the set on which it was called and False otherwise.

func (Set) Intersection

func (s Set) Intersection(s2 Set) Set

Intersection creates and returns a new Set with the elements of the set on which it was called that are also in the passed set.

func (Set) IsSubSet

func (s Set) IsSubSet(subset Set) bool

IsSubSet checks if the parameter subset is a subset of the superset s.

func (Set) Remove

func (s Set) Remove(elem string)

Remove removes the passed string from the set on which was is called, if the string is a member of the set.

func (Set) Slice

func (s Set) Slice() []string

Slice creates and returns an unordered string slice with the elements of the set on which it was called.

type Signature

type Signature struct {
	KeyID string `json:"keyid"`
	Sig   string `json:"sig"`
}

Signature represents a generic in-toto signature that contains the identifier of the Key, which was used to create the signature and the signature data. The used signature scheme is found in the corresponding Key.

func GenerateSignature

func GenerateSignature(signable []byte, key Key) (Signature, error)

GenerateSignature will automatically detect the key type and sign the signable data with the provided key. If everything goes right GenerateSignature will return a for the key valid signature and err=nil. If something goes wrong it will return a not initialized signature and an error. Possible errors are:

  • ErrNoPEMBlock
  • ErrUnsupportedKeyType

Currently supported is only one scheme per key.

Note that in-toto-golang has different requirements to an ecdsa key. In in-toto-golang we use the string 'ecdsa' as string for the key type. In the key scheme we use: ecdsa-sha2-nistp256.

type Statement added in v0.2.0

type Statement struct {
	StatementHeader
	// Predicate contains type speficic metadata.
	Predicate interface{} `json:"predicate"`
}

Statement binds the attestation to a particular subject and identifies the of the predicate. This struct represents a generic statement.

type StatementHeader added in v0.2.0

type StatementHeader struct {
	Type          string    `json:"_type"`
	PredicateType string    `json:"predicateType"`
	Subject       []Subject `json:"subject"`
}

StatementHeader defines the common fields for all statements

type Step

type Step struct {
	Type            string   `json:"_type"`
	PubKeys         []string `json:"pubkeys"`
	ExpectedCommand []string `json:"expected_command"`
	Threshold       int      `json:"threshold"`
	SupplyChainItem
}

Step represents an in-toto step of the supply chain performed by a functionary. During final product verification in-toto looks for corresponding Link metadata, which is used as signed evidence that the step was performed according to the supply chain definition. Materials and products used/produced by the step are constrained by the artifact rules in the step's ExpectedMaterials and ExpectedProducts fields.

type Subject added in v0.2.0

type Subject struct {
	Name   string    `json:"name"`
	Digest DigestSet `json:"digest"`
}

Subject describes the set of software artifacts the statement applies to.

type SupplyChainItem

type SupplyChainItem struct {
	Name              string     `json:"name"`
	ExpectedMaterials [][]string `json:"expected_materials"`
	ExpectedProducts  [][]string `json:"expected_products"`
}

SupplyChainItem summarizes common fields of the two available supply chain item types, Inspection and Step.

Jump to

Keyboard shortcuts

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