• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package note defines the notes signed by the Go module database server.
6//
7// A note is text signed by one or more server keys.
8// The text should be ignored unless the note is signed by
9// a trusted server key and the signature has been verified
10// using the server's public key.
11//
12// A server's public key is identified by a name, typically the "host[/path]"
13// giving the base URL of the server's transparency log.
14// The syntactic restrictions on a name are that it be non-empty,
15// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B).
16//
17// A Go module database server signs texts using public key cryptography.
18// A given server may have multiple public keys, each
19// identified by a 32-bit hash of the public key.
20//
21// # Verifying Notes
22//
23// A [Verifier] allows verification of signatures by one server public key.
24// It can report the name of the server and the uint32 hash of the key,
25// and it can verify a purported signature by that key.
26//
27// The standard implementation of a Verifier is constructed
28// by [NewVerifier] starting from a verifier key, which is a
29// plain text string of the form "<name>+<hash>+<keydata>".
30//
31// A [Verifiers] allows looking up a Verifier by the combination
32// of server name and key hash.
33//
34// The standard implementation of a Verifiers is constructed
35// by VerifierList from a list of known verifiers.
36//
37// A [Note] represents a text with one or more signatures.
38// An implementation can reject a note with too many signatures
39// (for example, more than 100 signatures).
40//
41// A [Signature] represents a signature on a note, verified or not.
42//
43// The [Open] function takes as input a signed message
44// and a set of known verifiers. It decodes and verifies
45// the message signatures and returns a [Note] structure
46// containing the message text and (verified or unverified) signatures.
47//
48// # Signing Notes
49//
50// A [Signer] allows signing a text with a given key.
51// It can report the name of the server and the hash of the key
52// and can sign a raw text using that key.
53//
54// The standard implementation of a Signer is constructed
55// by [NewSigner] starting from an encoded signer key, which is a
56// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
57// Anyone with an encoded signer key can sign messages using that key,
58// so it must be kept secret. The encoding begins with the literal text
59// "PRIVATE+KEY" to avoid confusion with the public server key.
60//
61// The [Sign] function takes as input a Note and a list of Signers
62// and returns an encoded, signed message.
63//
64// # Signed Note Format
65//
66// A signed note consists of a text ending in newline (U+000A),
67// followed by a blank line (only a newline),
68// followed by one or more signature lines of this form:
69// em dash (U+2014), space (U+0020),
70// server name, space, base64-encoded signature, newline.
71//
72// Signed notes must be valid UTF-8 and must not contain any
73// ASCII control characters (those below U+0020) other than newline.
74//
75// A signature is a base64 encoding of 4+n bytes.
76//
77// The first four bytes in the signature are the uint32 key hash
78// stored in big-endian order.
79//
80// The remaining n bytes are the result of using the specified key
81// to sign the note text (including the final newline but not the
82// separating blank line).
83//
84// # Generating Keys
85//
86// There is only one key type, Ed25519 with algorithm identifier 1.
87// New key types may be introduced in the future as needed,
88// although doing so will require deploying the new algorithms to all clients
89// before starting to depend on them for signatures.
90//
91// The [GenerateKey] function generates and returns a new signer
92// and corresponding verifier.
93//
94// # Example
95//
96// Here is a well-formed signed note:
97//
98//	If you think cryptography is the answer to your problem,
99//	then you don't know what your problem is.
100//
101//	— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
102//
103// It can be constructed and displayed using:
104//
105//	skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
106//	text := "If you think cryptography is the answer to your problem,\n" +
107//		"then you don't know what your problem is.\n"
108//
109//	signer, err := note.NewSigner(skey)
110//	if err != nil {
111//		log.Fatal(err)
112//	}
113//
114//	msg, err := note.Sign(&note.Note{Text: text}, signer)
115//	if err != nil {
116//		log.Fatal(err)
117//	}
118//	os.Stdout.Write(msg)
119//
120// The note's text is two lines, including the final newline,
121// and the text is purportedly signed by a server named
122// "PeterNeumann". (Although server names are canonically
123// base URLs, the only syntactic requirement is that they
124// not contain spaces or newlines).
125//
126// If [Open] is given access to a [Verifiers] including the
127// [Verifier] for this key, then it will succeed at verifying
128// the encoded message and returning the parsed [Note]:
129//
130//	vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
131//	msg := []byte("If you think cryptography is the answer to your problem,\n" +
132//		"then you don't know what your problem is.\n" +
133//		"\n" +
134//		"— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n")
135//
136//	verifier, err := note.NewVerifier(vkey)
137//	if err != nil {
138//		log.Fatal(err)
139//	}
140//	verifiers := note.VerifierList(verifier)
141//
142//	n, err := note.Open([]byte(msg), verifiers)
143//	if err != nil {
144//		log.Fatal(err)
145//	}
146//	fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text)
147//
148// You can add your own signature to this message by re-signing the note:
149//
150//	skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot")
151//	if err != nil {
152//		log.Fatal(err)
153//	}
154//	_ = vkey // give to verifiers
155//
156//	me, err := note.NewSigner(skey)
157//	if err != nil {
158//		log.Fatal(err)
159//	}
160//
161//	msg, err := note.Sign(n, me)
162//	if err != nil {
163//		log.Fatal(err)
164//	}
165//	os.Stdout.Write(msg)
166//
167// This will print a doubly-signed message, like:
168//
169//	If you think cryptography is the answer to your problem,
170//	then you don't know what your problem is.
171//
172//	— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
173//	— EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=
174package note
175
176import (
177	"bytes"
178	"crypto/ed25519"
179	"crypto/sha256"
180	"encoding/base64"
181	"encoding/binary"
182	"errors"
183	"fmt"
184	"io"
185	"strconv"
186	"strings"
187	"unicode"
188	"unicode/utf8"
189)
190
191// A Verifier verifies messages signed with a specific key.
192type Verifier interface {
193	// Name returns the server name associated with the key.
194	Name() string
195
196	// KeyHash returns the key hash.
197	KeyHash() uint32
198
199	// Verify reports whether sig is a valid signature of msg.
200	Verify(msg, sig []byte) bool
201}
202
203// A Signer signs messages using a specific key.
204type Signer interface {
205	// Name returns the server name associated with the key.
206	Name() string
207
208	// KeyHash returns the key hash.
209	KeyHash() uint32
210
211	// Sign returns a signature for the given message.
212	Sign(msg []byte) ([]byte, error)
213}
214
215// keyHash computes the key hash for the given server name and encoded public key.
216func keyHash(name string, key []byte) uint32 {
217	h := sha256.New()
218	h.Write([]byte(name))
219	h.Write([]byte("\n"))
220	h.Write(key)
221	sum := h.Sum(nil)
222	return binary.BigEndian.Uint32(sum)
223}
224
225var (
226	errVerifierID   = errors.New("malformed verifier id")
227	errVerifierAlg  = errors.New("unknown verifier algorithm")
228	errVerifierHash = errors.New("invalid verifier hash")
229)
230
231const (
232	algEd25519 = 1
233)
234
235// isValidName reports whether name is valid.
236// It must be non-empty and not have any Unicode spaces or pluses.
237func isValidName(name string) bool {
238	return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
239}
240
241// NewVerifier construct a new [Verifier] from an encoded verifier key.
242func NewVerifier(vkey string) (Verifier, error) {
243	name, vkey := chop(vkey, "+")
244	hash16, key64 := chop(vkey, "+")
245	hash, err1 := strconv.ParseUint(hash16, 16, 32)
246	key, err2 := base64.StdEncoding.DecodeString(key64)
247	if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
248		return nil, errVerifierID
249	}
250	if uint32(hash) != keyHash(name, key) {
251		return nil, errVerifierHash
252	}
253
254	v := &verifier{
255		name: name,
256		hash: uint32(hash),
257	}
258
259	alg, key := key[0], key[1:]
260	switch alg {
261	default:
262		return nil, errVerifierAlg
263
264	case algEd25519:
265		if len(key) != 32 {
266			return nil, errVerifierID
267		}
268		v.verify = func(msg, sig []byte) bool {
269			return ed25519.Verify(key, msg, sig)
270		}
271	}
272
273	return v, nil
274}
275
276// chop chops s at the first instance of sep, if any,
277// and returns the text before and after sep.
278// If sep is not present, chop returns before is s and after is empty.
279func chop(s, sep string) (before, after string) {
280	i := strings.Index(s, sep)
281	if i < 0 {
282		return s, ""
283	}
284	return s[:i], s[i+len(sep):]
285}
286
287// verifier is a trivial Verifier implementation.
288type verifier struct {
289	name   string
290	hash   uint32
291	verify func([]byte, []byte) bool
292}
293
294func (v *verifier) Name() string                { return v.name }
295func (v *verifier) KeyHash() uint32             { return v.hash }
296func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
297
298// NewSigner constructs a new [Signer] from an encoded signer key.
299func NewSigner(skey string) (Signer, error) {
300	priv1, skey := chop(skey, "+")
301	priv2, skey := chop(skey, "+")
302	name, skey := chop(skey, "+")
303	hash16, key64 := chop(skey, "+")
304	hash, err1 := strconv.ParseUint(hash16, 16, 32)
305	key, err2 := base64.StdEncoding.DecodeString(key64)
306	if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
307		return nil, errSignerID
308	}
309
310	// Note: hash is the hash of the public key and we have the private key.
311	// Must verify hash after deriving public key.
312
313	s := &signer{
314		name: name,
315		hash: uint32(hash),
316	}
317
318	var pubkey []byte
319
320	alg, key := key[0], key[1:]
321	switch alg {
322	default:
323		return nil, errSignerAlg
324
325	case algEd25519:
326		if len(key) != 32 {
327			return nil, errSignerID
328		}
329		key = ed25519.NewKeyFromSeed(key)
330		pubkey = append([]byte{algEd25519}, key[32:]...)
331		s.sign = func(msg []byte) ([]byte, error) {
332			return ed25519.Sign(key, msg), nil
333		}
334	}
335
336	if uint32(hash) != keyHash(name, pubkey) {
337		return nil, errSignerHash
338	}
339
340	return s, nil
341}
342
343var (
344	errSignerID   = errors.New("malformed verifier id")
345	errSignerAlg  = errors.New("unknown verifier algorithm")
346	errSignerHash = errors.New("invalid verifier hash")
347)
348
349// signer is a trivial Signer implementation.
350type signer struct {
351	name string
352	hash uint32
353	sign func([]byte) ([]byte, error)
354}
355
356func (s *signer) Name() string                    { return s.name }
357func (s *signer) KeyHash() uint32                 { return s.hash }
358func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) }
359
360// GenerateKey generates a signer and verifier key pair for a named server.
361// The signer key skey is private and must be kept secret.
362func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) {
363	pub, priv, err := ed25519.GenerateKey(rand)
364	if err != nil {
365		return "", "", err
366	}
367	pubkey := append([]byte{algEd25519}, pub...)
368	privkey := append([]byte{algEd25519}, priv.Seed()...)
369	h := keyHash(name, pubkey)
370
371	skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey))
372	vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey))
373	return skey, vkey, nil
374}
375
376// NewEd25519VerifierKey returns an encoded verifier key using the given name
377// and Ed25519 public key.
378func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) {
379	if len(key) != ed25519.PublicKeySize {
380		return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize)
381	}
382
383	pubkey := append([]byte{algEd25519}, key...)
384	hash := keyHash(name, pubkey)
385
386	b64Key := base64.StdEncoding.EncodeToString(pubkey)
387	return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil
388}
389
390// A Verifiers is a collection of known verifier keys.
391type Verifiers interface {
392	// Verifier returns the Verifier associated with the key
393	// identified by the name and hash.
394	// If the name, hash pair is unknown, Verifier should return
395	// an UnknownVerifierError.
396	Verifier(name string, hash uint32) (Verifier, error)
397}
398
399// An UnknownVerifierError indicates that the given key is not known.
400// The Open function records signatures without associated verifiers as
401// unverified signatures.
402type UnknownVerifierError struct {
403	Name    string
404	KeyHash uint32
405}
406
407func (e *UnknownVerifierError) Error() string {
408	return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash)
409}
410
411// An ambiguousVerifierError indicates that the given name and hash
412// match multiple keys passed to [VerifierList].
413// (If this happens, some malicious actor has taken control of the
414// verifier list, at which point we may as well give up entirely,
415// but we diagnose the problem instead.)
416type ambiguousVerifierError struct {
417	name string
418	hash uint32
419}
420
421func (e *ambiguousVerifierError) Error() string {
422	return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
423}
424
425// VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
426func VerifierList(list ...Verifier) Verifiers {
427	m := make(verifierMap)
428	for _, v := range list {
429		k := nameHash{v.Name(), v.KeyHash()}
430		m[k] = append(m[k], v)
431	}
432	return m
433}
434
435type nameHash struct {
436	name string
437	hash uint32
438}
439
440type verifierMap map[nameHash][]Verifier
441
442func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) {
443	v, ok := m[nameHash{name, hash}]
444	if !ok {
445		return nil, &UnknownVerifierError{name, hash}
446	}
447	if len(v) > 1 {
448		return nil, &ambiguousVerifierError{name, hash}
449	}
450	return v[0], nil
451}
452
453// A Note is a text and signatures.
454type Note struct {
455	Text           string      // text of note
456	Sigs           []Signature // verified signatures
457	UnverifiedSigs []Signature // unverified signatures
458}
459
460// A Signature is a single signature found in a note.
461type Signature struct {
462	// Name and Hash give the name and key hash
463	// for the key that generated the signature.
464	Name string
465	Hash uint32
466
467	// Base64 records the base64-encoded signature bytes.
468	Base64 string
469}
470
471// An UnverifiedNoteError indicates that the note
472// successfully parsed but had no verifiable signatures.
473type UnverifiedNoteError struct {
474	Note *Note
475}
476
477func (e *UnverifiedNoteError) Error() string {
478	return "note has no verifiable signatures"
479}
480
481// An InvalidSignatureError indicates that the given key was known
482// and the associated Verifier rejected the signature.
483type InvalidSignatureError struct {
484	Name string
485	Hash uint32
486}
487
488func (e *InvalidSignatureError) Error() string {
489	return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash)
490}
491
492var (
493	errMalformedNote      = errors.New("malformed note")
494	errInvalidSigner      = errors.New("invalid signer")
495	errMismatchedVerifier = errors.New("verifier name or hash doesn't match signature")
496
497	sigSplit  = []byte("\n\n")
498	sigPrefix = []byte("— ")
499)
500
501// Open opens and parses the message msg, checking signatures from the known verifiers.
502//
503// For each signature in the message, Open calls known.Verifier to find a verifier.
504// If known.Verifier returns a verifier and the verifier accepts the signature,
505// Open records the signature in the returned note's Sigs field.
506// If known.Verifier returns a verifier but the verifier rejects the signature,
507// Open returns an InvalidSignatureError.
508// If known.Verifier returns an UnknownVerifierError,
509// Open records the signature in the returned note's UnverifiedSigs field.
510// If known.Verifier returns any other error, Open returns that error.
511//
512// If no known verifier has signed an otherwise valid note,
513// Open returns an [UnverifiedNoteError].
514// In this case, the unverified note can be fetched from inside the error.
515func Open(msg []byte, known Verifiers) (*Note, error) {
516	if known == nil {
517		// Treat nil Verifiers as empty list, to produce useful error instead of crash.
518		known = VerifierList()
519	}
520
521	// Must have valid UTF-8 with no non-newline ASCII control characters.
522	for i := 0; i < len(msg); {
523		r, size := utf8.DecodeRune(msg[i:])
524		if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 {
525			return nil, errMalformedNote
526		}
527		i += size
528	}
529
530	// Must end with signature block preceded by blank line.
531	split := bytes.LastIndex(msg, sigSplit)
532	if split < 0 {
533		return nil, errMalformedNote
534	}
535	text, sigs := msg[:split+1], msg[split+2:]
536	if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' {
537		return nil, errMalformedNote
538	}
539
540	n := &Note{
541		Text: string(text),
542	}
543
544	// Parse and verify signatures.
545	// Ignore duplicate signatures.
546	seen := make(map[nameHash]bool)
547	seenUnverified := make(map[string]bool)
548	numSig := 0
549	for len(sigs) > 0 {
550		// Pull out next signature line.
551		// We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one.
552		i := bytes.IndexByte(sigs, '\n')
553		line := sigs[:i]
554		sigs = sigs[i+1:]
555
556		if !bytes.HasPrefix(line, sigPrefix) {
557			return nil, errMalformedNote
558		}
559		line = line[len(sigPrefix):]
560		name, b64 := chop(string(line), " ")
561		sig, err := base64.StdEncoding.DecodeString(b64)
562		if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 {
563			return nil, errMalformedNote
564		}
565		hash := binary.BigEndian.Uint32(sig[0:4])
566		sig = sig[4:]
567
568		if numSig++; numSig > 100 {
569			// Avoid spending forever parsing a note with many signatures.
570			return nil, errMalformedNote
571		}
572
573		v, err := known.Verifier(name, hash)
574		if _, ok := err.(*UnknownVerifierError); ok {
575			// Drop repeated identical unverified signatures.
576			if seenUnverified[string(line)] {
577				continue
578			}
579			seenUnverified[string(line)] = true
580			n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64})
581			continue
582		}
583		if err != nil {
584			return nil, err
585		}
586
587		// Check that known.Verifier returned the right verifier.
588		if v.Name() != name || v.KeyHash() != hash {
589			return nil, errMismatchedVerifier
590		}
591
592		// Drop repeated signatures by a single verifier.
593		if seen[nameHash{name, hash}] {
594			continue
595		}
596		seen[nameHash{name, hash}] = true
597
598		ok := v.Verify(text, sig)
599		if !ok {
600			return nil, &InvalidSignatureError{name, hash}
601		}
602
603		n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64})
604	}
605
606	// Parsed and verified all the signatures.
607	if len(n.Sigs) == 0 {
608		return nil, &UnverifiedNoteError{n}
609	}
610	return n, nil
611}
612
613// Sign signs the note with the given signers and returns the encoded message.
614// The new signatures from signers are listed in the encoded message after
615// the existing signatures already present in n.Sigs.
616// If any signer uses the same key as an existing signature,
617// the existing signature is elided from the output.
618func Sign(n *Note, signers ...Signer) ([]byte, error) {
619	var buf bytes.Buffer
620	if !strings.HasSuffix(n.Text, "\n") {
621		return nil, errMalformedNote
622	}
623	buf.WriteString(n.Text)
624
625	// Prepare signatures.
626	var sigs bytes.Buffer
627	have := make(map[nameHash]bool)
628	for _, s := range signers {
629		name := s.Name()
630		hash := s.KeyHash()
631		have[nameHash{name, hash}] = true
632		if !isValidName(name) {
633			return nil, errInvalidSigner
634		}
635
636		sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
637		if err != nil {
638			return nil, err
639		}
640
641		var hbuf [4]byte
642		binary.BigEndian.PutUint32(hbuf[:], hash)
643		b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
644		sigs.WriteString("— ")
645		sigs.WriteString(name)
646		sigs.WriteString(" ")
647		sigs.WriteString(b64)
648		sigs.WriteString("\n")
649	}
650
651	buf.WriteString("\n")
652
653	// Emit existing signatures not replaced by new ones.
654	for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
655		for _, sig := range list {
656			name, hash := sig.Name, sig.Hash
657			if !isValidName(name) {
658				return nil, errMalformedNote
659			}
660			if have[nameHash{name, hash}] {
661				continue
662			}
663			// Double-check hash against base64.
664			raw, err := base64.StdEncoding.DecodeString(sig.Base64)
665			if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
666				return nil, errMalformedNote
667			}
668			buf.WriteString("— ")
669			buf.WriteString(sig.Name)
670			buf.WriteString(" ")
671			buf.WriteString(sig.Base64)
672			buf.WriteString("\n")
673		}
674	}
675	buf.Write(sigs.Bytes())
676
677	return buf.Bytes(), nil
678}
679