1 package jwk
2
3 import (
4 "crypto"
5 "crypto/rsa"
6 "encoding/binary"
7 "fmt"
8 "math/big"
9
10 "github.com/lestrrat-go/blackmagic"
11 "github.com/lestrrat-go/jwx/internal/base64"
12 "github.com/lestrrat-go/jwx/internal/pool"
13 "github.com/pkg/errors"
14 )
15
16 func (k *rsaPrivateKey) FromRaw(rawKey *rsa.PrivateKey) error {
17 k.mu.Lock()
18 defer k.mu.Unlock()
19
20 d, err := bigIntToBytes(rawKey.D)
21 if err != nil {
22 return errors.Wrap(err, `invalid rsa.PrivateKey`)
23 }
24 k.d = d
25
26 l := len(rawKey.Primes)
27
28 if l < 0 || l > 2 {
29 return fmt.Errorf(`invalid number of primes in rsa.PrivateKey: need 0 to 2, but got %d`, len(rawKey.Primes))
30 }
31
32 if l > 0 {
33 p, err := bigIntToBytes(rawKey.Primes[0])
34 if err != nil {
35 return fmt.Errorf(`invalid rsa.PrivateKey: %w`, err)
36 }
37 k.p = p
38 }
39
40 if l > 1 {
41 q, err := bigIntToBytes(rawKey.Primes[1])
42 if err != nil {
43 return fmt.Errorf(`invalid rsa.PrivateKey: %w`, err)
44 }
45 k.q = q
46 }
47
48
49 if v, err := bigIntToBytes(rawKey.Precomputed.Dp); err == nil {
50 k.dp = v
51 }
52 if v, err := bigIntToBytes(rawKey.Precomputed.Dq); err == nil {
53 k.dq = v
54 }
55 if v, err := bigIntToBytes(rawKey.Precomputed.Qinv); err == nil {
56 k.qi = v
57 }
58
59
60 n, e, err := rsaPublicKeyByteValuesFromRaw(&rawKey.PublicKey)
61 if err != nil {
62 return errors.Wrap(err, `invalid rsa.PrivateKey`)
63 }
64 k.n = n
65 k.e = e
66
67 return nil
68 }
69
70 func rsaPublicKeyByteValuesFromRaw(rawKey *rsa.PublicKey) ([]byte, []byte, error) {
71 n, err := bigIntToBytes(rawKey.N)
72 if err != nil {
73 return nil, nil, errors.Wrap(err, `invalid rsa.PublicKey`)
74 }
75
76 data := make([]byte, 8)
77 binary.BigEndian.PutUint64(data, uint64(rawKey.E))
78 i := 0
79 for ; i < len(data); i++ {
80 if data[i] != 0x0 {
81 break
82 }
83 }
84 return n, data[i:], nil
85 }
86
87 func (k *rsaPublicKey) FromRaw(rawKey *rsa.PublicKey) error {
88 k.mu.Lock()
89 defer k.mu.Unlock()
90
91 n, e, err := rsaPublicKeyByteValuesFromRaw(rawKey)
92 if err != nil {
93 return errors.Wrap(err, `invalid rsa.PrivateKey`)
94 }
95 k.n = n
96 k.e = e
97
98 return nil
99 }
100
101 func (k *rsaPrivateKey) Raw(v interface{}) error {
102 k.mu.RLock()
103 defer k.mu.RUnlock()
104
105 var d, q, p big.Int
106
107 d.SetBytes(k.d)
108 q.SetBytes(k.q)
109 p.SetBytes(k.p)
110
111
112 var dp, dq, qi *big.Int
113 if len(k.dp) > 0 {
114 dp = &big.Int{}
115 dp.SetBytes(k.dp)
116 }
117
118 if len(k.dq) > 0 {
119 dq = &big.Int{}
120 dq.SetBytes(k.dq)
121 }
122
123 if len(k.qi) > 0 {
124 qi = &big.Int{}
125 qi.SetBytes(k.qi)
126 }
127
128 var key rsa.PrivateKey
129
130 pubk := newRSAPublicKey()
131 pubk.n = k.n
132 pubk.e = k.e
133 if err := pubk.Raw(&key.PublicKey); err != nil {
134 return errors.Wrap(err, `failed to materialize RSA public key`)
135 }
136
137 key.D = &d
138 key.Primes = []*big.Int{&p, &q}
139
140 if dp != nil {
141 key.Precomputed.Dp = dp
142 }
143 if dq != nil {
144 key.Precomputed.Dq = dq
145 }
146 if qi != nil {
147 key.Precomputed.Qinv = qi
148 }
149 key.Precomputed.CRTValues = []rsa.CRTValue{}
150
151 return blackmagic.AssignIfCompatible(v, &key)
152 }
153
154
155
156 func (k *rsaPublicKey) Raw(v interface{}) error {
157 k.mu.RLock()
158 defer k.mu.RUnlock()
159
160 var key rsa.PublicKey
161
162 n := pool.GetBigInt()
163 e := pool.GetBigInt()
164 defer pool.ReleaseBigInt(e)
165
166 n.SetBytes(k.n)
167 e.SetBytes(k.e)
168
169 key.N = n
170 key.E = int(e.Int64())
171
172 return blackmagic.AssignIfCompatible(v, &key)
173 }
174
175 func makeRSAPublicKey(v interface {
176 makePairs() []*HeaderPair
177 }) (Key, error) {
178 newKey := NewRSAPublicKey()
179
180
181 for _, pair := range v.makePairs() {
182 switch pair.Key {
183 case RSADKey, RSADPKey, RSADQKey, RSAPKey, RSAQKey, RSAQIKey:
184 continue
185 default:
186
187 key := pair.Key.(string)
188 if err := newKey.Set(key, pair.Value); err != nil {
189 return nil, errors.Wrapf(err, `failed to set field %q`, key)
190 }
191 }
192 }
193
194 return newKey, nil
195 }
196
197 func (k *rsaPrivateKey) PublicKey() (Key, error) {
198 return makeRSAPublicKey(k)
199 }
200
201 func (k *rsaPublicKey) PublicKey() (Key, error) {
202 return makeRSAPublicKey(k)
203 }
204
205
206
207 func (k rsaPrivateKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
208 k.mu.RLock()
209 defer k.mu.RUnlock()
210
211 var key rsa.PrivateKey
212 if err := k.Raw(&key); err != nil {
213 return nil, errors.Wrap(err, `failed to materialize RSA private key`)
214 }
215 return rsaThumbprint(hash, &key.PublicKey)
216 }
217
218 func (k rsaPublicKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
219 k.mu.RLock()
220 defer k.mu.RUnlock()
221
222 var key rsa.PublicKey
223 if err := k.Raw(&key); err != nil {
224 return nil, errors.Wrap(err, `failed to materialize RSA public key`)
225 }
226 return rsaThumbprint(hash, &key)
227 }
228
229 func rsaThumbprint(hash crypto.Hash, key *rsa.PublicKey) ([]byte, error) {
230 buf := pool.GetBytesBuffer()
231 defer pool.ReleaseBytesBuffer(buf)
232
233 buf.WriteString(`{"e":"`)
234 buf.WriteString(base64.EncodeUint64ToString(uint64(key.E)))
235 buf.WriteString(`","kty":"RSA","n":"`)
236 buf.WriteString(base64.EncodeToString(key.N.Bytes()))
237 buf.WriteString(`"}`)
238
239 h := hash.New()
240 if _, err := buf.WriteTo(h); err != nil {
241 return nil, errors.Wrap(err, "failed to write rsaThumbprint")
242 }
243 return h.Sum(nil), nil
244 }
245
View as plain text