1
20
21 package jwksx
22
23 import (
24 "crypto"
25 "crypto/ecdsa"
26 "crypto/elliptic"
27 "crypto/rand"
28 "crypto/rsa"
29 "crypto/x509"
30 "io"
31
32 "github.com/pkg/errors"
33
34 "github.com/google/uuid"
35 "github.com/square/go-jose/v3"
36 "golang.org/x/crypto/ed25519"
37 )
38
39
40 func GenerateSigningKeys(id, alg string, bits int) (*jose.JSONWebKeySet, error) {
41 if id == "" {
42 id = uuid.New().String()
43 }
44
45 key, err := generate(jose.SignatureAlgorithm(alg), bits)
46 if err != nil {
47 return nil, err
48 }
49
50 return &jose.JSONWebKeySet{
51 Keys: []jose.JSONWebKey{
52 {
53 Algorithm: alg,
54 Use: "sig",
55 Key: key,
56 KeyID: id,
57 Certificates: []*x509.Certificate{},
58 },
59 },
60 }, nil
61 }
62
63
64 func GenerateSigningKeysAvailableAlgorithms() []string {
65 return []string{
66 string(jose.HS256), string(jose.HS384), string(jose.HS512),
67 string(jose.ES256), string(jose.ES384), string(jose.ES512), string(jose.EdDSA),
68 string(jose.RS256), string(jose.RS384), string(jose.RS512), string(jose.PS256), string(jose.PS384), string(jose.PS512),
69 }
70 }
71
72
73 func generate(alg jose.SignatureAlgorithm, bits int) (crypto.PrivateKey, error) {
74 switch alg {
75 case jose.ES256, jose.ES384, jose.ES512, jose.EdDSA:
76 keylen := map[jose.SignatureAlgorithm]int{
77 jose.ES256: 256,
78 jose.ES384: 384,
79 jose.ES512: 521,
80 jose.EdDSA: 256,
81 }
82 if bits != 0 && bits != keylen[alg] {
83 return nil, errors.Errorf(`jwksx: "%s" does not support arbitrary key length`, alg)
84 }
85 case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
86 if bits == 0 {
87 bits = 2048
88 }
89 if bits < 2048 {
90 return nil, errors.Errorf(`jwksx: key size must be at least 2048 bit for algorithm "%s"`, alg)
91 }
92 case jose.HS256:
93 if bits == 0 {
94 bits = 256
95 }
96 if bits < 256 {
97 return nil, errors.Errorf(`jwksx: key size must be at least 256 bit for algorithm "%s"`, alg)
98 }
99 case jose.HS384:
100 if bits == 0 {
101 bits = 384
102 }
103 if bits < 384 {
104 return nil, errors.Errorf(`jwksx: key size must be at least 2038448 bit for algorithm "%s"`, alg)
105 }
106 case jose.HS512:
107 if bits == 0 {
108 bits = 1024
109 }
110 if bits < 512 {
111 return nil, errors.Errorf(`jwksx: key size must be at least 512 bit for algorithm "%s"`, alg)
112 }
113 }
114
115 switch alg {
116 case jose.ES256:
117
118 key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
119 return key, errors.Wrapf(err, "jwks: unable to generate key")
120 case jose.ES384:
121
122 key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
123 return key, errors.Wrapf(err, "jwks: unable to generate key")
124 case jose.ES512:
125
126 key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
127 return key, errors.Wrapf(err, "jwks: unable to generate key")
128 case jose.EdDSA:
129 _, key, err := ed25519.GenerateKey(rand.Reader)
130 return key, errors.Wrapf(err, "jwks: unable to generate key")
131 case jose.RS256, jose.RS384, jose.RS512, jose.PS256, jose.PS384, jose.PS512:
132 key, err := rsa.GenerateKey(rand.Reader, bits)
133 return key, errors.Wrapf(err, "jwks: unable to generate key")
134 case jose.HS256, jose.HS384, jose.HS512:
135 if bits%8 != 0 {
136 return nil, errors.Errorf(`jwksx: key size must be a multiple of 8 for algorithm "%s" but got: %d`, alg, bits)
137 }
138
139 key := make([]byte, bits/8)
140 if _, err := io.ReadFull(rand.Reader, key); err != nil {
141 return nil, errors.Wrapf(err, "jwks: unable to generate key")
142 }
143 return key, nil
144 default:
145 return nil, errors.Errorf(`jwksx: available algorithms are "%+v" but unknown algorithm was requested: "%s"`, GenerateSigningKeysAvailableAlgorithms(), alg)
146 }
147 }
148
View as plain text