Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / mod@v0.3.0 / sumdb / note / note.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/mod@v0.3.0/sumdb/note/note.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/mod@v0.3.0/sumdb/note/note.go
new file mode 100644 (file)
index 0000000..467d25e
--- /dev/null
@@ -0,0 +1,678 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package note defines the notes signed by the Go module database server.
+//
+// A note is text signed by one or more server keys.
+// The text should be ignored unless the note is signed by
+// a trusted server key and the signature has been verified
+// using the server's public key.
+//
+// A server's public key is identified by a name, typically the "host[/path]"
+// giving the base URL of the server's transparency log.
+// The syntactic restrictions on a name are that it be non-empty,
+// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B).
+//
+// A Go module database server signs texts using public key cryptography.
+// A given server may have multiple public keys, each
+// identified by the first 32 bits of the SHA-256 hash of
+// the concatenation of the server name, a newline, and
+// the encoded public key.
+//
+// Verifying Notes
+//
+// A Verifier allows verification of signatures by one server public key.
+// It can report the name of the server and the uint32 hash of the key,
+// and it can verify a purported signature by that key.
+//
+// The standard implementation of a Verifier is constructed
+// by NewVerifier starting from a verifier key, which is a
+// plain text string of the form "<name>+<hash>+<keydata>".
+//
+// A Verifiers allows looking up a Verifier by the combination
+// of server name and key hash.
+//
+// The standard implementation of a Verifiers is constructed
+// by VerifierList from a list of known verifiers.
+//
+// A Note represents a text with one or more signatures.
+// An implementation can reject a note with too many signatures
+// (for example, more than 100 signatures).
+//
+// A Signature represents a signature on a note, verified or not.
+//
+// The Open function takes as input a signed message
+// and a set of known verifiers. It decodes and verifies
+// the message signatures and returns a Note structure
+// containing the message text and (verified or unverified) signatures.
+//
+// Signing Notes
+//
+// A Signer allows signing a text with a given key.
+// It can report the name of the server and the hash of the key
+// and can sign a raw text using that key.
+//
+// The standard implementation of a Signer is constructed
+// by NewSigner starting from an encoded signer key, which is a
+// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
+// Anyone with an encoded signer key can sign messages using that key,
+// so it must be kept secret. The encoding begins with the literal text
+// "PRIVATE+KEY" to avoid confusion with the public server key.
+//
+// The Sign function takes as input a Note and a list of Signers
+// and returns an encoded, signed message.
+//
+// Signed Note Format
+//
+// A signed note consists of a text ending in newline (U+000A),
+// followed by a blank line (only a newline),
+// followed by one or more signature lines of this form:
+// em dash (U+2014), space (U+0020),
+// server name, space, base64-encoded signature, newline.
+//
+// Signed notes must be valid UTF-8 and must not contain any
+// ASCII control characters (those below U+0020) other than newline.
+//
+// A signature is a base64 encoding of 4+n bytes.
+//
+// The first four bytes in the signature are the uint32 key hash
+// stored in big-endian order, which is to say they are the first
+// four bytes of the truncated SHA-256 used to derive the key hash
+// in the first place.
+//
+// The remaining n bytes are the result of using the specified key
+// to sign the note text (including the final newline but not the
+// separating blank line).
+//
+// Generating Keys
+//
+// There is only one key type, Ed25519 with algorithm identifier 1.
+// New key types may be introduced in the future as needed,
+// although doing so will require deploying the new algorithms to all clients
+// before starting to depend on them for signatures.
+//
+// The GenerateKey function generates and returns a new signer
+// and corresponding verifier.
+//
+// Example
+//
+// Here is a well-formed signed note:
+//
+//     If you think cryptography is the answer to your problem,
+//     then you don't know what your problem is.
+//
+//     — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
+//
+// It can be constructed and displayed using:
+//
+//     skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
+//     text := "If you think cryptography is the answer to your problem,\n" +
+//             "then you don't know what your problem is.\n"
+//
+//     signer, err := note.NewSigner(skey)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//
+//     msg, err := note.Sign(&note.Note{Text: text}, signer)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//     os.Stdout.Write(msg)
+//
+// The note's text is two lines, including the final newline,
+// and the text is purportedly signed by a server named
+// "PeterNeumann". (Although server names are canonically
+// base URLs, the only syntactic requirement is that they
+// not contain spaces or newlines).
+//
+// If Open is given access to a Verifiers including the
+// Verifier for this key, then it will succeed at verifiying
+// the encoded message and returning the parsed Note:
+//
+//     vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
+//     msg := []byte("If you think cryptography is the answer to your problem,\n" +
+//             "then you don't know what your problem is.\n" +
+//             "\n" +
+//             "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n")
+//
+//     verifier, err := note.NewVerifier(vkey)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//     verifiers := note.VerifierList(verifier)
+//
+//     n, err := note.Open([]byte(msg), verifiers)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//     fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text)
+//
+// You can add your own signature to this message by re-signing the note:
+//
+//     skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot")
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//     _ = vkey // give to verifiers
+//
+//     me, err := note.NewSigner(skey)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//
+//     msg, err := note.Sign(n, me)
+//     if err != nil {
+//             log.Fatal(err)
+//     }
+//     os.Stdout.Write(msg)
+//
+// This will print a doubly-signed message, like:
+//
+//     If you think cryptography is the answer to your problem,
+//     then you don't know what your problem is.
+//
+//     — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
+//     — EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=
+//
+package note
+
+import (
+       "bytes"
+       "crypto/sha256"
+       "encoding/base64"
+       "encoding/binary"
+       "errors"
+       "fmt"
+       "io"
+       "strconv"
+       "strings"
+       "unicode"
+       "unicode/utf8"
+
+       "golang.org/x/crypto/ed25519"
+)
+
+// A Verifier verifies messages signed with a specific key.
+type Verifier interface {
+       // Name returns the server name associated with the key.
+       Name() string
+
+       // KeyHash returns the key hash.
+       KeyHash() uint32
+
+       // Verify reports whether sig is a valid signature of msg.
+       Verify(msg, sig []byte) bool
+}
+
+// A Signer signs messages using a specific key.
+type Signer interface {
+       // Name returns the server name associated with the key.
+       Name() string
+
+       // KeyHash returns the key hash.
+       KeyHash() uint32
+
+       // Sign returns a signature for the given message.
+       Sign(msg []byte) ([]byte, error)
+}
+
+// keyHash computes the key hash for the given server name and encoded public key.
+func keyHash(name string, key []byte) uint32 {
+       h := sha256.New()
+       h.Write([]byte(name))
+       h.Write([]byte("\n"))
+       h.Write(key)
+       sum := h.Sum(nil)
+       return binary.BigEndian.Uint32(sum)
+}
+
+var (
+       errVerifierID   = errors.New("malformed verifier id")
+       errVerifierAlg  = errors.New("unknown verifier algorithm")
+       errVerifierHash = errors.New("invalid verifier hash")
+)
+
+const (
+       algEd25519 = 1
+)
+
+// isValidName reports whether name is valid.
+// It must be non-empty and not have any Unicode spaces or pluses.
+func isValidName(name string) bool {
+       return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
+}
+
+// NewVerifier construct a new Verifier from an encoded verifier key.
+func NewVerifier(vkey string) (Verifier, error) {
+       name, vkey := chop(vkey, "+")
+       hash16, key64 := chop(vkey, "+")
+       hash, err1 := strconv.ParseUint(hash16, 16, 32)
+       key, err2 := base64.StdEncoding.DecodeString(key64)
+       if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
+               return nil, errVerifierID
+       }
+       if uint32(hash) != keyHash(name, key) {
+               return nil, errVerifierHash
+       }
+
+       v := &verifier{
+               name: name,
+               hash: uint32(hash),
+       }
+
+       alg, key := key[0], key[1:]
+       switch alg {
+       default:
+               return nil, errVerifierAlg
+
+       case algEd25519:
+               if len(key) != 32 {
+                       return nil, errVerifierID
+               }
+               v.verify = func(msg, sig []byte) bool {
+                       return ed25519.Verify(key, msg, sig)
+               }
+       }
+
+       return v, nil
+}
+
+// chop chops s at the first instance of sep, if any,
+// and returns the text before and after sep.
+// If sep is not present, chop returns before is s and after is empty.
+func chop(s, sep string) (before, after string) {
+       i := strings.Index(s, sep)
+       if i < 0 {
+               return s, ""
+       }
+       return s[:i], s[i+len(sep):]
+}
+
+// verifier is a trivial Verifier implementation.
+type verifier struct {
+       name   string
+       hash   uint32
+       verify func([]byte, []byte) bool
+}
+
+func (v *verifier) Name() string                { return v.name }
+func (v *verifier) KeyHash() uint32             { return v.hash }
+func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
+
+// NewSigner constructs a new Signer from an encoded signer key.
+func NewSigner(skey string) (Signer, error) {
+       priv1, skey := chop(skey, "+")
+       priv2, skey := chop(skey, "+")
+       name, skey := chop(skey, "+")
+       hash16, key64 := chop(skey, "+")
+       hash, err1 := strconv.ParseUint(hash16, 16, 32)
+       key, err2 := base64.StdEncoding.DecodeString(key64)
+       if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
+               return nil, errSignerID
+       }
+
+       // Note: hash is the hash of the public key and we have the private key.
+       // Must verify hash after deriving public key.
+
+       s := &signer{
+               name: name,
+               hash: uint32(hash),
+       }
+
+       var pubkey []byte
+
+       alg, key := key[0], key[1:]
+       switch alg {
+       default:
+               return nil, errSignerAlg
+
+       case algEd25519:
+               if len(key) != 32 {
+                       return nil, errSignerID
+               }
+               key = ed25519.NewKeyFromSeed(key)
+               pubkey = append([]byte{algEd25519}, key[32:]...)
+               s.sign = func(msg []byte) ([]byte, error) {
+                       return ed25519.Sign(key, msg), nil
+               }
+       }
+
+       if uint32(hash) != keyHash(name, pubkey) {
+               return nil, errSignerHash
+       }
+
+       return s, nil
+}
+
+var (
+       errSignerID   = errors.New("malformed verifier id")
+       errSignerAlg  = errors.New("unknown verifier algorithm")
+       errSignerHash = errors.New("invalid verifier hash")
+)
+
+// signer is a trivial Signer implementation.
+type signer struct {
+       name string
+       hash uint32
+       sign func([]byte) ([]byte, error)
+}
+
+func (s *signer) Name() string                    { return s.name }
+func (s *signer) KeyHash() uint32                 { return s.hash }
+func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) }
+
+// GenerateKey generates a signer and verifier key pair for a named server.
+// The signer key skey is private and must be kept secret.
+func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) {
+       pub, priv, err := ed25519.GenerateKey(rand)
+       if err != nil {
+               return "", "", err
+       }
+       pubkey := append([]byte{algEd25519}, pub...)
+       privkey := append([]byte{algEd25519}, priv.Seed()...)
+       h := keyHash(name, pubkey)
+
+       skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey))
+       vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey))
+       return skey, vkey, nil
+}
+
+// NewEd25519VerifierKey returns an encoded verifier key using the given name
+// and Ed25519 public key.
+func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) {
+       if len(key) != ed25519.PublicKeySize {
+               return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize)
+       }
+
+       pubkey := append([]byte{algEd25519}, key...)
+       hash := keyHash(name, pubkey)
+
+       b64Key := base64.StdEncoding.EncodeToString(pubkey)
+       return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil
+}
+
+// A Verifiers is a collection of known verifier keys.
+type Verifiers interface {
+       // Verifier returns the Verifier associated with the key
+       // identified by the name and hash.
+       // If the name, hash pair is unknown, Verifier should return
+       // an UnknownVerifierError.
+       Verifier(name string, hash uint32) (Verifier, error)
+}
+
+// An UnknownVerifierError indicates that the given key is not known.
+// The Open function records signatures without associated verifiers as
+// unverified signatures.
+type UnknownVerifierError struct {
+       Name    string
+       KeyHash uint32
+}
+
+func (e *UnknownVerifierError) Error() string {
+       return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash)
+}
+
+// An ambiguousVerifierError indicates that the given name and hash
+// match multiple keys passed to VerifierList.
+// (If this happens, some malicious actor has taken control of the
+// verifier list, at which point we may as well give up entirely,
+// but we diagnose the problem instead.)
+type ambiguousVerifierError struct {
+       name string
+       hash uint32
+}
+
+func (e *ambiguousVerifierError) Error() string {
+       return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
+}
+
+// VerifierList returns a Verifiers implementation that uses the given list of verifiers.
+func VerifierList(list ...Verifier) Verifiers {
+       m := make(verifierMap)
+       for _, v := range list {
+               k := nameHash{v.Name(), v.KeyHash()}
+               m[k] = append(m[k], v)
+       }
+       return m
+}
+
+type nameHash struct {
+       name string
+       hash uint32
+}
+
+type verifierMap map[nameHash][]Verifier
+
+func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) {
+       v, ok := m[nameHash{name, hash}]
+       if !ok {
+               return nil, &UnknownVerifierError{name, hash}
+       }
+       if len(v) > 1 {
+               return nil, &ambiguousVerifierError{name, hash}
+       }
+       return v[0], nil
+}
+
+// A Note is a text and signatures.
+type Note struct {
+       Text           string      // text of note
+       Sigs           []Signature // verified signatures
+       UnverifiedSigs []Signature // unverified signatures
+}
+
+// A Signature is a single signature found in a note.
+type Signature struct {
+       // Name and Hash give the name and key hash
+       // for the key that generated the signature.
+       Name string
+       Hash uint32
+
+       // Base64 records the base64-encoded signature bytes.
+       Base64 string
+}
+
+// An UnverifiedNoteError indicates that the note
+// successfully parsed but had no verifiable signatures.
+type UnverifiedNoteError struct {
+       Note *Note
+}
+
+func (e *UnverifiedNoteError) Error() string {
+       return "note has no verifiable signatures"
+}
+
+// An InvalidSignatureError indicates that the given key was known
+// and the associated Verifier rejected the signature.
+type InvalidSignatureError struct {
+       Name string
+       Hash uint32
+}
+
+func (e *InvalidSignatureError) Error() string {
+       return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash)
+}
+
+var (
+       errMalformedNote = errors.New("malformed note")
+       errInvalidSigner = errors.New("invalid signer")
+
+       sigSplit  = []byte("\n\n")
+       sigPrefix = []byte("— ")
+)
+
+// Open opens and parses the message msg, checking signatures from the known verifiers.
+//
+// For each signature in the message, Open calls known.Verifier to find a verifier.
+// If known.Verifier returns a verifier and the verifier accepts the signature,
+// Open records the signature in the returned note's Sigs field.
+// If known.Verifier returns a verifier but the verifier rejects the signature,
+// Open returns an InvalidSignatureError.
+// If known.Verifier returns an UnknownVerifierError,
+// Open records the signature in the returned note's UnverifiedSigs field.
+// If known.Verifier returns any other error, Open returns that error.
+//
+// If no known verifier has signed an otherwise valid note,
+// Open returns an UnverifiedNoteError.
+// In this case, the unverified note can be fetched from inside the error.
+func Open(msg []byte, known Verifiers) (*Note, error) {
+       if known == nil {
+               // Treat nil Verifiers as empty list, to produce useful error instead of crash.
+               known = VerifierList()
+       }
+
+       // Must have valid UTF-8 with no non-newline ASCII control characters.
+       for i := 0; i < len(msg); {
+               r, size := utf8.DecodeRune(msg[i:])
+               if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 {
+                       return nil, errMalformedNote
+               }
+               i += size
+       }
+
+       // Must end with signature block preceded by blank line.
+       split := bytes.LastIndex(msg, sigSplit)
+       if split < 0 {
+               return nil, errMalformedNote
+       }
+       text, sigs := msg[:split+1], msg[split+2:]
+       if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' {
+               return nil, errMalformedNote
+       }
+
+       n := &Note{
+               Text: string(text),
+       }
+
+       // Parse and verify signatures.
+       // Ignore duplicate signatures.
+       seen := make(map[nameHash]bool)
+       seenUnverified := make(map[string]bool)
+       numSig := 0
+       for len(sigs) > 0 {
+               // Pull out next signature line.
+               // We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one.
+               i := bytes.IndexByte(sigs, '\n')
+               line := sigs[:i]
+               sigs = sigs[i+1:]
+
+               if !bytes.HasPrefix(line, sigPrefix) {
+                       return nil, errMalformedNote
+               }
+               line = line[len(sigPrefix):]
+               name, b64 := chop(string(line), " ")
+               sig, err := base64.StdEncoding.DecodeString(b64)
+               if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 {
+                       return nil, errMalformedNote
+               }
+               hash := binary.BigEndian.Uint32(sig[0:4])
+               sig = sig[4:]
+
+               if numSig++; numSig > 100 {
+                       // Avoid spending forever parsing a note with many signatures.
+                       return nil, errMalformedNote
+               }
+
+               v, err := known.Verifier(name, hash)
+               if _, ok := err.(*UnknownVerifierError); ok {
+                       // Drop repeated identical unverified signatures.
+                       if seenUnverified[string(line)] {
+                               continue
+                       }
+                       seenUnverified[string(line)] = true
+                       n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64})
+                       continue
+               }
+               if err != nil {
+                       return nil, err
+               }
+
+               // Drop repeated signatures by a single verifier.
+               if seen[nameHash{name, hash}] {
+                       continue
+               }
+               seen[nameHash{name, hash}] = true
+
+               ok := v.Verify(text, sig)
+               if !ok {
+                       return nil, &InvalidSignatureError{name, hash}
+               }
+
+               n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64})
+       }
+
+       // Parsed and verified all the signatures.
+       if len(n.Sigs) == 0 {
+               return nil, &UnverifiedNoteError{n}
+       }
+       return n, nil
+}
+
+// Sign signs the note with the given signers and returns the encoded message.
+// The new signatures from signers are listed in the encoded message after
+// the existing signatures already present in n.Sigs.
+// If any signer uses the same key as an existing signature,
+// the existing signature is elided from the output.
+func Sign(n *Note, signers ...Signer) ([]byte, error) {
+       var buf bytes.Buffer
+       if !strings.HasSuffix(n.Text, "\n") {
+               return nil, errMalformedNote
+       }
+       buf.WriteString(n.Text)
+
+       // Prepare signatures.
+       var sigs bytes.Buffer
+       have := make(map[nameHash]bool)
+       for _, s := range signers {
+               name := s.Name()
+               hash := s.KeyHash()
+               have[nameHash{name, hash}] = true
+               if !isValidName(name) {
+                       return nil, errInvalidSigner
+               }
+
+               sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
+               if err != nil {
+                       return nil, err
+               }
+
+               var hbuf [4]byte
+               binary.BigEndian.PutUint32(hbuf[:], hash)
+               b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
+               sigs.WriteString("— ")
+               sigs.WriteString(name)
+               sigs.WriteString(" ")
+               sigs.WriteString(b64)
+               sigs.WriteString("\n")
+       }
+
+       buf.WriteString("\n")
+
+       // Emit existing signatures not replaced by new ones.
+       for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
+               for _, sig := range list {
+                       name, hash := sig.Name, sig.Hash
+                       if !isValidName(name) {
+                               return nil, errMalformedNote
+                       }
+                       if have[nameHash{name, hash}] {
+                               continue
+                       }
+                       // Double-check hash against base64.
+                       raw, err := base64.StdEncoding.DecodeString(sig.Base64)
+                       if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
+                               return nil, errMalformedNote
+                       }
+                       buf.WriteString("— ")
+                       buf.WriteString(sig.Name)
+                       buf.WriteString(" ")
+                       buf.WriteString(sig.Base64)
+                       buf.WriteString("\n")
+               }
+       }
+       buf.Write(sigs.Bytes())
+
+       return buf.Bytes(), nil
+}