Documentation

Overview

Package hashchain implements a hash chain of signatures over a chain of code changes.

A hash chain is stored in a simple newline separated text file where each hash chain entry corresponds to a single line and has the following form:

hash-of-previous current-time type type-fields ...

Where hash-of-previous is the SHA256 hash of the previous line (without the trailing newline) in hex encoding. The fields are separated by single white spaces. The current-time is encoded as an ISO 8601 string in UTC (corresponds to time.RFC3339).

All hashes in a hash chain are SHA256 hashes encoded in hex notation. Hex encodings have to be lowercase. All public keys are Ed25519 keys and they and their signatures are encoded in base64 (URL encoding without padding). Comments are arbitrary UTF-8 sequences, but cannot contain newlines.

There are six different types of hash chain entries:

cstart
source
signtr
addkey
remkey
sigctl

A hash chain must start with a cstart entry and that is the only line where this type must appear.

Type cstart

A cstart entry starts a new hash chain.

hash-of-previous current-time cstart pubkey nonce signature [comment]

The hash-of-previous for the cstart time is the hash of an empty source tree (see tree.EmptyHash). The signature by pubkey is over the pubkey, the nonce, and the optional comment. The comment should identify the owner of the pubkey, not the project. The nonce must be a 24 byte random number in base64 (URL encoding without padding). This makes pubkey the only valid signer for the hash chain and implicitly sets the signature threshold m to 1.

Type source

A source entry marks a new source tree state for publication from the developer owning the signing pubkey. The optional comment can be used to describe the change to the reviewers.

hash-of-previous current-time source tree-hash pubkey signature [comment]

The signature by pubkey is over the source tree hash and the optional comment. See the tree package for a detailed description of source tree hashes.

Type signtr

A signtr entry signs a previous hash chain entry and thereby approves all code changes and changes to the set of signature keys and m up to that point.

hash-of-previous current-time signtr hash-of-chain-entry pubkey signature

It does not necessarily sign the previous line and can therefore be done in a detached fashion by a reviewer and added later by the developer responsible for maintaining the hash chain. This avoids merge conflicts.

Type addkey

An addkey entry marks a signature pubkey for addition to the list of approved signature keys.

hash-of-previous current-time addkey w pubkey signature [comment]

The weight of the key towards the minimum number of necessary signatures m is denoted by w. The pubkey can be accompanied by an optional comment, but the signature must be over both. The comment is added last so it can contain white spaces without complicating the parsing, it should identify the owner of the pubkey.

Type remkey

A remkey entry marks a signature pubkey for removal from the list of approved signature keys.

hash-of-previous current-time remkey pubkey

Type sigctl

A sigctl entry denotes an update of m, the minimum number of necessary signatures to approve state changes (the threshold).

hash-of-previous current-time sigctl m

Example

An example of a hash chain.

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2018-05-19T00:07:02Z cstart KDKOGoY8ErjOnbDQb4k8SZFMvWdAIb-x6FGKKCRby70 sVnVenzHyCOV6nLUkCKg6ARllkYsTV-n 0UmUcDFZ2j3WWnqzEdxX-wzofWlhF3O0Rm1tT6qMUwLu8a1R5MwbK5zDongYZKccpA37Vp6Sp3m0xSreGskzCg Alice <alice@example.com>
40c7e5ca4be98e9cae6931afa4ac09e11ecb1ce20fa18d0faaabfac7e8fad071 2018-05-19T00:09:44Z addkey 1 91HOu2fvkjHd5S0LtAWTl6dYBk5cqB-NWiJqc0c_7Gc Xsr_L-1_5_B56vocve8s3Pb3vJoc-jpa2-tzIQhEjuoytYfcAiONu3er6RnVNMcsPuZFeqWCQKBwka-F-c13Ag Bob <bob@example.com>
34cd10effd93e67ba96fefb29ea751d013459a6de11cc117cf1deacd77d6b7be 2018-05-19T00:10:25Z sigctl 2
92d2fc6687b0d36d045adaf34a1615e513ef0e2dc60384cfe19863e9753567f8 2018-05-19T00:11:44Z source d844cbe6f6c2c29e97742b272096407e4d92e6ac7f167216b321c7aa55629716 KDKOGoY8ErjOnbDQb4k8SZFMvWdAIb-x6FGKKCRby70 r5aZCYGwWCFppaMDV7XSOHoyCl3qbUKGiSuYzjsTl4C0W9n0tCa0MXDy_fOwspV9f4_o0kMcb6XZS706ml3FAQ first release
d258ce20943beeed2d483096702a1449447f112dec7d907d50c285c649c17a24 2018-05-19T00:12:48Z signtr d258ce20943beeed2d483096702a1449447f112dec7d907d50c285c649c17a24 KDKOGoY8ErjOnbDQb4k8SZFMvWdAIb-x6FGKKCRby70 HKlLKnYSCVzc4b-erETK50EN5gKRKZQsT16grv7eFBklFqXBFoSXSmcY99HLWhAP9BJcA6c3Px1trNBns3KkDA
2e34e23ee293e8c0ed174639d325eb3e30f5337d5c5846380367724e93cb619e 2018-05-19T00:34:51Z signtr 2e34e23ee293e8c0ed174639d325eb3e30f5337d5c5846380367724e93cb619e 91HOu2fvkjHd5S0LtAWTl6dYBk5cqB-NWiJqc0c_7Gc xffZultos-MCbI4cNzAzAoccuDSnpL2nq_BsQanIruYM3RXoD9kdC6WiPEUkxrphKdG742IgBWlB3LwY0i1ZCw

