Skip to content

Commit 9039c6c

Browse files
committed
feat: Tidy up key logic
1 parent 67969a1 commit 9039c6c

6 files changed

Lines changed: 340 additions & 298 deletions

File tree

canonicalize.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func canonicalizeSignatureParams(out io.Writer, sp *signatureParams) error {
9696
type signatureParams struct {
9797
items []string
9898
keyID string
99-
alg string
99+
alg Algorithm
100100
created time.Time
101101
expires *time.Time
102102
nonce *string
@@ -168,7 +168,7 @@ func parseSignatureInput(in string) (*signatureParams, error) {
168168
// TODO: error when not wrapped in quotes
169169
switch paramParts[0] {
170170
case "alg":
171-
sp.alg = strings.Trim(paramParts[1], `"`)
171+
sp.alg = Algorithm(strings.Trim(paramParts[1], `"`))
172172
case "keyid":
173173
sp.keyID = strings.Trim(paramParts[1], `"`)
174174
case "nonce":

example_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,41 @@ func Example_round_trip() {
4646
// Output:
4747
// 200 OK
4848
}
49+
50+
type testKeyResolver struct{}
51+
52+
func (r *testKeyResolver) Resolve(keyID string, alg httpsig.Algorithm) (httpsig.VerifyingKey, error) {
53+
return &httpsig.HmacSha256VerifyingKey{Secret: []byte(secret)}, nil
54+
}
55+
56+
func Example_round_trip_resolver() {
57+
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
58+
w.Header().Set("Content-Type", "text/plain")
59+
_, _ = io.WriteString(w, "Your request has a valid signature!")
60+
})
61+
62+
middleware := httpsig.NewVerifyMiddleware(httpsig.WithVerifyingKeyResolver(&testKeyResolver{}))
63+
http.Handle("/resolver", middleware(h))
64+
go func() { _ = http.ListenAndServe("127.0.0.1:1234", http.DefaultServeMux) }()
65+
66+
// Give the server time to sleep. Terrible, I know.
67+
time.Sleep(100 * time.Millisecond)
68+
69+
client := http.Client{
70+
// Wrap the transport:
71+
Transport: httpsig.NewSignTransport(http.DefaultTransport,
72+
httpsig.WithHmacSha256("key1", []byte(secret))),
73+
}
74+
75+
resp, err := client.Get("http://127.0.0.1:1234/")
76+
if err != nil {
77+
fmt.Println("got err: ", err)
78+
return
79+
}
80+
defer resp.Body.Close()
81+
82+
fmt.Println(resp.Status)
83+
84+
// Output:
85+
// 200 OK
86+
}

httpsig.go

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ func sliceHas(haystack []string, needle string) bool {
2727
return false
2828
}
2929

30+
type Algorithm string
31+
32+
const (
33+
AlgorithmRsaPkcs1v15Sha256 Algorithm = "rsa-v1_5-sha256"
34+
AlgorithmRsaPssSha512 Algorithm = "rsa-pss-sha512"
35+
AlgorithmEcdsaP256Sha256 Algorithm = "ecdsa-p256-sha256"
36+
AlgorithmEcdsaP384Sha384 Algorithm = "ecdsa-p384-sha384"
37+
AlgorithmEd25519 Algorithm = "ed25519"
38+
AlgorithmHmacSha256 Algorithm = "hmac-sha256"
39+
)
40+
41+
type SigningKey interface {
42+
Sign(data []byte) ([]byte, error)
43+
Algorithm() Algorithm
44+
Nonce() *string
45+
}
46+
3047
type Signer struct {
3148
*signer
3249
}
@@ -87,10 +104,11 @@ func (s *Signer) Sign(r *http.Request) error {
87104

88105
type VerifyingKey interface {
89106
Verify(data []byte, signature []byte) error
107+
Algorithm() Algorithm
90108
}
91109

92110
type VerifyingKeyResolver interface {
93-
Resolve(keyID string) VerifyingKey
111+
Resolve(keyID string, alg Algorithm) (VerifyingKey, error)
94112
}
95113

96114
type Verifier struct {
@@ -235,87 +253,87 @@ func WithVerifyingKeyResolver(resolver VerifyingKeyResolver) verifyOption {
235253
// using the given key id.
236254
func WithSignRsaPkcs1v15Sha256(keyID string, pk *rsa.PrivateKey) signOption {
237255
return &optImpl{
238-
s: func(s *signer) { s.keys.Store(keyID, signRsaPkcs1v15Sha256(pk)) },
256+
s: func(s *signer) { s.keys.Store(keyID, &RsaPkcs1v15Sha256SigningKey{pk}) },
239257
}
240258
}
241259

242260
// WithVerifyRsaPkcs1v15Sha256 adds signature verification using `rsa-v1_5-sha256` with the
243261
// given public key using the given key id.
244262
func WithVerifyRsaPkcs1v15Sha256(keyID string, pk *rsa.PublicKey) verifyOption {
245263
return &optImpl{
246-
v: func(v *verifier) { v.keys.Store(keyID, verifyRsaPkcs1v15Sha256(pk)) },
264+
v: func(v *verifier) { v.keys.Store(keyID, &RsaPkcs1v15Sha256VerifyingKey{pk}) },
247265
}
248266
}
249267

250268
// WithSignRsaPssSha512 adds signing using `rsa-pss-sha512` with the given private key
251269
// using the given key id.
252270
func WithSignRsaPssSha512(keyID string, pk *rsa.PrivateKey) signOption {
253271
return &optImpl{
254-
s: func(s *signer) { s.keys.Store(keyID, signRsaPssSha512(pk)) },
272+
s: func(s *signer) { s.keys.Store(keyID, &RsaPssSha512SigningKey{pk}) },
255273
}
256274
}
257275

258276
// WithVerifyRsaPssSha512 adds signature verification using `rsa-pss-sha512` with the
259277
// given public key using the given key id.
260278
func WithVerifyRsaPssSha512(keyID string, pk *rsa.PublicKey) verifyOption {
261279
return &optImpl{
262-
v: func(v *verifier) { v.keys.Store(keyID, verifyRsaPssSha512(pk)) },
280+
v: func(v *verifier) { v.keys.Store(keyID, &RsaPssSha512VerifyingKey{pk}) },
263281
}
264282
}
265283

266284
// WithSignEcdsaP256Sha256 adds signing using `ecdsa-p256-sha256` with the given private key
267285
// using the given key id.
268286
func WithSignEcdsaP256Sha256(keyID string, pk *ecdsa.PrivateKey) signOption {
269287
return &optImpl{
270-
s: func(s *signer) { s.keys.Store(keyID, signEccP256(pk)) },
288+
s: func(s *signer) { s.keys.Store(keyID, &EcdsaP256SigningKey{pk}) },
271289
}
272290
}
273291

274292
// WithVerifyEcdsaP256Sha256 adds signature verification using `ecdsa-p256-sha256` with the
275293
// given public key using the given key id.
276294
func WithVerifyEcdsaP256Sha256(keyID string, pk *ecdsa.PublicKey) verifyOption {
277295
return &optImpl{
278-
v: func(v *verifier) { v.keys.Store(keyID, verifyEccP256(pk)) },
296+
v: func(v *verifier) { v.keys.Store(keyID, &EcdsaP256VerifyingKey{pk}) },
279297
}
280298
}
281299

282300
// WithSignEcdsaP384Sha384 adds signing using `ecdsa-p384-sha384` with the given private key
283301
// using the given key id.
284302
func WithSignEcdsaP384Sha384(keyID string, pk *ecdsa.PrivateKey) signOption {
285303
return &optImpl{
286-
s: func(s *signer) { s.keys.Store(keyID, signEccP384(pk)) },
304+
s: func(s *signer) { s.keys.Store(keyID, &EcdsaP384SigningKey{pk}) },
287305
}
288306
}
289307

290308
// WithVerifyEcdsaP384Sha384 adds signature verification using `ecdsa-p384-sha384` with the
291309
// given public key using the given key id.
292310
func WithVerifyEcdsaP384Sha384(keyID string, pk *ecdsa.PublicKey) verifyOption {
293311
return &optImpl{
294-
v: func(v *verifier) { v.keys.Store(keyID, verifyEccP384(pk)) },
312+
v: func(v *verifier) { v.keys.Store(keyID, &EcdsaP384VerifyingKey{pk}) },
295313
}
296314
}
297315

298316
// WithSignEd25519 adds signing using `ed25519` with the given private key
299317
// using the given key id.
300-
func WithSignEd25519(keyID string, pk *ed25519.PrivateKey) signOption {
318+
func WithSignEd25519(keyID string, pk ed25519.PrivateKey) signOption {
301319
return &optImpl{
302-
s: func(s *signer) { s.keys.Store(keyID, signEd25519(pk)) },
320+
s: func(s *signer) { s.keys.Store(keyID, &Ed25519SigningKey{pk}) },
303321
}
304322
}
305323

306324
// WithVerifyEd25519 adds signature verification using `ed25519` with the
307325
// given public key using the given key id.
308-
func WithVerifyEd25519(keyID string, pk *ed25519.PublicKey) verifyOption {
326+
func WithVerifyEd25519(keyID string, pk ed25519.PublicKey) verifyOption {
309327
return &optImpl{
310-
v: func(v *verifier) { v.keys.Store(keyID, verifyEd25519(pk)) },
328+
v: func(v *verifier) { v.keys.Store(keyID, &Ed25519VerifyingKey{pk}) },
311329
}
312330
}
313331

314332
// WithHmacSha256 adds signing or signature verification using `hmac-sha256` with the
315333
// given shared secret using the given key id.
316334
func WithHmacSha256(keyID string, secret []byte) signOrVerifyOption {
317335
return &optImpl{
318-
s: func(s *signer) { s.keys.Store(keyID, signHmacSha256(secret)) },
319-
v: func(v *verifier) { v.keys.Store(keyID, verifyHmacSha256(secret)) },
336+
s: func(s *signer) { s.keys.Store(keyID, &HmacSha256SigningKey{Secret: secret}) },
337+
v: func(v *verifier) { v.keys.Store(keyID, &HmacSha256VerifyingKey{Secret: secret}) },
320338
}
321339
}

0 commit comments

Comments
 (0)