...
1 package jws
2
3 import (
4 "crypto"
5 "crypto/ed25519"
6 "crypto/rand"
7
8 "github.com/lestrrat-go/jwx/internal/keyconv"
9 "github.com/lestrrat-go/jwx/jwa"
10 "github.com/pkg/errors"
11 )
12
13 type eddsaSigner struct{}
14
15 func newEdDSASigner() Signer {
16 return &eddsaSigner{}
17 }
18
19 func (s eddsaSigner) Algorithm() jwa.SignatureAlgorithm {
20 return jwa.EdDSA
21 }
22
23 func (s eddsaSigner) Sign(payload []byte, key interface{}) ([]byte, error) {
24 if key == nil {
25 return nil, errors.New(`missing private key while signing payload`)
26 }
27
28
29
30 signer, ok := key.(crypto.Signer)
31 if !ok {
32
33
34 var privkey ed25519.PrivateKey
35 if err := keyconv.Ed25519PrivateKey(&privkey, key); err != nil {
36 return nil, errors.Wrapf(err, `failed to retrieve ed25519.PrivateKey out of %T`, key)
37 }
38 signer = privkey
39 }
40 return signer.Sign(rand.Reader, payload, crypto.Hash(0))
41 }
42
43 type eddsaVerifier struct{}
44
45 func newEdDSAVerifier() Verifier {
46 return &eddsaVerifier{}
47 }
48
49 func (v eddsaVerifier) Verify(payload, signature []byte, key interface{}) (err error) {
50 if key == nil {
51 return errors.New(`missing public key while verifying payload`)
52 }
53
54 var pubkey ed25519.PublicKey
55 signer, ok := key.(crypto.Signer)
56 if ok {
57 v := signer.Public()
58 pubkey, ok = v.(ed25519.PublicKey)
59 if !ok {
60 return errors.Errorf(`expected crypto.Signer.Public() to return ed25519.PublicKey, but got %T`, v)
61 }
62 } else {
63 if err := keyconv.Ed25519PublicKey(&pubkey, key); err != nil {
64 return errors.Wrapf(err, `failed to retrieve ed25519.PublicKey out of %T`, key)
65 }
66 }
67
68 if !ed25519.Verify(pubkey, payload, signature) {
69 return errors.New(`failed to match EdDSA signature`)
70 }
71
72 return nil
73 }
74
View as plain text