Source file src/cmd/vendor/golang.org/x/mod/sumdb/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  // 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=
   174  package note
   175  
   176  import (
   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.
   192  type 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.
   204  type 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.
   216  func 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  
   225  var (
   226  	errVerifierID   = errors.New("malformed verifier id")
   227  	errVerifierAlg  = errors.New("unknown verifier algorithm")
   228  	errVerifierHash = errors.New("invalid verifier hash")
   229  )
   230  
   231  const (
   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.
   237  func 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.
   242  func NewVerifier(vkey string) (Verifier, error) {
   243  	name, vkey, _ := strings.Cut(vkey, "+")
   244  	hash16, key64, _ := strings.Cut(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  // verifier is a trivial Verifier implementation.
   277  type verifier struct {
   278  	name   string
   279  	hash   uint32
   280  	verify func([]byte, []byte) bool
   281  }
   282  
   283  func (v *verifier) Name() string                { return v.name }
   284  func (v *verifier) KeyHash() uint32             { return v.hash }
   285  func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
   286  
   287  // NewSigner constructs a new [Signer] from an encoded signer key.
   288  func NewSigner(skey string) (Signer, error) {
   289  	priv1, skey, _ := strings.Cut(skey, "+")
   290  	priv2, skey, _ := strings.Cut(skey, "+")
   291  	name, skey, _ := strings.Cut(skey, "+")
   292  	hash16, key64, _ := strings.Cut(skey, "+")
   293  	hash, err1 := strconv.ParseUint(hash16, 16, 32)
   294  	key, err2 := base64.StdEncoding.DecodeString(key64)
   295  	if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
   296  		return nil, errSignerID
   297  	}
   298  
   299  	// Note: hash is the hash of the public key and we have the private key.
   300  	// Must verify hash after deriving public key.
   301  
   302  	s := &signer{
   303  		name: name,
   304  		hash: uint32(hash),
   305  	}
   306  
   307  	var pubkey []byte
   308  
   309  	alg, key := key[0], key[1:]
   310  	switch alg {
   311  	default:
   312  		return nil, errSignerAlg
   313  
   314  	case algEd25519:
   315  		if len(key) != 32 {
   316  			return nil, errSignerID
   317  		}
   318  		key = ed25519.NewKeyFromSeed(key)
   319  		pubkey = append([]byte{algEd25519}, key[32:]...)
   320  		s.sign = func(msg []byte) ([]byte, error) {
   321  			return ed25519.Sign(key, msg), nil
   322  		}
   323  	}
   324  
   325  	if uint32(hash) != keyHash(name, pubkey) {
   326  		return nil, errSignerHash
   327  	}
   328  
   329  	return s, nil
   330  }
   331  
   332  var (
   333  	errSignerID   = errors.New("malformed verifier id")
   334  	errSignerAlg  = errors.New("unknown verifier algorithm")
   335  	errSignerHash = errors.New("invalid verifier hash")
   336  )
   337  
   338  // signer is a trivial Signer implementation.
   339  type signer struct {
   340  	name string
   341  	hash uint32
   342  	sign func([]byte) ([]byte, error)
   343  }
   344  
   345  func (s *signer) Name() string                    { return s.name }
   346  func (s *signer) KeyHash() uint32                 { return s.hash }
   347  func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) }
   348  
   349  // GenerateKey generates a signer and verifier key pair for a named server.
   350  // The signer key skey is private and must be kept secret.
   351  func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) {
   352  	pub, priv, err := ed25519.GenerateKey(rand)
   353  	if err != nil {
   354  		return "", "", err
   355  	}
   356  	pubkey := append([]byte{algEd25519}, pub...)
   357  	privkey := append([]byte{algEd25519}, priv.Seed()...)
   358  	h := keyHash(name, pubkey)
   359  
   360  	skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey))
   361  	vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey))
   362  	return skey, vkey, nil
   363  }
   364  
   365  // NewEd25519VerifierKey returns an encoded verifier key using the given name
   366  // and Ed25519 public key.
   367  func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) {
   368  	if len(key) != ed25519.PublicKeySize {
   369  		return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize)
   370  	}
   371  
   372  	pubkey := append([]byte{algEd25519}, key...)
   373  	hash := keyHash(name, pubkey)
   374  
   375  	b64Key := base64.StdEncoding.EncodeToString(pubkey)
   376  	return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil
   377  }
   378  
   379  // A Verifiers is a collection of known verifier keys.
   380  type Verifiers interface {
   381  	// Verifier returns the Verifier associated with the key
   382  	// identified by the name and hash.
   383  	// If the name, hash pair is unknown, Verifier should return
   384  	// an UnknownVerifierError.
   385  	Verifier(name string, hash uint32) (Verifier, error)
   386  }
   387  
   388  // An UnknownVerifierError indicates that the given key is not known.
   389  // The Open function records signatures without associated verifiers as
   390  // unverified signatures.
   391  type UnknownVerifierError struct {
   392  	Name    string
   393  	KeyHash uint32
   394  }
   395  
   396  func (e *UnknownVerifierError) Error() string {
   397  	return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash)
   398  }
   399  
   400  // An ambiguousVerifierError indicates that the given name and hash
   401  // match multiple keys passed to [VerifierList].
   402  // (If this happens, some malicious actor has taken control of the
   403  // verifier list, at which point we may as well give up entirely,
   404  // but we diagnose the problem instead.)
   405  type ambiguousVerifierError struct {
   406  	name string
   407  	hash uint32
   408  }
   409  
   410  func (e *ambiguousVerifierError) Error() string {
   411  	return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
   412  }
   413  
   414  // VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
   415  func VerifierList(list ...Verifier) Verifiers {
   416  	m := make(verifierMap)
   417  	for _, v := range list {
   418  		k := nameHash{v.Name(), v.KeyHash()}
   419  		m[k] = append(m[k], v)
   420  	}
   421  	return m
   422  }
   423  
   424  type nameHash struct {
   425  	name string
   426  	hash uint32
   427  }
   428  
   429  type verifierMap map[nameHash][]Verifier
   430  
   431  func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) {
   432  	v, ok := m[nameHash{name, hash}]
   433  	if !ok {
   434  		return nil, &UnknownVerifierError{name, hash}
   435  	}
   436  	if len(v) > 1 {
   437  		return nil, &ambiguousVerifierError{name, hash}
   438  	}
   439  	return v[0], nil
   440  }
   441  
   442  // A Note is a text and signatures.
   443  type Note struct {
   444  	Text           string      // text of note
   445  	Sigs           []Signature // verified signatures
   446  	UnverifiedSigs []Signature // unverified signatures
   447  }
   448  
   449  // A Signature is a single signature found in a note.
   450  type Signature struct {
   451  	// Name and Hash give the name and key hash
   452  	// for the key that generated the signature.
   453  	Name string
   454  	Hash uint32
   455  
   456  	// Base64 records the base64-encoded signature bytes.
   457  	Base64 string
   458  }
   459  
   460  // An UnverifiedNoteError indicates that the note
   461  // successfully parsed but had no verifiable signatures.
   462  type UnverifiedNoteError struct {
   463  	Note *Note
   464  }
   465  
   466  func (e *UnverifiedNoteError) Error() string {
   467  	return "note has no verifiable signatures"
   468  }
   469  
   470  // An InvalidSignatureError indicates that the given key was known
   471  // and the associated Verifier rejected the signature.
   472  type InvalidSignatureError struct {
   473  	Name string
   474  	Hash uint32
   475  }
   476  
   477  func (e *InvalidSignatureError) Error() string {
   478  	return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash)
   479  }
   480  
   481  var (
   482  	errMalformedNote      = errors.New("malformed note")
   483  	errInvalidSigner      = errors.New("invalid signer")
   484  	errMismatchedVerifier = errors.New("verifier name or hash doesn't match signature")
   485  
   486  	sigSplit  = []byte("\n\n")
   487  	sigPrefix = []byte("— ")
   488  )
   489  
   490  // Open opens and parses the message msg, checking signatures from the known verifiers.
   491  //
   492  // For each signature in the message, Open calls known.Verifier to find a verifier.
   493  // If known.Verifier returns a verifier and the verifier accepts the signature,
   494  // Open records the signature in the returned note's Sigs field.
   495  // If known.Verifier returns a verifier but the verifier rejects the signature,
   496  // Open returns an InvalidSignatureError.
   497  // If known.Verifier returns an UnknownVerifierError,
   498  // Open records the signature in the returned note's UnverifiedSigs field.
   499  // If known.Verifier returns any other error, Open returns that error.
   500  //
   501  // If no known verifier has signed an otherwise valid note,
   502  // Open returns an [UnverifiedNoteError].
   503  // In this case, the unverified note can be fetched from inside the error.
   504  func Open(msg []byte, known Verifiers) (*Note, error) {
   505  	if known == nil {
   506  		// Treat nil Verifiers as empty list, to produce useful error instead of crash.
   507  		known = VerifierList()
   508  	}
   509  
   510  	// Must have valid UTF-8 with no non-newline ASCII control characters.
   511  	for i := 0; i < len(msg); {
   512  		r, size := utf8.DecodeRune(msg[i:])
   513  		if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 {
   514  			return nil, errMalformedNote
   515  		}
   516  		i += size
   517  	}
   518  
   519  	// Must end with signature block preceded by blank line.
   520  	split := bytes.LastIndex(msg, sigSplit)
   521  	if split < 0 {
   522  		return nil, errMalformedNote
   523  	}
   524  	text, sigs := msg[:split+1], msg[split+2:]
   525  	if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' {
   526  		return nil, errMalformedNote
   527  	}
   528  
   529  	n := &Note{
   530  		Text: string(text),
   531  	}
   532  
   533  	// Parse and verify signatures.
   534  	// Ignore duplicate signatures.
   535  	seen := make(map[nameHash]bool)
   536  	seenUnverified := make(map[string]bool)
   537  	numSig := 0
   538  	for len(sigs) > 0 {
   539  		// Pull out next signature line.
   540  		// We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one.
   541  		i := bytes.IndexByte(sigs, '\n')
   542  		line := sigs[:i]
   543  		sigs = sigs[i+1:]
   544  
   545  		if !bytes.HasPrefix(line, sigPrefix) {
   546  			return nil, errMalformedNote
   547  		}
   548  		line = line[len(sigPrefix):]
   549  		name, b64, _ := strings.Cut(string(line), " ")
   550  		sig, err := base64.StdEncoding.DecodeString(b64)
   551  		if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 {
   552  			return nil, errMalformedNote
   553  		}
   554  		hash := binary.BigEndian.Uint32(sig[0:4])
   555  		sig = sig[4:]
   556  
   557  		if numSig++; numSig > 100 {
   558  			// Avoid spending forever parsing a note with many signatures.
   559  			return nil, errMalformedNote
   560  		}
   561  
   562  		v, err := known.Verifier(name, hash)
   563  		if _, ok := err.(*UnknownVerifierError); ok {
   564  			// Drop repeated identical unverified signatures.
   565  			if seenUnverified[string(line)] {
   566  				continue
   567  			}
   568  			seenUnverified[string(line)] = true
   569  			n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64})
   570  			continue
   571  		}
   572  		if err != nil {
   573  			return nil, err
   574  		}
   575  
   576  		// Check that known.Verifier returned the right verifier.
   577  		if v.Name() != name || v.KeyHash() != hash {
   578  			return nil, errMismatchedVerifier
   579  		}
   580  
   581  		// Drop repeated signatures by a single verifier.
   582  		if seen[nameHash{name, hash}] {
   583  			continue
   584  		}
   585  		seen[nameHash{name, hash}] = true
   586  
   587  		ok := v.Verify(text, sig)
   588  		if !ok {
   589  			return nil, &InvalidSignatureError{name, hash}
   590  		}
   591  
   592  		n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64})
   593  	}
   594  
   595  	// Parsed and verified all the signatures.
   596  	if len(n.Sigs) == 0 {
   597  		return nil, &UnverifiedNoteError{n}
   598  	}
   599  	return n, nil
   600  }
   601  
   602  // Sign signs the note with the given signers and returns the encoded message.
   603  // The new signatures from signers are listed in the encoded message after
   604  // the existing signatures already present in n.Sigs.
   605  // If any signer uses the same key as an existing signature,
   606  // the existing signature is elided from the output.
   607  func Sign(n *Note, signers ...Signer) ([]byte, error) {
   608  	var buf bytes.Buffer
   609  	if !strings.HasSuffix(n.Text, "\n") {
   610  		return nil, errMalformedNote
   611  	}
   612  	buf.WriteString(n.Text)
   613  
   614  	// Prepare signatures.
   615  	var sigs bytes.Buffer
   616  	have := make(map[nameHash]bool)
   617  	for _, s := range signers {
   618  		name := s.Name()
   619  		hash := s.KeyHash()
   620  		have[nameHash{name, hash}] = true
   621  		if !isValidName(name) {
   622  			return nil, errInvalidSigner
   623  		}
   624  
   625  		sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
   626  		if err != nil {
   627  			return nil, err
   628  		}
   629  
   630  		var hbuf [4]byte
   631  		binary.BigEndian.PutUint32(hbuf[:], hash)
   632  		b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
   633  		sigs.WriteString("— ")
   634  		sigs.WriteString(name)
   635  		sigs.WriteString(" ")
   636  		sigs.WriteString(b64)
   637  		sigs.WriteString("\n")
   638  	}
   639  
   640  	buf.WriteString("\n")
   641  
   642  	// Emit existing signatures not replaced by new ones.
   643  	for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
   644  		for _, sig := range list {
   645  			name, hash := sig.Name, sig.Hash
   646  			if !isValidName(name) {
   647  				return nil, errMalformedNote
   648  			}
   649  			if have[nameHash{name, hash}] {
   650  				continue
   651  			}
   652  			// Double-check hash against base64.
   653  			raw, err := base64.StdEncoding.DecodeString(sig.Base64)
   654  			if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
   655  				return nil, errMalformedNote
   656  			}
   657  			buf.WriteString("— ")
   658  			buf.WriteString(sig.Name)
   659  			buf.WriteString(" ")
   660  			buf.WriteString(sig.Base64)
   661  			buf.WriteString("\n")
   662  		}
   663  	}
   664  	buf.Write(sigs.Bytes())
   665  
   666  	return buf.Bytes(), nil
   667  }
   668  

View as plain text