Index

Constants

This section is empty.

Variables

View Source
var ErrCannotMerge = errors.New("hashchain: cannot merge")

    ErrCannotMerge is returned if two hash chains cannot be merged.

    View Source
    var ErrDescendingTime = errors.New("hashchain: time is going backwards")

      ErrDescendingTime is returned when the time in the hash chain is not ascending.

      View Source
      var ErrEmpty = errors.New("hashchain: is empty")

        ErrEmpty is returned when the hash chain is empty.

        View Source
        var ErrHeadNotFound = errors.New("hashchain: head not found")

          ErrHeadNotFound is returned if the head could not be found in hash chain.

          View Source
          var ErrIllegalCStart = errors.New("hashchain: cstart is only allowed on start")

            ErrIllegalCStart is returned when a cstart entry appears in a different row than row 1.

            View Source
            var ErrLinkBroken = errors.New("hashchain: link broken")

              ErrLinkBroken is returned when a link in the hash chain is broken.

              View Source
              var ErrMLargerThanN = errors.New("hashchain: signature threshold m is larger than total weight of signers n")

                ErrMLargerThanN is returned when m > n.

                View Source
                var ErrMustStartWithCStart = errors.New("hashchain: must start with cstart")

                  ErrMustStartWithCStart is returned when the hash chain doess not start with a cstart entry.

                  View Source
                  var ErrNothingToMerge = errors.New("hashchain: nothing to merge")

                    ErrNothingToMerge is returned if there is nothing to merge.

                    View Source
                    var ErrSignatureThresholdNonPositive = errors.New("hashchain: signature threshold m must be positive")

                      ErrSignatureThresholdNonPositive is returned when the signature threshold is non-positive.

                      View Source
                      var ErrUnknownLinkType = errors.New("hashchain: unknown link type")

                        ErrUnknownLinkType is returned when the link type is unknown.

                        View Source
                        var ErrWrongSigAddKey = errors.New("hashchain: addkey signature doesn't validate")

                          ErrWrongSigAddKey is returned when the signature of an addkey entry doesn't validate.

                          View Source
                          var ErrWrongSigCStart = errors.New("hashchain: cstart signature doesn't validate")

                            ErrWrongSigCStart is returned when the signature of a cstart entry doesn't validate.

                            View Source
                            var ErrWrongSigSignature = errors.New("hashchain: signature signature doesn't validate")

                              ErrWrongSigSignature is returned when the signature of a signature entry doesn't validate.

                              View Source
                              var ErrWrongSigSource = errors.New("hashchain: source signature doesn't validate")

                                ErrWrongSigSource is returned when the signature of a source entry doesn't validate.

                                View Source
                                var ErrWrongTypeFields = errors.New("hashchain: entry has wrong number of type fields")

                                  ErrWrongTypeFields is returned when a hash chain entry has the wrong number of type fields.

                                  Functions

                                  This section is empty.

                                  Types

                                  type HashChain

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

                                    HashChain of threshold signatures over a chain of code changes.

                                    func Read

                                    func Read(r io.Reader) (*HashChain, error)

                                      Read hash chain from r and verify it.

                                      func ReadFile

                                      func ReadFile(filename string) (*HashChain, error)

                                        ReadFile reads hash chain from filename and verifies it.

                                        func Start

                                        func Start(filename string, secKey [64]byte, comment []byte) (*HashChain, string, error)

                                          Start returns a new hash chain with signature control list m.

                                          func (*HashChain) AddKey

                                          func (c *HashChain) AddKey(weight int, pubKey [32]byte, signature [64]byte, comment []byte) (string, error)

                                            AddKey adds pubkey with signature and optional comment to hash chain.

                                            func (*HashChain) Apply

                                            func (c *HashChain) Apply(head *[32]byte, patchDir string) error

                                              Apply to current working directory and check head if not nil.

                                              func (*HashChain) CheckHead

                                              func (c *HashChain) CheckHead(head [32]byte) error

                                                CheckHead checks wether the hash chain contains the given head as entry.

                                                func (*HashChain) Close

                                                func (c *HashChain) Close() error

                                                  Close the underlying file pointer of hash chain and release lock.

                                                  func (*HashChain) DeepVerify

                                                  func (c *HashChain) DeepVerify(treeDir, patchDir string, excludePaths []string) error

                                                    DeepVerify hash chain. Use directory treeDir to apply patches from patchDir one after another and verify that they reflect the treehashes recorded in the hash chain.

                                                    func (*HashChain) DetachedSignature

                                                    func (c *HashChain) DetachedSignature(linkHash, pubKey, signature string) (string, error)

                                                      DetachedSignature adds a detached signature entry for linkHash signed by pubKey to the hash chain.

                                                      func (*HashChain) Fprint

                                                      func (c *HashChain) Fprint(w io.Writer) error

                                                        Fprint hash chain to w.

                                                        func (*HashChain) Head

                                                        func (c *HashChain) Head() [32]byte

                                                          Head returns the hash of the last entry.

                                                          func (*HashChain) LastSignedTreeHash

                                                          func (c *HashChain) LastSignedTreeHash() (string, int)

                                                            LastSignedTreeHash returns the last signed tree hash and its index. The first signed tree hash is tree.EmptyHash with index 0.

                                                            func (*HashChain) LastTreeHash

                                                            func (c *HashChain) LastTreeHash() string

                                                              LastTreeHash returns the most current tree hash (can be unsigned).

                                                              func (*HashChain) LinkHash

                                                              func (c *HashChain) LinkHash(treeHash string) [32]byte

                                                                LinkHash returns the link hash corresponding to given treeHash.

                                                                func (*HashChain) M

                                                                func (c *HashChain) M() int

                                                                  M returns the signature threshold.

                                                                  func (*HashChain) Merge

                                                                  func (c *HashChain) Merge(src *HashChain) error

                                                                    Merge hashchain src into c.

                                                                    func (*HashChain) N

                                                                    func (c *HashChain) N() int

                                                                      N returns the total weight of all signers.

                                                                      func (*HashChain) Print

                                                                      func (c *HashChain) Print()

                                                                        Print colorized hash chain on stdout.

                                                                        func (*HashChain) RemoveKey

                                                                        func (c *HashChain) RemoveKey(pubKey [32]byte) (string, error)

                                                                          RemoveKey adds a pubkey remove entry to hash chain.

                                                                          func (*HashChain) Signature

                                                                          func (c *HashChain) Signature(linkHash [32]byte, secKey [64]byte, detached bool) (string, error)

                                                                            Signature adds a signature entry for linkHash signed by secKey to the hash chain. If detached it just returns the signature without adding it.

                                                                            func (*HashChain) SignatureControl

                                                                            func (c *HashChain) SignatureControl(m int) (string, error)

                                                                              SignatureControl adds a signature control entry to the hash chain.

                                                                              func (*HashChain) Signer

                                                                              func (c *HashChain) Signer() map[string]bool

                                                                                Signer returns a map containing all active signers for hash chain.

                                                                                func (*HashChain) SignerBarrier

                                                                                func (c *HashChain) SignerBarrier(pubKey string) int

                                                                                  SignerBarrier returns the signer barrier for pubKey.

                                                                                  func (*HashChain) SignerComment

                                                                                  func (c *HashChain) SignerComment(pubKey string) string

                                                                                    SignerComment returns the signer comment for given pubKey.

                                                                                    func (*HashChain) SignerInfo

                                                                                    func (c *HashChain) SignerInfo(treeHash string) (string, string)

                                                                                      SignerInfo returns signer pubKey and comment for patch with given treeHash.

                                                                                      func (*HashChain) SignerWeight

                                                                                      func (c *HashChain) SignerWeight(pubKey string) int

                                                                                        SignerWeight returns the signer weight for given pubKey.

                                                                                        func (*HashChain) Source

                                                                                        func (c *HashChain) Source(treeHash [32]byte, secKey [64]byte, comment []byte) (string, error)

                                                                                          Source adds a source entry for treeHash and optional comment signed by secKey to the hash chain.

                                                                                          func (*HashChain) SourceLine

                                                                                          func (c *HashChain) SourceLine(treeHash string) int

                                                                                            SourceLine returns the line number where the given tree hash was signed.

                                                                                            func (*HashChain) TreeComments

                                                                                            func (c *HashChain) TreeComments() []string

                                                                                              TreeComments returns a list of all tree comments in order (starting from tree.EmptyHash).

                                                                                              func (*HashChain) TreeHashes

                                                                                              func (c *HashChain) TreeHashes() []string

                                                                                                TreeHashes returns a list of all tree hashes in order (starting from tree.EmptyHash).

                                                                                                func (*HashChain) UnsignedInfo

                                                                                                func (c *HashChain) UnsignedInfo(pubkey, treeHash string, omitSource bool) ([]string, error)

                                                                                                  UnsignedInfo returns a string slice with information about all unsigned entries suitable for printing. If TreeHash is defined it returns info until that treeHash. If omitSource is true source lines are omitted

                                                                                                  Directories

                                                                                                  Path Synopsis
                                                                                                  Package linktype defines the different link types of a hash chain.
                                                                                                  Package linktype defines the different link types of a hash chain.
                                                                                                  internal
                                                                                                  state
                                                                                                  Package state implements the state of a hashchain.
                                                                                                  Package state implements the state of a hashchain.