-
Notifications
You must be signed in to change notification settings - Fork 2
/
key.go
108 lines (95 loc) · 2.89 KB
/
key.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
// Copyright 2014 Robert A. Uhl. All rights reserved.
// Use of this source code is governed by an MIT-style license which may
// be found in the LICENSE file.
package spki
import (
"fmt"
"github.com/eadmund/sexprs"
)
type Key interface {
// Returns true if the key is just a hash.
IsHash() bool
// Returns the public key for the key: the key itself, if it's
// already a public key; a public version of the key, if it's
// a private key; or nil, if it is a hash without a key.
PublicKey() (*PublicKey)
// Returns the hash value of the key under a particular
// algorithm, or an error if the key is just a hash and the
// specified algorithm is not the algorithm used to generate
// it.
Hashed(algorithm string) ([]byte, error)
// Returns the hash value of the key as per Hashed, but as a
// Hash object.
HashExp(algorithm string) (Hash, error)
// Returns the SPKI signature algorithm of the key,
// e.g. "ecdsa-sha256". May be the empty string if unknown.
SignatureAlgorithm() string
// Returns the SPKI hash algorithm the key uses in signing,
// e.g. "sha256". May be the empty string if unknown.
HashAlgorithm() string
Equal(Key) bool
Sexp() sexprs.Sexp
String() string
}
// A HashKey is just the hash value(s) of a key, without any public or
// private component; as such, it can only report its value under its
// own algorithm(s), and cannot be used to sign or verify anything.
type HashKey struct {
Hashes []Hash
}
func (h HashKey) IsHash() bool {
return true
}
func (h HashKey) PublicKey() *PublicKey {
return nil
}
func (h HashKey) Hashed(algorithm string) ([]byte, error) {
hash, err := h.HashExp(algorithm)
return hash.Hash, err
}
func (h HashKey) String() string {
if len(h.Hashes) == 0 {
return ""
}
return h.Hashes[0].String()
}
func (h HashKey) HashExp(algorithm string) (hh Hash, err error) {
for _, hash := range h.Hashes {
if hash.Algorithm == algorithm {
return hash, nil
}
}
return hh, fmt.Errorf("No hash found for algorithm %s", algorithm)
}
// Hashed keys never have any known signature algorithm.
func (h HashKey) SignatureAlgorithm() string {
return ""
}
// Hashed keys never have any known hash algorithm.
func (h HashKey) HashAlgorithm() string {
return ""
}
// BUG(eadmund): rather than returning the first stored hash, return
// the 'best' for some value of.
func (h HashKey) Subject() sexprs.Sexp {
if h.Hashes == nil || len(h.Hashes) == 0 {
return nil
}
return sexprs.List{sexprs.Atom{Value: []byte("subject")}, h.Hashes[0].Sexp()}
}
func (h HashKey) Equal(k Key) bool {
fmt.Println("hashkey", h.String(), fmt.Sprintf("%#v", h), "key", k.String())
if k == nil {
return false
}
for _, hash1 := range h.Hashes {
// can never return an error because we know algorithm is good
fmt.Println(")", hash1.String())
hash2, _ := k.HashExp(hash1.Algorithm)
fmt.Println(">", hash2.String())
if hash1.Equal(hash2) {
return true
}
}
return false
}