Source file src/pkg/cmd/go/internal/note/note.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
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
200 type Verifier interface {
201
202 Name() string
203
204
205 KeyHash() uint32
206
207
208 Verify(msg, sig []byte) bool
209 }
210
211
212 type Signer interface {
213
214 Name() string
215
216
217 KeyHash() uint32
218
219
220 Sign(msg []byte) ([]byte, error)
221 }
222
223
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
244
245 func isValidName(name string) bool {
246 return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
247 }
248
249
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
285
286
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
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
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
319
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
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
369
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
385
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
399 type Verifiers interface {
400
401
402
403
404 Verifier(name string, hash uint32) (Verifier, error)
405 }
406
407
408
409
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
420
421
422
423
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
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
462 type Note struct {
463 Text string
464 Sigs []Signature
465 UnverifiedSigs []Signature
466 }
467
468
469 type Signature struct {
470
471
472 Name string
473 Hash uint32
474
475
476 Base64 string
477 }
478
479
480
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
490
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
509
510
511
512
513
514
515
516
517
518
519
520
521
522 func Open(msg []byte, known Verifiers) (*Note, error) {
523 if known == nil {
524
525 known = VerifierList()
526 }
527
528
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
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
555
556 seen := make(map[nameHash]bool)
557 seenUnverified := make(map[string]bool)
558 numSig := 0
559 for len(sigs) > 0 {
560
561
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
580 return nil, errMalformedNote
581 }
582
583 v, err := known.Verifier(name, hash)
584 if _, ok := err.(*UnknownVerifierError); ok {
585
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
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
612 if len(n.Sigs) == 0 {
613 return nil, &UnverifiedNoteError{n}
614 }
615 return n, nil
616 }
617
618
619
620
621
622
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
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())
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
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
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