|
1 | 1 | package jwt_signer
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "crypto" |
| 5 | + "crypto/ecdsa" |
| 6 | + "crypto/rsa" |
4 | 7 | "errors"
|
5 | 8 | "github.com/domsolutions/gopayloader/pkgs/jwt-signer/definition"
|
6 |
| - "github.com/domsolutions/gopayloader/pkgs/jwt-signer/ecdsa" |
7 |
| - ed25519 "github.com/domsolutions/gopayloader/pkgs/jwt-signer/ed25519" |
8 |
| - "github.com/domsolutions/gopayloader/pkgs/jwt-signer/rsa256" |
9 |
| - rsa512 "github.com/domsolutions/gopayloader/pkgs/jwt-signer/rsa512" |
| 9 | + "github.com/golang-jwt/jwt" |
| 10 | + "github.com/pterm/pterm" |
10 | 11 | )
|
11 | 12 |
|
12 |
| -type Signer func(privKey []byte, kid string) (definition.Signer, error) |
| 13 | +func CreateSigner(privKey []byte, kid string) (definition.Signer, error) { |
| 14 | + var signer definition.Signer |
13 | 15 |
|
14 |
| -// TODO add more signers, use generics? |
| 16 | + signer, err := createSigner[*ecdsa.PrivateKey](privKey, kid, jwt.ParseECPrivateKeyFromPEM, jwt.SigningMethodES256) |
| 17 | + if err == nil { |
| 18 | + return signer, nil |
| 19 | + } |
| 20 | + signer, err = createSigner[*ecdsa.PrivateKey](privKey, kid, jwt.ParseECPrivateKeyFromPEM, jwt.SigningMethodES384) |
| 21 | + if err == nil { |
| 22 | + return signer, nil |
| 23 | + } |
| 24 | + signer, err = createSigner[*ecdsa.PrivateKey](privKey, kid, jwt.ParseECPrivateKeyFromPEM, jwt.SigningMethodES512) |
| 25 | + if err == nil { |
| 26 | + return signer, nil |
| 27 | + } |
| 28 | + signer, err = createSigner[crypto.PrivateKey](privKey, kid, jwt.ParseEdPrivateKeyFromPEM, jwt.SigningMethodEdDSA) |
| 29 | + if err == nil { |
| 30 | + return signer, nil |
| 31 | + } |
| 32 | + signer, err = createSigner[*rsa.PrivateKey](privKey, kid, jwt.ParseRSAPrivateKeyFromPEM, jwt.SigningMethodRS512) |
| 33 | + if err == nil { |
| 34 | + return signer, nil |
| 35 | + } |
| 36 | + signer, err = createSigner[*rsa.PrivateKey](privKey, kid, jwt.ParseRSAPrivateKeyFromPEM, jwt.SigningMethodRS256) |
| 37 | + if err == nil { |
| 38 | + return signer, nil |
| 39 | + } |
| 40 | + signer, err = createSigner[*rsa.PrivateKey](privKey, kid, jwt.ParseRSAPrivateKeyFromPEM, jwt.SigningMethodRS384) |
| 41 | + if err == nil { |
| 42 | + return signer, nil |
| 43 | + } |
15 | 44 |
|
16 |
| -var signers = []Signer{ecdsa.Signer, ed25519.Signer, rsa256.Signer, rsa512.Signer} |
| 45 | + signer, err = createSigner[[]byte](privKey, kid, func(key []byte) ([]byte, error) { |
| 46 | + return key, nil |
| 47 | + }, jwt.SigningMethodHS256) |
| 48 | + if err == nil { |
| 49 | + return signer, nil |
| 50 | + } |
17 | 51 |
|
18 |
| -func CreateSigner(privKey []byte, kid string) (definition.Signer, error) { |
19 |
| - var signer definition.Signer |
20 |
| - var err error |
21 |
| - for _, s := range signers { |
22 |
| - signer, err = s(privKey, kid) |
23 |
| - if err != nil { |
24 |
| - continue |
25 |
| - } |
| 52 | + signer, err = createSigner[[]byte](privKey, kid, func(key []byte) ([]byte, error) { |
| 53 | + return key, nil |
| 54 | + }, jwt.SigningMethodHS384) |
| 55 | + if err == nil { |
| 56 | + return signer, nil |
| 57 | + } |
| 58 | + |
| 59 | + signer, err = createSigner[[]byte](privKey, kid, func(key []byte) ([]byte, error) { |
| 60 | + return key, nil |
| 61 | + }, jwt.SigningMethodHS512) |
| 62 | + if err == nil { |
26 | 63 | return signer, nil
|
27 | 64 | }
|
28 | 65 |
|
29 | 66 | return nil, errors.New("no supported jwt signer")
|
30 | 67 | }
|
| 68 | + |
| 69 | +type signer struct { |
| 70 | + kid string |
| 71 | + privKey any |
| 72 | + method jwt.SigningMethod |
| 73 | +} |
| 74 | + |
| 75 | +func (e *signer) Generate(claims jwt.MapClaims) (string, error) { |
| 76 | + token := jwt.NewWithClaims(e.method, claims) |
| 77 | + token.Header["kid"] = e.kid |
| 78 | + |
| 79 | + t, err := token.SignedString(e.privKey) |
| 80 | + if err != nil { |
| 81 | + return "", err |
| 82 | + } |
| 83 | + return t, nil |
| 84 | +} |
| 85 | + |
| 86 | +func createSigner[k any](privKey []byte, kid string, genPrivKey func(key []byte) (k, error), method jwt.SigningMethod) (definition.Signer, error) { |
| 87 | + key, err := genPrivKey(privKey) |
| 88 | + if err != nil { |
| 89 | + pterm.Debug.Printf("Failed to parse private key %v", err) |
| 90 | + return nil, err |
| 91 | + } |
| 92 | + |
| 93 | + s := &signer{ |
| 94 | + kid: kid, |
| 95 | + privKey: key, |
| 96 | + method: method, |
| 97 | + } |
| 98 | + claim := make(jwt.MapClaims) |
| 99 | + claim["test"] = true |
| 100 | + if _, err := s.Generate(claim); err != nil { |
| 101 | + pterm.Debug.Printf("Failed to generate jwt %v", err) |
| 102 | + return nil, err |
| 103 | + } |
| 104 | + return s, nil |
| 105 | +} |
0 commit comments