...

Source file src/pkg/cmd/go/internal/note/note.go

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

View as plain text