blob: dac4cacf20ef1f2342e0f856b51a3abb0af38bbf [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001package libtrust
2
3import (
4 "crypto"
5 "crypto/rand"
6 "crypto/rsa"
7 "crypto/x509"
8 "encoding/json"
9 "encoding/pem"
10 "errors"
11 "fmt"
12 "io"
13 "math/big"
14)
15
16/*
17 * RSA DSA PUBLIC KEY
18 */
19
20// rsaPublicKey implements a JWK Public Key using RSA digital signature algorithms.
21type rsaPublicKey struct {
22 *rsa.PublicKey
23 extended map[string]interface{}
24}
25
26func fromRSAPublicKey(cryptoPublicKey *rsa.PublicKey) *rsaPublicKey {
27 return &rsaPublicKey{cryptoPublicKey, map[string]interface{}{}}
28}
29
30// KeyType returns the JWK key type for RSA keys, i.e., "RSA".
31func (k *rsaPublicKey) KeyType() string {
32 return "RSA"
33}
34
35// KeyID returns a distinct identifier which is unique to this Public Key.
36func (k *rsaPublicKey) KeyID() string {
37 return keyIDFromCryptoKey(k)
38}
39
40func (k *rsaPublicKey) String() string {
41 return fmt.Sprintf("RSA Public Key <%s>", k.KeyID())
42}
43
44// Verify verifyies the signature of the data in the io.Reader using this Public Key.
45// The alg parameter should be the name of the JWA digital signature algorithm
46// which was used to produce the signature and should be supported by this
47// public key. Returns a nil error if the signature is valid.
48func (k *rsaPublicKey) Verify(data io.Reader, alg string, signature []byte) error {
49 // Verify the signature of the given date, return non-nil error if valid.
50 sigAlg, err := rsaSignatureAlgorithmByName(alg)
51 if err != nil {
52 return fmt.Errorf("unable to verify Signature: %s", err)
53 }
54
55 hasher := sigAlg.HashID().New()
56 _, err = io.Copy(hasher, data)
57 if err != nil {
58 return fmt.Errorf("error reading data to sign: %s", err)
59 }
60 hash := hasher.Sum(nil)
61
62 err = rsa.VerifyPKCS1v15(k.PublicKey, sigAlg.HashID(), hash, signature)
63 if err != nil {
64 return fmt.Errorf("invalid %s signature: %s", sigAlg.HeaderParam(), err)
65 }
66
67 return nil
68}
69
70// CryptoPublicKey returns the internal object which can be used as a
71// crypto.PublicKey for use with other standard library operations. The type
72// is either *rsa.PublicKey or *ecdsa.PublicKey
73func (k *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
74 return k.PublicKey
75}
76
77func (k *rsaPublicKey) toMap() map[string]interface{} {
78 jwk := make(map[string]interface{})
79 for k, v := range k.extended {
80 jwk[k] = v
81 }
82 jwk["kty"] = k.KeyType()
83 jwk["kid"] = k.KeyID()
84 jwk["n"] = joseBase64UrlEncode(k.N.Bytes())
85 jwk["e"] = joseBase64UrlEncode(serializeRSAPublicExponentParam(k.E))
86
87 return jwk
88}
89
90// MarshalJSON serializes this Public Key using the JWK JSON serialization format for
91// RSA keys.
92func (k *rsaPublicKey) MarshalJSON() (data []byte, err error) {
93 return json.Marshal(k.toMap())
94}
95
96// PEMBlock serializes this Public Key to DER-encoded PKIX format.
97func (k *rsaPublicKey) PEMBlock() (*pem.Block, error) {
98 derBytes, err := x509.MarshalPKIXPublicKey(k.PublicKey)
99 if err != nil {
100 return nil, fmt.Errorf("unable to serialize RSA PublicKey to DER-encoded PKIX format: %s", err)
101 }
102 k.extended["kid"] = k.KeyID() // For display purposes.
103 return createPemBlock("PUBLIC KEY", derBytes, k.extended)
104}
105
106func (k *rsaPublicKey) AddExtendedField(field string, value interface{}) {
107 k.extended[field] = value
108}
109
110func (k *rsaPublicKey) GetExtendedField(field string) interface{} {
111 v, ok := k.extended[field]
112 if !ok {
113 return nil
114 }
115 return v
116}
117
118func rsaPublicKeyFromMap(jwk map[string]interface{}) (*rsaPublicKey, error) {
119 // JWK key type (kty) has already been determined to be "RSA".
120 // Need to extract 'n', 'e', and 'kid' and check for
121 // consistency.
122
123 // Get the modulus parameter N.
124 nB64Url, err := stringFromMap(jwk, "n")
125 if err != nil {
126 return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err)
127 }
128
129 n, err := parseRSAModulusParam(nB64Url)
130 if err != nil {
131 return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err)
132 }
133
134 // Get the public exponent E.
135 eB64Url, err := stringFromMap(jwk, "e")
136 if err != nil {
137 return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err)
138 }
139
140 e, err := parseRSAPublicExponentParam(eB64Url)
141 if err != nil {
142 return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err)
143 }
144
145 key := &rsaPublicKey{
146 PublicKey: &rsa.PublicKey{N: n, E: e},
147 }
148
149 // Key ID is optional, but if it exists, it should match the key.
150 _, ok := jwk["kid"]
151 if ok {
152 kid, err := stringFromMap(jwk, "kid")
153 if err != nil {
154 return nil, fmt.Errorf("JWK RSA Public Key ID: %s", err)
155 }
156 if kid != key.KeyID() {
157 return nil, fmt.Errorf("JWK RSA Public Key ID does not match: %s", kid)
158 }
159 }
160
161 if _, ok := jwk["d"]; ok {
162 return nil, fmt.Errorf("JWK RSA Public Key cannot contain private exponent")
163 }
164
165 key.extended = jwk
166
167 return key, nil
168}
169
170/*
171 * RSA DSA PRIVATE KEY
172 */
173
174// rsaPrivateKey implements a JWK Private Key using RSA digital signature algorithms.
175type rsaPrivateKey struct {
176 rsaPublicKey
177 *rsa.PrivateKey
178}
179
180func fromRSAPrivateKey(cryptoPrivateKey *rsa.PrivateKey) *rsaPrivateKey {
181 return &rsaPrivateKey{
182 *fromRSAPublicKey(&cryptoPrivateKey.PublicKey),
183 cryptoPrivateKey,
184 }
185}
186
187// PublicKey returns the Public Key data associated with this Private Key.
188func (k *rsaPrivateKey) PublicKey() PublicKey {
189 return &k.rsaPublicKey
190}
191
192func (k *rsaPrivateKey) String() string {
193 return fmt.Sprintf("RSA Private Key <%s>", k.KeyID())
194}
195
196// Sign signs the data read from the io.Reader using a signature algorithm supported
197// by the RSA private key. If the specified hashing algorithm is supported by
198// this key, that hash function is used to generate the signature otherwise the
199// the default hashing algorithm for this key is used. Returns the signature
200// and the name of the JWK signature algorithm used, e.g., "RS256", "RS384",
201// "RS512".
202func (k *rsaPrivateKey) Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) {
203 // Generate a signature of the data using the internal alg.
204 sigAlg := rsaPKCS1v15SignatureAlgorithmForHashID(hashID)
205 hasher := sigAlg.HashID().New()
206
207 _, err = io.Copy(hasher, data)
208 if err != nil {
209 return nil, "", fmt.Errorf("error reading data to sign: %s", err)
210 }
211 hash := hasher.Sum(nil)
212
213 signature, err = rsa.SignPKCS1v15(rand.Reader, k.PrivateKey, sigAlg.HashID(), hash)
214 if err != nil {
215 return nil, "", fmt.Errorf("error producing signature: %s", err)
216 }
217
218 alg = sigAlg.HeaderParam()
219
220 return
221}
222
223// CryptoPrivateKey returns the internal object which can be used as a
224// crypto.PublicKey for use with other standard library operations. The type
225// is either *rsa.PublicKey or *ecdsa.PublicKey
226func (k *rsaPrivateKey) CryptoPrivateKey() crypto.PrivateKey {
227 return k.PrivateKey
228}
229
230func (k *rsaPrivateKey) toMap() map[string]interface{} {
231 k.Precompute() // Make sure the precomputed values are stored.
232 jwk := k.rsaPublicKey.toMap()
233
234 jwk["d"] = joseBase64UrlEncode(k.D.Bytes())
235 jwk["p"] = joseBase64UrlEncode(k.Primes[0].Bytes())
236 jwk["q"] = joseBase64UrlEncode(k.Primes[1].Bytes())
237 jwk["dp"] = joseBase64UrlEncode(k.Precomputed.Dp.Bytes())
238 jwk["dq"] = joseBase64UrlEncode(k.Precomputed.Dq.Bytes())
239 jwk["qi"] = joseBase64UrlEncode(k.Precomputed.Qinv.Bytes())
240
241 otherPrimes := k.Primes[2:]
242
243 if len(otherPrimes) > 0 {
244 otherPrimesInfo := make([]interface{}, len(otherPrimes))
245 for i, r := range otherPrimes {
246 otherPrimeInfo := make(map[string]string, 3)
247 otherPrimeInfo["r"] = joseBase64UrlEncode(r.Bytes())
248 crtVal := k.Precomputed.CRTValues[i]
249 otherPrimeInfo["d"] = joseBase64UrlEncode(crtVal.Exp.Bytes())
250 otherPrimeInfo["t"] = joseBase64UrlEncode(crtVal.Coeff.Bytes())
251 otherPrimesInfo[i] = otherPrimeInfo
252 }
253 jwk["oth"] = otherPrimesInfo
254 }
255
256 return jwk
257}
258
259// MarshalJSON serializes this Private Key using the JWK JSON serialization format for
260// RSA keys.
261func (k *rsaPrivateKey) MarshalJSON() (data []byte, err error) {
262 return json.Marshal(k.toMap())
263}
264
265// PEMBlock serializes this Private Key to DER-encoded PKIX format.
266func (k *rsaPrivateKey) PEMBlock() (*pem.Block, error) {
267 derBytes := x509.MarshalPKCS1PrivateKey(k.PrivateKey)
268 k.extended["keyID"] = k.KeyID() // For display purposes.
269 return createPemBlock("RSA PRIVATE KEY", derBytes, k.extended)
270}
271
272func rsaPrivateKeyFromMap(jwk map[string]interface{}) (*rsaPrivateKey, error) {
273 // The JWA spec for RSA Private Keys (draft rfc section 5.3.2) states that
274 // only the private key exponent 'd' is REQUIRED, the others are just for
275 // signature/decryption optimizations and SHOULD be included when the JWK
276 // is produced. We MAY choose to accept a JWK which only includes 'd', but
277 // we're going to go ahead and not choose to accept it without the extra
278 // fields. Only the 'oth' field will be optional (for multi-prime keys).
279 privateExponent, err := parseRSAPrivateKeyParamFromMap(jwk, "d")
280 if err != nil {
281 return nil, fmt.Errorf("JWK RSA Private Key exponent: %s", err)
282 }
283 firstPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "p")
284 if err != nil {
285 return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
286 }
287 secondPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "q")
288 if err != nil {
289 return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
290 }
291 firstFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dp")
292 if err != nil {
293 return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
294 }
295 secondFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dq")
296 if err != nil {
297 return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
298 }
299 crtCoeff, err := parseRSAPrivateKeyParamFromMap(jwk, "qi")
300 if err != nil {
301 return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err)
302 }
303
304 var oth interface{}
305 if _, ok := jwk["oth"]; ok {
306 oth = jwk["oth"]
307 delete(jwk, "oth")
308 }
309
310 // JWK key type (kty) has already been determined to be "RSA".
311 // Need to extract the public key information, then extract the private
312 // key values.
313 publicKey, err := rsaPublicKeyFromMap(jwk)
314 if err != nil {
315 return nil, err
316 }
317
318 privateKey := &rsa.PrivateKey{
319 PublicKey: *publicKey.PublicKey,
320 D: privateExponent,
321 Primes: []*big.Int{firstPrimeFactor, secondPrimeFactor},
322 Precomputed: rsa.PrecomputedValues{
323 Dp: firstFactorCRT,
324 Dq: secondFactorCRT,
325 Qinv: crtCoeff,
326 },
327 }
328
329 if oth != nil {
330 // Should be an array of more JSON objects.
331 otherPrimesInfo, ok := oth.([]interface{})
332 if !ok {
333 return nil, errors.New("JWK RSA Private Key: Invalid other primes info: must be an array")
334 }
335 numOtherPrimeFactors := len(otherPrimesInfo)
336 if numOtherPrimeFactors == 0 {
337 return nil, errors.New("JWK RSA Privake Key: Invalid other primes info: must be absent or non-empty")
338 }
339 otherPrimeFactors := make([]*big.Int, numOtherPrimeFactors)
340 productOfPrimes := new(big.Int).Mul(firstPrimeFactor, secondPrimeFactor)
341 crtValues := make([]rsa.CRTValue, numOtherPrimeFactors)
342
343 for i, val := range otherPrimesInfo {
344 otherPrimeinfo, ok := val.(map[string]interface{})
345 if !ok {
346 return nil, errors.New("JWK RSA Private Key: Invalid other prime info: must be a JSON object")
347 }
348
349 otherPrimeFactor, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "r")
350 if err != nil {
351 return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
352 }
353 otherFactorCRT, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "d")
354 if err != nil {
355 return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
356 }
357 otherCrtCoeff, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "t")
358 if err != nil {
359 return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err)
360 }
361
362 crtValue := crtValues[i]
363 crtValue.Exp = otherFactorCRT
364 crtValue.Coeff = otherCrtCoeff
365 crtValue.R = productOfPrimes
366 otherPrimeFactors[i] = otherPrimeFactor
367 productOfPrimes = new(big.Int).Mul(productOfPrimes, otherPrimeFactor)
368 }
369
370 privateKey.Primes = append(privateKey.Primes, otherPrimeFactors...)
371 privateKey.Precomputed.CRTValues = crtValues
372 }
373
374 key := &rsaPrivateKey{
375 rsaPublicKey: *publicKey,
376 PrivateKey: privateKey,
377 }
378
379 return key, nil
380}
381
382/*
383 * Key Generation Functions.
384 */
385
386func generateRSAPrivateKey(bits int) (k *rsaPrivateKey, err error) {
387 k = new(rsaPrivateKey)
388 k.PrivateKey, err = rsa.GenerateKey(rand.Reader, bits)
389 if err != nil {
390 return nil, err
391 }
392
393 k.rsaPublicKey.PublicKey = &k.PrivateKey.PublicKey
394 k.extended = make(map[string]interface{})
395
396 return
397}
398
399// GenerateRSA2048PrivateKey generates a key pair using 2048-bit RSA.
400func GenerateRSA2048PrivateKey() (PrivateKey, error) {
401 k, err := generateRSAPrivateKey(2048)
402 if err != nil {
403 return nil, fmt.Errorf("error generating RSA 2048-bit key: %s", err)
404 }
405
406 return k, nil
407}
408
409// GenerateRSA3072PrivateKey generates a key pair using 3072-bit RSA.
410func GenerateRSA3072PrivateKey() (PrivateKey, error) {
411 k, err := generateRSAPrivateKey(3072)
412 if err != nil {
413 return nil, fmt.Errorf("error generating RSA 3072-bit key: %s", err)
414 }
415
416 return k, nil
417}
418
419// GenerateRSA4096PrivateKey generates a key pair using 4096-bit RSA.
420func GenerateRSA4096PrivateKey() (PrivateKey, error) {
421 k, err := generateRSAPrivateKey(4096)
422 if err != nil {
423 return nil, fmt.Errorf("error generating RSA 4096-bit key: %s", err)
424 }
425
426 return k, nil
427}