@@ -21,6 +21,7 @@ package note
21
21
import (
22
22
"bytes"
23
23
"context"
24
+ "crypto"
24
25
"crypto/ecdsa"
25
26
"crypto/ed25519"
26
27
"crypto/rsa"
@@ -67,6 +68,24 @@ func (n *noteSigner) Sign(msg []byte) ([]byte, error) {
67
68
return n .sign (msg )
68
69
}
69
70
71
+ type noteVerifier struct {
72
+ name string
73
+ hash uint32
74
+ verify func (msg , sig []byte ) bool
75
+ }
76
+
77
+ func (n * noteVerifier ) Name () string {
78
+ return n .name
79
+ }
80
+
81
+ func (n * noteVerifier ) KeyHash () uint32 {
82
+ return n .hash
83
+ }
84
+
85
+ func (n * noteVerifier ) Verify (msg , sig []byte ) bool {
86
+ return n .verify (msg , sig )
87
+ }
88
+
70
89
// isValidName reports whether the name conforms to the spec for the origin string of the note text
71
90
// as defined in https://github.com/C2SP/C2SP/blob/main/tlog-checkpoint.md#note-text.
72
91
func isValidName (name string ) bool {
@@ -112,32 +131,45 @@ func rsaKeyHash(name string, key *rsa.PublicKey) (uint32, error) {
112
131
return genConformantKeyHash (name , rsaAlg , marshaled ), nil
113
132
}
114
133
115
- // NewNoteSigner converts a sigstore/sigstore/pkg/signature.Signer into a note.Signer.
116
- func NewNoteSigner (ctx context.Context , origin string , signer signature.Signer ) (note.Signer , error ) {
117
- if ! isValidName (origin ) {
118
- return & noteSigner {}, fmt .Errorf ("invalid name %s" , origin )
119
- }
120
-
121
- pubKey , err := signer .PublicKey ()
122
- if err != nil {
123
- return & noteSigner {}, fmt .Errorf ("getting public key: %w" , err )
124
- }
134
+ // keyHash generates a 4-byte identifier for a public key/origin
135
+ func keyHash (origin string , key crypto.PublicKey ) (uint32 , error ) {
125
136
var keyID uint32
126
- switch pk := pubKey .(type ) {
137
+ var err error
138
+
139
+ switch pk := key .(type ) {
127
140
case * ecdsa.PublicKey :
128
141
keyID , err = ecdsaKeyHash (pk )
129
142
if err != nil {
130
- return & noteSigner {} , fmt .Errorf ("getting ECDSA key hash: %w" , err )
143
+ return 0 , fmt .Errorf ("getting ECDSA key hash: %w" , err )
131
144
}
132
145
case ed25519.PublicKey :
133
146
keyID = ed25519KeyHash (origin , pk )
134
147
case * rsa.PublicKey :
135
148
keyID , err = rsaKeyHash (origin , pk )
136
149
if err != nil {
137
- return & noteSigner {} , fmt .Errorf ("getting RSA key hash: %w" , err )
150
+ return 0 , fmt .Errorf ("getting RSA key hash: %w" , err )
138
151
}
139
152
default :
140
- return & noteSigner {}, fmt .Errorf ("unsupported key type: %T" , pubKey )
153
+ return 0 , fmt .Errorf ("unsupported key type: %T" , key )
154
+ }
155
+
156
+ return keyID , nil
157
+ }
158
+
159
+ // NewNoteSigner converts a sigstore/sigstore/pkg/signature.Signer into a note.Signer.
160
+ func NewNoteSigner (ctx context.Context , origin string , signer signature.Signer ) (note.Signer , error ) {
161
+ if ! isValidName (origin ) {
162
+ return nil , fmt .Errorf ("invalid name %s" , origin )
163
+ }
164
+
165
+ pubKey , err := signer .PublicKey ()
166
+ if err != nil {
167
+ return nil , fmt .Errorf ("getting public key: %w" , err )
168
+ }
169
+
170
+ keyID , err := keyHash (origin , pubKey )
171
+ if err != nil {
172
+ return nil , err
141
173
}
142
174
143
175
sign := func (msg []byte ) ([]byte , error ) {
@@ -150,3 +182,30 @@ func NewNoteSigner(ctx context.Context, origin string, signer signature.Signer)
150
182
sign : sign ,
151
183
}, nil
152
184
}
185
+
186
+ func NewNoteVerifier (origin string , verifier signature.Verifier ) (note.Verifier , error ) {
187
+ if ! isValidName (origin ) {
188
+ return nil , fmt .Errorf ("invalid name %s" , origin )
189
+ }
190
+
191
+ pubKey , err := verifier .PublicKey ()
192
+ if err != nil {
193
+ return nil , fmt .Errorf ("getting public key: %w" , err )
194
+ }
195
+
196
+ keyID , err := keyHash (origin , pubKey )
197
+ if err != nil {
198
+ return nil , err
199
+ }
200
+
201
+ return & noteVerifier {
202
+ name : origin ,
203
+ hash : keyID ,
204
+ verify : func (msg , sig []byte ) bool {
205
+ if err := verifier .VerifySignature (bytes .NewReader (sig ), bytes .NewReader (msg )); err != nil {
206
+ return false
207
+ }
208
+ return true
209
+ },
210
+ }, nil
211
+ }
0 commit comments