001package com.nimbusds.jose.jwk;
002
003
004import java.io.Serializable;
005import java.net.URI;
006import java.math.BigInteger;
007import java.security.*;
008import java.security.interfaces.RSAMultiPrimePrivateCrtKey;
009import java.security.interfaces.RSAPrivateCrtKey;
010import java.security.interfaces.RSAPrivateKey;
011import java.security.interfaces.RSAPublicKey;
012import java.security.spec.InvalidKeySpecException;
013import java.security.spec.RSAMultiPrimePrivateCrtKeySpec;
014import java.security.spec.RSAOtherPrimeInfo;
015import java.security.spec.RSAPrivateCrtKeySpec;
016import java.security.spec.RSAPrivateKeySpec;
017import java.security.spec.RSAPublicKeySpec;
018import java.text.ParseException;
019import java.util.*;
020
021import net.jcip.annotations.Immutable;
022
023import net.minidev.json.JSONArray;
024import net.minidev.json.JSONObject;
025
026import com.nimbusds.jose.Algorithm;
027import com.nimbusds.jose.JOSEException;
028import com.nimbusds.jose.util.Base64;
029import com.nimbusds.jose.util.Base64URL;
030import com.nimbusds.jose.util.JSONObjectUtils;
031
032
033/**
034 * Public and private {@link KeyType#RSA RSA} JSON Web Key (JWK). This class is
035 * immutable.
036 *
037 * <p>Provides RSA JWK import from / export to the following standard Java 
038 * interfaces and classes:
039 *
040 * <ul>
041 *     <li>{@code java.security.interfaces.RSAPublicKey}
042 *     <li>{@code java.security.interfaces.RSAPrivateKey}
043 *         <ul>
044 *             <li>{@code java.security.interfaces.RSAPrivateCrtKey}
045 *             <li>{@code java.security.interfaces.RSAMultiPrimePrivateCrtKey}
046 *         </ul>
047 *     <li>{@code java.security.KeyPair}
048 * </ul>
049 *
050 * <p>Example JSON object representation of a public RSA JWK:
051 *
052 * <pre>
053 * { 
054 *   "kty" : "RSA",
055 *   "n"   : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
056 *            4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
057 *            tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
058 *            QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
059 *            SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
060 *            w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
061 *   "e"   : "AQAB",
062 *   "alg" : "RS256",
063 *   "kid" : "2011-04-29"
064 * }
065 * </pre>
066 *
067 * <p>Example JSON object representation of a public and private RSA JWK (with 
068 * both the first and the second private key representations):
069 *
070 * <pre>
071 * { 
072 *   "kty" : "RSA",
073 *   "n"   : "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
074 *            4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
075 *            tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
076 *            QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
077 *            SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
078 *            w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
079 *   "e"   : "AQAB",
080 *   "d"   : "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9
081 *            M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij
082 *            wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d
083 *            _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz
084 *            nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz
085 *            me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
086 *   "p"   : "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV
087 *            nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV
088 *            WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
089 *   "q"   : "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum
090 *            qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx
091 *            kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
092 *   "dp"  : "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim
093 *            YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu
094 *            YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
095 *   "dq"  : "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU
096 *            vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9
097 *            GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
098 *   "qi"  : "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg
099 *            UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx
100 *            yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
101 *   "alg" : "RS256",
102 *   "kid" : "2011-04-29"
103 * }
104 * </pre>
105 *
106 * <p>See RFC 3447.
107 *
108 * <p>See http://en.wikipedia.org/wiki/RSA_%28algorithm%29
109 *
110 * @author Vladimir Dzhuvinov
111 * @author Justin Richer
112 * @author Cedric Staub
113 * @version 2015-12-08
114 */
115@Immutable
116public final class RSAKey extends JWK implements AssymetricJWK {
117
118
119        private static final long serialVersionUID = 1L;
120
121
122        /**
123         * Other Primes Info, represents the private {@code oth} parameter of a
124         * RSA JWK. This class is immutable.
125         */
126        @Immutable
127        public static class OtherPrimesInfo implements Serializable {
128
129
130                private static final long serialVersionUID = 1L;
131
132
133                 /**
134                  * The prime factor.
135                  */
136                private final Base64URL r;
137
138                
139                /**
140                 * The factor Chinese Remainder Theorem (CRT) exponent.
141                 */
142                private final Base64URL d;
143        
144
145                /**
146                 * The factor Chinese Remainder Theorem (CRT) coefficient.
147                 */
148                private final Base64URL t;
149
150
151                /**
152                 * Creates a new JWK Other Primes Info with the specified 
153                 * parameters.
154                 *
155                 * @param r The prime factor. Must not be {@code null}.
156                 * @param d The factor Chinese Remainder Theorem (CRT) 
157                 *          exponent. Must not be {@code null}.
158                 * @param t The factor Chinese Remainder Theorem (CRT) 
159                 *          coefficient. Must not be {@code null}.
160                 */
161                public OtherPrimesInfo(final Base64URL r, final Base64URL d, final Base64URL t) {
162
163                        if (r == null) {
164
165                                throw new IllegalArgumentException("The prime factor must not be null");
166                        }
167
168                        this.r = r;
169
170                        if (d == null) {
171
172                                throw new IllegalArgumentException("The factor CRT exponent must not be null");
173                        }
174
175                        this.d = d;
176
177                        if (t == null) {
178
179                                throw new IllegalArgumentException("The factor CRT coefficient must not be null");
180                        }
181                        
182                        this.t = t;
183                }
184
185
186                /**
187                 * Creates a new JWK Other Primes Info from the specified
188                 * {@code java.security.spec.RSAOtherPrimeInfo} instance.
189                 *
190                 * @param oth The RSA Other Primes Info instance. Must not be 
191                 *            {@code null}.
192                 */
193                public OtherPrimesInfo(final RSAOtherPrimeInfo oth) {
194
195                        r = Base64URL.encode(oth.getPrime());
196                        d = Base64URL.encode(oth.getExponent());
197                        t = Base64URL.encode(oth.getCrtCoefficient());
198                }
199       
200        
201                /**
202                 * Gets the prime factor ({@code r}).
203                 *
204                 * @return The prime factor.
205                 */
206                public Base64URL getPrimeFactor() {
207
208                        return r;
209                }
210
211
212                /**
213                 * Gets factor Chinese Remainder Theorem (CRT) exponent
214                 * ({@code d}).
215                 *
216                 * @return The factor Chinese Remainder Theorem (CRT) exponent.
217                 */
218                public Base64URL getFactorCRTExponent() {
219
220                        return d;
221                }
222
223
224                /**
225                 * The factor Chinese Remainder Theorem (CRT) coefficient
226                 * ({@code t}).
227                 *
228                 * @return The factor Chinese Remainder Theorem (CRT) 
229                 *         coefficient.
230                 */
231                public Base64URL getFactorCRTCoefficient() {
232
233                        return t;
234                }
235
236
237                /**
238                 * Converts the specified array of 
239                 * {@code java.security.spec.RSAOtherPrimeInfo} instances to a
240                 * list of JWK Other Prime Infos.
241                 *
242                 * @param othArray Array of RSA Other Primes Info instances. 
243                 *                 May be be {@code null}.
244                 *
245                 * @return The corresponding list of JWK Other Prime Infos, or
246                 *         empty list of the array was {@code null}.
247                 */
248                public static List<OtherPrimesInfo> toList(final RSAOtherPrimeInfo[] othArray) {
249
250                        List<OtherPrimesInfo> list = new ArrayList<>();
251
252                        if (othArray == null) {
253
254                                // Return empty list
255                                return list;
256                        }
257
258                        for (RSAOtherPrimeInfo oth: othArray) {
259
260                                list.add(new OtherPrimesInfo(oth));
261                        }
262
263                        return list;
264                }
265        }
266
267
268        /**
269         * Builder for constructing RSA JWKs.
270         *
271         * <p>Example usage:
272         *
273         * <pre>
274         * RSAKey key = new RSAKey.Builder(n, e).
275         *              privateExponent(d).
276         *              algorithm(JWSAlgorithm.RS512).
277         *              keyID("456").
278         *              build();
279         * </pre>
280         */
281        public static class Builder {
282
283
284                // Public RSA params
285
286                /**
287                 * The modulus value for the RSA key.
288                 */
289                private final Base64URL n;
290
291
292                /**
293                 * The public exponent of the RSA key.
294                 */
295                private final Base64URL e;
296
297
298                // Private RSA params, 1st representation       
299
300                /**
301                 * The private exponent of the RSA key.
302                 */
303                private Base64URL d;
304
305                
306                // Private RSA params, 2nd representation
307
308                /**
309                 * The first prime factor of the private RSA key.
310                 */
311                private Base64URL p;
312
313                
314                /**
315                 * The second prime factor of the private RSA key.
316                 */
317                private Base64URL q;
318
319                
320                /**
321                 * The first factor Chinese Remainder Theorem exponent of the 
322                 * private RSA key.
323                 */
324                private Base64URL dp;
325
326                
327                /**
328                 * The second factor Chinese Remainder Theorem exponent of the
329                 * private RSA key.
330                 */
331                private Base64URL dq;
332
333                
334                /**
335                 * The first Chinese Remainder Theorem coefficient of the private RSA
336                 * key.
337                 */
338                private Base64URL qi;
339
340                
341                /**
342                 * The other primes information of the private RSA key, should
343                 * they exist. When only two primes have been used (the normal
344                 * case), this parameter MUST be omitted. When three or more 
345                 * primes have been used, the number of array elements MUST be 
346                 * the number of primes used minus two.
347                 */
348                private List<OtherPrimesInfo> oth;
349
350
351                /**
352                 * The key use, optional.
353                 */
354                private KeyUse use;
355
356
357                /**
358                 * The key operations, optional.
359                 */
360                private Set<KeyOperation> ops;
361
362
363                /**
364                 * The intended JOSE algorithm for the key, optional.
365                 */
366                private Algorithm alg;
367
368
369                /**
370                 * The key ID, optional.
371                 */
372                private String kid;
373
374
375                /**
376                 * X.509 certificate URL, optional.
377                 */
378                private URI x5u;
379
380
381                /**
382                 * X.509 certificate thumbprint, optional.
383                 */
384                private Base64URL x5t;
385
386
387                /**
388                 * The X.509 certificate chain, optional.
389                 */
390                private List<Base64> x5c;
391
392
393                /**
394                 * Creates a new RSA JWK builder.
395                 *
396                 * @param n The the modulus value for the public RSA key. It is 
397                 *          represented as the Base64URL encoding of value's 
398                 *          big endian representation. Must not be 
399                 *          {@code null}.
400                 * @param e The exponent value for the public RSA key. It is 
401                 *          represented as the Base64URL encoding of value's 
402                 *          big endian representation. Must not be 
403                 *          {@code null}.
404                 */
405                public Builder(final Base64URL n, final Base64URL e) {
406
407                        // Ensure the public params are defined
408
409                        if (n == null) {
410                                throw new IllegalArgumentException("The modulus value must not be null");
411                        }
412
413                        this.n = n;
414
415
416                        if (e == null) {
417                                throw new IllegalArgumentException("The public exponent value must not be null");
418                        }
419
420                        this.e = e;
421                }
422
423
424                /**
425                 * Creates a new RSA JWK builder.
426                 * 
427                 * @param pub The public RSA key to represent. Must not be 
428                 *            {@code null}.
429                 */
430                public Builder(final RSAPublicKey pub) {
431
432                        n = Base64URL.encode(pub.getModulus());
433                        e = Base64URL.encode(pub.getPublicExponent());
434                }
435
436
437                /**
438                 * Sets the private exponent ({@code d}) of the RSA key.
439                 *
440                 * @param d The private RSA key exponent. It is represented as 
441                 *          the Base64URL encoding of the value's big endian 
442                 *          representation. {@code null} if not specified (for 
443                 *          a public key or a private key using the second 
444                 *          representation only).
445                 *
446                 * @return This builder.
447                 */
448                public Builder privateExponent(final Base64URL d) {
449
450                        this.d = d;
451                        return this;
452                }
453
454
455                /**
456                 * Sets the private RSA key, using the first representation.
457                 * 
458                 * @param priv The private RSA key, used to obtain the private
459                 *             exponent ({@code d}). Must not be {@code null}.
460                 *
461                 * @return This builder.
462                 */
463                public Builder privateKey(final RSAPrivateKey priv) {
464
465                        if (priv instanceof RSAPrivateCrtKey) {
466                                return this.privateKey((RSAPrivateCrtKey) priv);
467                        } else if (priv instanceof RSAMultiPrimePrivateCrtKey) {
468                                return this.privateKey((RSAMultiPrimePrivateCrtKey) priv);
469                        } else {
470                                this.d = Base64URL.encode(priv.getPrivateExponent());
471                                return this;
472                        }
473                }
474
475
476                /**
477                 * Sets the first prime factor ({@code p}) of the private RSA
478                 * key. 
479                 *
480                 * @param p The RSA first prime factor. It is represented as 
481                 *          the Base64URL encoding of the value's big endian 
482                 *          representation. {@code null} if not specified (for 
483                 *          a public key or a private key using the first 
484                 *          representation only).
485                 *
486                 * @return This builder.
487                 */
488                public Builder firstPrimeFactor(final Base64URL p) {
489
490                        this.p = p;
491                        return this;
492                }
493
494
495                /**
496                 * Sets the second prime factor ({@code q}) of the private RSA 
497                 * key.
498                 *
499                 * @param q The RSA second prime factor. It is represented as 
500                 *          the Base64URL encoding of the value's big endian 
501                 *          representation. {@code null} if not specified (for 
502                 *          a public key or a private key using the first 
503                 *          representation only).
504                 *
505                 * @return This builder.
506                 */
507                public Builder secondPrimeFactor(final Base64URL q) {
508
509                        this.q = q;
510                        return this;
511                }
512
513
514                /**
515                 * Sets the first factor Chinese Remainder Theorem (CRT) 
516                 * exponent ({@code dp}) of the private RSA key.
517                 *
518                 * @param dp The RSA first factor CRT exponent. It is 
519                 *           represented as the Base64URL encoding of the 
520                 *           value's big endian representation. {@code null} 
521                 *           if not specified (for a public key or a private
522                 *           key using the first representation only).
523                 *
524                 * @return This builder.
525                 */
526                public Builder firstFactorCRTExponent(final Base64URL dp) {
527
528                        this.dp = dp;
529                        return this;
530                }
531
532
533                /**
534                 * Sets the second factor Chinese Remainder Theorem (CRT) 
535                 * exponent ({@code dq}) of the private RSA key.
536                 *
537                 * @param dq The RSA second factor CRT exponent. It is 
538                 *           represented as the Base64URL encoding of the 
539                 *           value's big endian representation. {@code null} if 
540                 *           not specified (for a public key or a private key 
541                 *           using the first representation only).
542                 *
543                 * @return This builder.
544                 */
545                public Builder secondFactorCRTExponent(final Base64URL dq) {
546
547                        this.dq = dq;
548                        return this;
549                }
550
551
552                /**
553                 * Sets the first Chinese Remainder Theorem (CRT) coefficient
554                 * ({@code qi})} of the private RSA key.
555                 *
556                 * @param qi The RSA first CRT coefficient. It is represented 
557                 *           as the Base64URL encoding of the value's big 
558                 *           endian representation. {@code null} if not 
559                 *           specified (for a public key or a private key using 
560                 *           the first representation only).
561                 *
562                 * @return This builder.
563                 */
564                public Builder firstCRTCoefficient(final Base64URL qi) {
565
566                        this.qi = qi;
567                        return this;
568                }
569
570
571                /**
572                 * Sets the other primes information ({@code oth}) for the 
573                 * private RSA key, should they exist.
574                 *
575                 * @param oth The RSA other primes information, {@code null} or 
576                 *            empty list if not specified.
577                 *
578                 * @return This builder.
579                 */
580                public Builder otherPrimes(final List<OtherPrimesInfo> oth) {
581
582                        this.oth = oth;
583                        return this;
584                }
585
586
587                /**
588                 * Sets the private RSA key, using the second representation 
589                 * (see RFC 3447, section 3.2).
590                 * 
591                 * @param priv The private RSA key, used to obtain the private
592                 *             exponent ({@code d}), the first prime factor
593                 *             ({@code p}), the second prime factor 
594                 *             ({@code q}), the first factor CRT exponent 
595                 *             ({@code dp}), the second factor CRT exponent
596                 *             ({@code dq}) and the first CRT coefficient 
597                 *             ({@code qi}). Must not be {@code null}.
598                 *
599                 * @return This builder.
600                 */
601                public Builder privateKey(final RSAPrivateCrtKey priv) {
602
603                        d = Base64URL.encode(priv.getPrivateExponent());
604                        p = Base64URL.encode(priv.getPrimeP());
605                        q = Base64URL.encode(priv.getPrimeQ());
606                        dp = Base64URL.encode(priv.getPrimeExponentP());
607                        dq = Base64URL.encode(priv.getPrimeExponentQ());
608                        qi = Base64URL.encode(priv.getCrtCoefficient());
609
610                        return this;
611                }
612
613
614                /**
615                 * Sets the private RSA key, using the second representation, 
616                 * with optional other primes info (see RFC 3447, section 3.2).
617                 * 
618                 * @param priv The private RSA key, used to obtain the private
619                 *             exponent ({@code d}), the first prime factor
620                 *             ({@code p}), the second prime factor 
621                 *             ({@code q}), the first factor CRT exponent 
622                 *             ({@code dp}), the second factor CRT exponent
623                 *             ({@code dq}), the first CRT coefficient 
624                 *             ({@code qi}) and the other primes info
625                 *             ({@code oth}). Must not be {@code null}.
626                 *
627                 * @return This builder.
628                 */
629                public Builder privateKey(final RSAMultiPrimePrivateCrtKey priv) {
630                        
631                        d = Base64URL.encode(priv.getPrivateExponent());
632                        p = Base64URL.encode(priv.getPrimeP());
633                        q = Base64URL.encode(priv.getPrimeQ());
634                        dp = Base64URL.encode(priv.getPrimeExponentP());
635                        dq = Base64URL.encode(priv.getPrimeExponentQ());
636                        qi = Base64URL.encode(priv.getCrtCoefficient());
637                        oth = OtherPrimesInfo.toList(priv.getOtherPrimeInfo());
638
639                        return this;
640                }
641
642
643                /**
644                 * Sets the use ({@code use}) of the JWK.
645                 *
646                 * @param use The key use, {@code null} if not specified or if
647                 *            the key is intended for signing as well as
648                 *            encryption.
649                 *
650                 * @return This builder.
651                 */
652                public Builder keyUse(final KeyUse use) {
653
654                        this.use = use;
655                        return this;
656                }
657
658
659                /**
660                 * Sets the operations ({@code key_ops}) of the JWK (for a
661                 * non-public key).
662                 *
663                 * @param ops The key operations, {@code null} if not
664                 *            specified.
665                 *
666                 * @return This builder.
667                 */
668                public Builder keyOperations(final Set<KeyOperation> ops) {
669
670                        this.ops = ops;
671                        return this;
672                }
673
674
675                /**
676                 * Sets the intended JOSE algorithm ({@code alg}) for the JWK.
677                 *
678                 * @param alg The intended JOSE algorithm, {@code null} if not
679                 *            specified.
680                 *
681                 * @return This builder.
682                 */
683                public Builder algorithm(final Algorithm alg) {
684
685                        this.alg = alg;
686                        return this;
687                }
688
689                /**
690                 * Sets the ID ({@code kid}) of the JWK. The key ID can be used
691                 * to match a specific key. This can be used, for instance, to
692                 * choose a key within a {@link JWKSet} during key rollover.
693                 * The key ID may also correspond to a JWS/JWE {@code kid}
694                 * header parameter value.
695                 *
696                 * @param kid The key ID, {@code null} if not specified.
697                 *
698                 * @return This builder.
699                 */
700                public Builder keyID(final String kid) {
701
702                        this.kid = kid;
703                        return this;
704                }
705
706
707                /**
708                 * Sets the ID ({@code kid}) of the JWK to its SHA-256 JWK
709                 * thumbprint (RFC 7638). The key ID can be used to match a
710                 * specific key. This can be used, for instance, to choose a
711                 * key within a {@link JWKSet} during key rollover. The key ID
712                 * may also correspond to a JWS/JWE {@code kid} header
713                 * parameter value.
714                 *
715                 * @return This builder.
716                 *
717                 * @throws JOSEException If the SHA-256 hash algorithm is not
718                 *                       supported.
719                 */
720                public Builder keyIDFromThumbprint()
721                        throws JOSEException {
722
723                        return keyIDFromThumbprint("SHA-256");
724                }
725
726
727                /**
728                 * Sets the ID ({@code kid}) of the JWK to its JWK thumbprint
729                 * (RFC 7638). The key ID can be used to match a specific key.
730                 * This can be used, for instance, to choose a key within a
731                 * {@link JWKSet} during key rollover. The key ID may also
732                 * correspond to a JWS/JWE {@code kid} header parameter value.
733                 *
734                 * @param hashAlg The hash algorithm for the JWK thumbprint
735                 *                computation. Must not be {@code null}.
736                 *
737                 * @return This builder.
738                 *
739                 * @throws JOSEException If the hash algorithm is not
740                 *                       supported.
741                 */
742                public Builder keyIDFromThumbprint(final String hashAlg)
743                        throws JOSEException {
744
745                        // Put mandatory params in sorted order
746                        LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>();
747                        requiredParams.put("e", e.toString());
748                        requiredParams.put("kty", KeyType.RSA.getValue());
749                        requiredParams.put("n", n.toString());
750                        this.kid = ThumbprintUtils.compute(hashAlg, requiredParams).toString();
751                        return this;
752                }
753
754
755                /**
756                 * Sets the X.509 certificate URL ({@code x5u}) of the JWK.
757                 *
758                 * @param x5u The X.509 certificate URL, {@code null} if not
759                 *            specified.
760                 *
761                 * @return This builder.
762                 */
763                public Builder x509CertURL(final URI x5u) {
764
765                        this.x5u = x5u;
766                        return this;
767                }
768
769
770                /**
771                 * Sets the X.509 certificate thumbprint ({@code x5t}) of the
772                 * JWK.
773                 *
774                 * @param x5t The X.509 certificate thumbprint, {@code null} if
775                 *            not specified.
776                 *
777                 * @return This builder.
778                 */
779                public Builder x509CertThumbprint(final Base64URL x5t) {
780
781                        this.x5t = x5t;
782                        return this;
783                }
784
785                /**
786                 * Sets the X.509 certificate chain ({@code x5c}) of the JWK.
787                 *
788                 * @param x5c The X.509 certificate chain as a unmodifiable
789                 *            list, {@code null} if not specified.
790                 *
791                 * @return This builder.
792                 */
793                public Builder x509CertChain(final List<Base64> x5c) {
794
795                        this.x5c = x5c;
796                        return this;
797                }
798
799                /**
800                 * Builds a new RSA JWK.
801                 *
802                 * @return The RSA JWK.
803                 *
804                 * @throws IllegalStateException If the JWK parameters were
805                 *                               inconsistently specified.
806                 */
807                public RSAKey build() {
808
809                        try {
810                                // The full constructor
811                                return new RSAKey(n, e, d, p, q, dp, dq, qi, oth,
812                                                  use, ops, alg, kid, x5u, x5t, x5c);
813
814                        } catch (IllegalArgumentException e) {
815
816                                throw new IllegalStateException(e.getMessage(), e);
817                        }
818                }
819        }
820
821
822        // Public RSA params
823
824        /**
825         * The modulus value of the RSA key.
826         */
827        private final Base64URL n;
828
829
830        /**
831         * The public exponent of the RSA key.
832         */
833        private final Base64URL e;
834
835
836        // Private RSA params, 1st representation       
837
838        /**
839         * The private exponent of the RSA key.
840         */
841        private final Base64URL d;
842
843        
844        // Private RSA params, 2nd representation
845
846        /**
847         * The first prime factor of the private RSA key.
848         */
849        private final Base64URL p;
850
851        
852        /**
853         * The second prime factor of the private RSA key.
854         */
855        private final Base64URL q;
856
857        
858        /**
859         * The first factor Chinese Remainder Theorem exponent of the private 
860         * RSA key.
861         */
862        private final Base64URL dp;
863
864        
865        /**
866         * The second factor Chinese Remainder Theorem exponent of the private
867         * RSA key.
868         */
869        private final Base64URL dq;
870
871        
872        /**
873         * The first Chinese Remainder Theorem coefficient of the private RSA
874         * key.
875         */
876        private final Base64URL qi;
877
878        
879        /**
880         * The other primes information of the private RSA key, should they
881         * exist. When only two primes have been used (the normal case), this 
882         * parameter MUST be omitted. When three or more primes have been used,
883         * the number of array elements MUST be the number of primes used minus
884         * two.
885         */
886        private final List<OtherPrimesInfo> oth;
887
888
889        /**
890         * Creates a new public RSA JSON Web Key (JWK) with the specified 
891         * parameters.
892         *
893         * @param n   The the modulus value for the public RSA key. It is 
894         *            represented as the Base64URL encoding of value's big 
895         *            endian representation. Must not be {@code null}.
896         * @param e   The exponent value for the public RSA key. It is 
897         *            represented as the Base64URL encoding of value's big 
898         *            endian representation. Must not be {@code null}.
899         * @param use The key use, {@code null} if not specified or if the key
900         *            is intended for signing as well as encryption.
901         * @param ops The key operations, {@code null} if not specified.
902         * @param alg The intended JOSE algorithm for the key, {@code null} if
903         *            not specified.
904         * @param kid The key ID. {@code null} if not specified.
905         * @param x5u The X.509 certificate URL, {@code null} if not specified.
906         * @param x5t The X.509 certificate thumbprint, {@code null} if not
907         *            specified.
908         * @param x5c The X.509 certificate chain, {@code null} if not 
909         *            specified.
910         */
911        public RSAKey(final Base64URL n, final Base64URL e,
912                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
913                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
914
915                // Call the full constructor, all private key parameters are null
916                this(n, e, null, null, null, null, null, null, null, use, ops, alg, kid,
917                     x5u, x5t, x5c);
918        }
919
920
921        /**
922         * Creates a new public / private RSA JSON Web Key (JWK) with the 
923         * specified parameters. The private RSA key is specified by its first
924         * representation (see RFC 3447, section 3.2).
925         * 
926         * @param n   The the modulus value for the public RSA key. It is
927         *            represented as the Base64URL encoding of value's big 
928         *            endian representation. Must not be {@code null}.
929         * @param e   The exponent value for the public RSA key. It is 
930         *            represented as the Base64URL encoding of value's big 
931         *            endian representation. Must not be {@code null}.
932         * @param d   The private exponent. It is represented as the Base64URL 
933         *            encoding of the value's big endian representation. Must 
934         *            not be {@code null}.
935         * @param use The key use, {@code null} if not specified or if the key
936         *            is intended for signing as well as encryption.
937         * @param ops The key operations, {@code null} if not specified.
938         * @param alg The intended JOSE algorithm for the key, {@code null} if
939         *            not specified.
940         * @param kid The key ID. {@code null} if not specified.
941         * @param x5u The X.509 certificate URL, {@code null} if not specified.
942         * @param x5t The X.509 certificate thumbprint, {@code null} if not
943         *            specified.
944         * @param x5c The X.509 certificate chain, {@code null} if not 
945         *            specified.
946         */
947        public RSAKey(final Base64URL n, final Base64URL e, final Base64URL d,
948                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
949                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
950            
951                // Call the full constructor, the second private representation 
952                // parameters are all null
953                this(n, e, d, null, null, null, null, null, null, use, ops, alg, kid,
954                     x5u, x5t, x5c);
955
956                if (d == null) {
957                        throw new IllegalArgumentException("The private exponent must not be null");
958                }
959        }
960
961
962        /**
963         * Creates a new public / private RSA JSON Web Key (JWK) with the 
964         * specified parameters. The private RSA key is specified by its
965         * second representation (see RFC 3447, section 3.2).
966         * 
967         * @param n   The the modulus value for the public RSA key. It is
968         *            represented as the Base64URL encoding of value's big 
969         *            endian representation. Must not be {@code null}.
970         * @param e   The exponent value for the public RSA key. It is 
971         *            represented as the Base64URL encoding of value's big 
972         *            endian representation. Must not be {@code null}.
973         * @param p   The first prime factor. It is represented as the 
974         *            Base64URL encoding of the value's big endian 
975         *            representation. Must not be {@code null}.
976         * @param q   The second prime factor. It is represented as the 
977         *            Base64URL encoding of the value's big endian 
978         *            representation. Must not be {@code null}.
979         * @param dp  The first factor Chinese Remainder Theorem exponent. It 
980         *            is represented as the Base64URL encoding of the value's 
981         *            big endian representation. Must not be {@code null}.
982         * @param dq  The second factor Chinese Remainder Theorem exponent. It 
983         *            is represented as the Base64URL encoding of the value's 
984         *            big endian representation. Must not be {@code null}.
985         * @param qi  The first Chinese Remainder Theorem coefficient. It is 
986         *            represented as the Base64URL encoding of the value's big 
987         *            endian representation. Must not be {@code null}.
988         * @param oth The other primes information, should they exist,
989         *            {@code null} or an empty list if not specified.
990         * @param use The key use, {@code null} if not specified or if the key
991         *            is intended for signing as well as encryption.
992         * @param ops The key operations, {@code null} if not specified.
993         * @param alg The intended JOSE algorithm for the key, {@code null} if
994         *            not specified.
995         * @param kid The key ID. {@code null} if not specified.
996         * @param x5u The X.509 certificate URL, {@code null} if not specified.
997         * @param x5t The X.509 certificate thumbprint, {@code null} if not
998         *            specified.
999         * @param x5c The X.509 certificate chain, {@code null} if not 
1000         *            specified.
1001         */
1002        public RSAKey(final Base64URL n, final Base64URL e, 
1003                      final Base64URL p, final Base64URL q, 
1004                      final Base64URL dp, final Base64URL dq, final Base64URL qi, 
1005                      final List<OtherPrimesInfo> oth,
1006                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1007                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1008            
1009                // Call the full constructor, the first private representation 
1010                // d param is null
1011                this(n, e, null, p, q, dp, dq, qi, oth, use, ops, alg, kid,
1012                     x5u, x5t, x5c);
1013
1014                if (p == null) {
1015                        throw new IllegalArgumentException("The first prime factor must not be null");
1016                }
1017
1018                if (q == null) {
1019                        throw new IllegalArgumentException("The second prime factor must not be null");
1020                }
1021
1022                if (dp == null) {
1023                        throw new IllegalArgumentException("The first factor CRT exponent must not be null");
1024                }
1025
1026                if (dq == null) {
1027                        throw new IllegalArgumentException("The second factor CRT exponent must not be null");
1028                }
1029
1030                if (qi == null) {
1031                        throw new IllegalArgumentException("The first CRT coefficient must not be null");
1032                }
1033        }
1034
1035
1036        /**
1037         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1038         * specified parameters. The private RSA key is specified by both its
1039         * first and second representations (see RFC 3447, section 3.2).
1040         *
1041         * <p>A valid first private RSA key representation must specify the
1042         * {@code d} parameter.
1043         *
1044         * <p>A valid second private RSA key representation must specify all 
1045         * required Chinese Remained Theorem (CRT) parameters - {@code p}, 
1046         * {@code q}, {@code dp}, {@code dq} and {@code qi}, else an
1047         * {@link java.lang.IllegalArgumentException} will be thrown.
1048         * 
1049         * @param n   The the modulus value for the public RSA key. It is
1050         *            represented as the Base64URL encoding of value's big 
1051         *            endian representation. Must not be {@code null}.
1052         * @param e   The exponent value for the public RSA key. It is 
1053         *            represented as the Base64URL encoding of value's big 
1054         *            endian representation. Must not be {@code null}.
1055         * @param d   The private exponent. It is represented as the Base64URL 
1056         *            encoding of the value's big endian representation. May 
1057         *            be {@code null}.
1058         * @param p   The first prime factor. It is represented as the 
1059         *            Base64URL encoding of the value's big endian 
1060         *            representation. May be {@code null}.
1061         * @param q   The second prime factor. It is represented as the 
1062         *            Base64URL encoding of the value's big endian 
1063         *            representation. May be {@code null}.
1064         * @param dp  The first factor Chinese Remainder Theorem exponent. It 
1065         *            is represented as the Base64URL encoding of the value's 
1066         *            big endian representation. May be {@code null}.
1067         * @param dq  The second factor Chinese Remainder Theorem exponent. It 
1068         *            is represented as the Base64URL encoding of the value's 
1069         *            big endian representation. May be {@code null}.
1070         * @param qi  The first Chinese Remainder Theorem coefficient. It is 
1071         *            represented as the Base64URL encoding of the value's big 
1072         *            endian representation. May be {@code null}.
1073         * @param oth The other primes information, should they exist,
1074         *            {@code null} or an empty list if not specified.
1075         * @param use The key use, {@code null} if not specified or if the key
1076         *            is intended for signing as well as encryption.
1077         * @param ops The key operations, {@code null} if not specified.
1078         * @param alg The intended JOSE algorithm for the key, {@code null} if
1079         *            not specified.
1080         * @param kid The key ID. {@code null} if not specified.
1081         * @param x5u The X.509 certificate URL, {@code null} if not specified.
1082         * @param x5t The X.509 certificate thumbprint, {@code null} if not
1083         *            specified.
1084         * @param x5c The X.509 certificate chain, {@code null} if not 
1085         *            specified.
1086         */
1087        public RSAKey(final Base64URL n, final Base64URL e,
1088                      final Base64URL d, 
1089                      final Base64URL p, final Base64URL q, 
1090                      final Base64URL dp, final Base64URL dq, final Base64URL qi, 
1091                      final List<OtherPrimesInfo> oth,
1092                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1093                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1094            
1095                super(KeyType.RSA, use, ops, alg, kid, x5u, x5t, x5c);
1096
1097
1098                // Ensure the public params are defined
1099
1100                if (n == null) {
1101                        throw new IllegalArgumentException("The modulus value must not be null");
1102                }
1103
1104                this.n = n;
1105
1106
1107                if (e == null) {
1108                        throw new IllegalArgumentException("The public exponent value must not be null");
1109                }
1110
1111                this.e = e;
1112
1113
1114                // Private params, 1st representation
1115
1116                this.d = d;
1117
1118
1119                // Private params, 2nd representation, check for consistency
1120
1121                if (p != null && q != null && dp != null && dq != null && qi != null) {
1122
1123                        // CRT params fully specified
1124                        this.p = p;
1125                        this.q = q;
1126                        this.dp = dp;
1127                        this.dq = dq;
1128                        this.qi = qi;
1129
1130                        // Other RSA primes info optional, default to empty list
1131                        if (oth != null) {
1132                                this.oth = Collections.unmodifiableList(oth);
1133                        } else {
1134                                this.oth = Collections.emptyList();
1135                        }
1136
1137                } else if (p == null && q == null && dp == null && dq == null && qi == null && oth == null) {
1138
1139                        // No CRT params
1140                        this.p = null;
1141                        this.q = null;
1142                        this.dp = null;
1143                        this.dq = null;
1144                        this.qi = null;
1145
1146                        this.oth = Collections.emptyList();
1147
1148                } else {
1149
1150                        if (p == null) {
1151                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first prime factor must not be null");
1152                        } else if (q == null) {
1153                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second prime factor must not be null");
1154                        } else if (dp == null) {
1155                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first factor CRT exponent must not be null");
1156                        } else if (dq == null) {
1157                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The second factor CRT exponent must not be null");
1158                        } else { // qi == null
1159                                throw new IllegalArgumentException("Incomplete second private (CRT) representation: The first CRT coefficient must not be null");
1160                        }
1161                }
1162        }
1163
1164
1165        /**
1166         * Creates a new public RSA JSON Web Key (JWK) with the specified
1167         * parameters.
1168         * 
1169         * @param pub The public RSA key to represent. Must not be 
1170         *            {@code null}.
1171         * @param use The key use, {@code null} if not specified or if the key
1172         *            is intended for signing as well as encryption.
1173         * @param ops The key operations, {@code null} if not specified.
1174         * @param alg The intended JOSE algorithm for the key, {@code null} if
1175         *            not specified.
1176         * @param kid The key ID. {@code null} if not specified.
1177         * @param x5u The X.509 certificate URL, {@code null} if not specified.
1178         * @param x5t The X.509 certificate thumbprint, {@code null} if not
1179         *            specified.
1180         * @param x5c The X.509 certificate chain, {@code null} if not 
1181         *            specified.
1182         */
1183        public RSAKey(final RSAPublicKey pub,
1184                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1185                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1186
1187                this(Base64URL.encode(pub.getModulus()),
1188                        Base64URL.encode(pub.getPublicExponent()),
1189                        use, ops, alg, kid,
1190                        x5u, x5t, x5c);
1191        }
1192
1193
1194        /**
1195         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1196         * specified parameters. The private RSA key is specified by its first
1197         * representation (see RFC 3447, section 3.2).
1198         * 
1199         * @param pub  The public RSA key to represent. Must not be 
1200         *             {@code null}.
1201         * @param priv The private RSA key to represent. Must not be
1202         *             {@code null}.
1203         * @param use  The key use, {@code null} if not specified or if the key
1204         *             is intended for signing as well as encryption.
1205         * @param ops  The key operations, {@code null} if not specified.
1206         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1207         *             not specified.
1208         * @param kid  The key ID. {@code null} if not specified.
1209         * @param x5u  The X.509 certificate URL, {@code null} if not
1210         *             specified.
1211         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1212         *             specified.
1213         * @param x5c  The X.509 certificate chain, {@code null} if not
1214         *             specified.
1215         */
1216        public RSAKey(final RSAPublicKey pub, final RSAPrivateKey priv,
1217                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1218                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1219                
1220                this(Base64URL.encode(pub.getModulus()), 
1221                     Base64URL.encode(pub.getPublicExponent()), 
1222                     Base64URL.encode(priv.getPrivateExponent()),
1223                     use, ops, alg, kid,
1224                     x5u, x5t, x5c);
1225        }
1226
1227
1228        /**
1229         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1230         * specified parameters. The private RSA key is specified by its second
1231         * representation (see RFC 3447, section 3.2).
1232         * 
1233         * @param pub  The public RSA key to represent. Must not be 
1234         *             {@code null}.
1235         * @param priv The private RSA key to represent. Must not be
1236         *             {@code null}.
1237         * @param use  The key use, {@code null} if not specified or if the key
1238         *             is intended for signing as well as encryption.
1239         * @param ops  The key operations, {@code null} if not specified.
1240         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1241         *             not specified.
1242         * @param kid  The key ID. {@code null} if not specified.
1243         * @param x5u  The X.509 certificate URL, {@code null} if not
1244         *             specified.
1245         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1246         *             specified.
1247         * @param x5c  The X.509 certificate chain, {@code null} if not
1248         *             specified.
1249         */
1250        public RSAKey(final RSAPublicKey pub, final RSAPrivateCrtKey priv,
1251                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1252                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1253                
1254                this(Base64URL.encode(pub.getModulus()), 
1255                     Base64URL.encode(pub.getPublicExponent()), 
1256                     Base64URL.encode(priv.getPrivateExponent()),
1257                     Base64URL.encode(priv.getPrimeP()),
1258                     Base64URL.encode(priv.getPrimeQ()),
1259                     Base64URL.encode(priv.getPrimeExponentP()),
1260                     Base64URL.encode(priv.getPrimeExponentQ()),
1261                     Base64URL.encode(priv.getCrtCoefficient()),
1262                     null,
1263                     use, ops, alg, kid,
1264                     x5u, x5t, x5c);
1265        }
1266
1267
1268        /**
1269         * Creates a new public / private RSA JSON Web Key (JWK) with the 
1270         * specified parameters. The private RSA key is specified by its second
1271         * representation, with optional other primes info (see RFC 3447, 
1272         * section 3.2).
1273         * 
1274         * @param pub  The public RSA key to represent. Must not be 
1275         *             {@code null}.
1276         * @param priv The private RSA key to represent. Must not be
1277         *             {@code null}.
1278         * @param use  The key use, {@code null} if not specified or if the key
1279         *             is intended for signing as well as encryption.
1280         * @param ops  The key operations, {@code null} if not specified.
1281         * @param alg  The intended JOSE algorithm for the key, {@code null} if
1282         *             not specified.
1283         * @param kid  The key ID. {@code null} if not specified.
1284         * @param x5u  The X.509 certificate URL, {@code null} if not
1285         *             specified.
1286         * @param x5t  The X.509 certificate thumbprint, {@code null} if not
1287         *             specified.
1288         * @param x5c  The X.509 certificate chain, {@code null} if not
1289         *             specified.
1290         */
1291        public RSAKey(final RSAPublicKey pub, final RSAMultiPrimePrivateCrtKey priv,
1292                      final KeyUse use, final Set<KeyOperation> ops, final Algorithm alg, final String kid,
1293                      final URI x5u, final Base64URL x5t, final List<Base64> x5c) {
1294                
1295                this(Base64URL.encode(pub.getModulus()), 
1296                     Base64URL.encode(pub.getPublicExponent()), 
1297                     Base64URL.encode(priv.getPrivateExponent()),
1298                     Base64URL.encode(priv.getPrimeP()),
1299                     Base64URL.encode(priv.getPrimeQ()),
1300                     Base64URL.encode(priv.getPrimeExponentP()),
1301                     Base64URL.encode(priv.getPrimeExponentQ()),
1302                     Base64URL.encode(priv.getCrtCoefficient()),
1303                     OtherPrimesInfo.toList(priv.getOtherPrimeInfo()),
1304                     use, ops, alg, kid,
1305                     x5u, x5t, x5c);
1306        }
1307
1308
1309        /**
1310         * Gets the modulus value ({@code n}) of the RSA key.
1311         *
1312         * @return The RSA key modulus. It is represented as the Base64URL 
1313         *         encoding of the value's big endian representation.
1314         */
1315        public Base64URL getModulus() {
1316
1317                return n;
1318        }
1319
1320
1321        /**
1322         * Gets the public exponent ({@code e}) of the RSA key.
1323         *
1324         * @return The public RSA key exponent. It is represented as the 
1325         *         Base64URL encoding of the value's big endian representation.
1326         */
1327        public Base64URL getPublicExponent() {
1328
1329                return e;
1330        }
1331
1332
1333        /**
1334         * Gets the private exponent ({@code d}) of the RSA key.
1335         *
1336         * @return The private RSA key exponent. It is represented as the 
1337         *         Base64URL encoding of the value's big endian representation. 
1338         *         {@code null} if not specified (for a public key or a private
1339         *         key using the second representation only).
1340         */
1341        public Base64URL getPrivateExponent() {
1342
1343                return d;
1344        }
1345
1346
1347        /**
1348         * Gets the first prime factor ({@code p}) of the private RSA key. 
1349         *
1350         * @return The RSA first prime factor. It is represented as the 
1351         *         Base64URL encoding of the value's big endian representation. 
1352         *         {@code null} if not specified (for a public key or a private
1353         *         key using the first representation only).
1354         */
1355        public Base64URL getFirstPrimeFactor() {
1356
1357                return p;
1358        }
1359
1360
1361        /**
1362         * Gets the second prime factor ({@code q}) of the private RSA key.
1363         *
1364         * @return The RSA second prime factor. It is represented as the 
1365         *         Base64URL encoding of the value's big endian representation. 
1366         *         {@code null} if not specified (for a public key or a private
1367         *         key using the first representation only).
1368         */
1369        public Base64URL getSecondPrimeFactor() {
1370
1371                return q;
1372        }
1373
1374
1375        /**
1376         * Gets the first factor Chinese Remainder Theorem (CRT) exponent
1377         * ({@code dp}) of the private RSA key.
1378         *
1379         * @return The RSA first factor CRT exponent. It is represented as the 
1380         *         Base64URL encoding of the value's big endian representation. 
1381         *         {@code null} if not specified (for a public key or a private
1382         *         key using the first representation only).
1383         */
1384        public Base64URL getFirstFactorCRTExponent() {
1385
1386                return dp;
1387        }
1388
1389
1390        /**
1391         * Gets the second factor Chinese Remainder Theorem (CRT) exponent 
1392         * ({@code dq}) of the private RSA key.
1393         *
1394         * @return The RSA second factor CRT exponent. It is represented as the 
1395         *         Base64URL encoding of the value's big endian representation. 
1396         *         {@code null} if not specified (for a public key or a private
1397         *         key using the first representation only).
1398         */
1399        public Base64URL getSecondFactorCRTExponent() {
1400
1401                return dq;
1402        }
1403
1404
1405        /**
1406         * Gets the first Chinese Remainder Theorem (CRT) coefficient
1407         * ({@code qi})} of the private RSA key.
1408         *
1409         * @return The RSA first CRT coefficient. It is represented as the 
1410         *         Base64URL encoding of the value's big endian representation. 
1411         *         {@code null} if not specified (for a public key or a private
1412         *         key using the first representation only).
1413         */
1414        public Base64URL getFirstCRTCoefficient() {
1415
1416                return qi;
1417        }
1418
1419
1420        /**
1421         * Gets the other primes information ({@code oth}) for the private RSA
1422         * key, should they exist.
1423         *
1424         * @return The RSA other primes information, {@code null} or empty list
1425         *         if not specified.
1426         */
1427        public List<OtherPrimesInfo> getOtherPrimes() {
1428
1429                return oth;
1430        }
1431
1432        
1433        /**
1434         * Returns a standard {@code java.security.interfaces.RSAPublicKey} 
1435         * representation of this RSA JWK.
1436         * 
1437         * @return The public RSA key.
1438         * 
1439         * @throws JOSEException If RSA is not supported by the underlying Java
1440         *                       Cryptography (JCA) provider or if the JWK
1441         *                       parameters are invalid for a public RSA key.
1442         */
1443        public RSAPublicKey toRSAPublicKey() 
1444                throws JOSEException {
1445
1446                BigInteger modulus = n.decodeToBigInteger();
1447                BigInteger exponent = e.decodeToBigInteger();
1448                                
1449                RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, exponent);
1450
1451                try {
1452                        KeyFactory factory = KeyFactory.getInstance("RSA");
1453
1454                        return (RSAPublicKey) factory.generatePublic(spec);
1455
1456                } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
1457
1458                        throw new JOSEException(e.getMessage(), e);
1459                }
1460        }
1461        
1462
1463        /**
1464         * Returns a standard {@code java.security.interfaces.RSAPrivateKey} 
1465         * representation of this RSA JWK.
1466         * 
1467         * @return The private RSA key, {@code null} if not specified by this
1468         *         JWK.
1469         * 
1470         * @throws JOSEException If RSA is not supported by the underlying Java
1471         *                       Cryptography (JCA) provider or if the JWK
1472         *                       parameters are invalid for a private RSA key.
1473         */
1474        public RSAPrivateKey toRSAPrivateKey() 
1475                throws JOSEException {
1476                
1477                if (d == null) {
1478                        // no private key
1479                        return null;
1480                }
1481                
1482                BigInteger modulus = n.decodeToBigInteger();
1483                BigInteger privateExponent = d.decodeToBigInteger();
1484                
1485                RSAPrivateKeySpec spec;
1486
1487                if (p == null) {
1488                        // Use 1st representation
1489                        spec = new RSAPrivateKeySpec(modulus, privateExponent);
1490
1491                } else {
1492                        // Use 2nd (CRT) representation
1493                        BigInteger publicExponent = e.decodeToBigInteger();
1494                        BigInteger primeP = p.decodeToBigInteger();
1495                        BigInteger primeQ = q.decodeToBigInteger();
1496                        BigInteger primeExponentP = dp.decodeToBigInteger();
1497                        BigInteger primeExponentQ = dq.decodeToBigInteger();
1498                        BigInteger crtCoefficient = qi.decodeToBigInteger();
1499
1500                        if (oth != null && ! oth.isEmpty()) {
1501                                // Construct other info spec
1502                                RSAOtherPrimeInfo[] otherInfo = new RSAOtherPrimeInfo[oth.size()];
1503
1504                                for (int i=0; i < oth.size(); i++) {
1505
1506                                        OtherPrimesInfo opi = oth.get(i);
1507
1508                                        BigInteger otherPrime = opi.getPrimeFactor().decodeToBigInteger();
1509                                        BigInteger otherPrimeExponent = opi.getFactorCRTExponent().decodeToBigInteger();
1510                                        BigInteger otherCrtCoefficient = opi.getFactorCRTCoefficient().decodeToBigInteger();
1511
1512                                        otherInfo[i] = new RSAOtherPrimeInfo(otherPrime,
1513                                                                             otherPrimeExponent,
1514                                                                             otherCrtCoefficient);
1515                                }
1516
1517                                spec = new RSAMultiPrimePrivateCrtKeySpec(modulus,
1518                                                                          publicExponent,
1519                                                                          privateExponent,
1520                                                                          primeP,
1521                                                                          primeQ,
1522                                                                          primeExponentP,
1523                                                                          primeExponentQ,
1524                                                                          crtCoefficient,
1525                                                                          otherInfo);
1526                        } else {
1527                                // Construct spec with no other info
1528                                spec = new RSAPrivateCrtKeySpec(modulus,
1529                                                                publicExponent,
1530                                                                privateExponent,
1531                                                                primeP,
1532                                                                primeQ,
1533                                                                primeExponentP,
1534                                                                primeExponentQ,
1535                                                                crtCoefficient);        
1536                        } 
1537                }
1538
1539                try {
1540                        KeyFactory factory = KeyFactory.getInstance("RSA");
1541
1542                        return (RSAPrivateKey) factory.generatePrivate(spec);
1543
1544                } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
1545
1546                        throw new JOSEException(e.getMessage(), e);
1547                }
1548        }
1549
1550
1551        @Override
1552        public PublicKey toPublicKey()
1553                throws JOSEException {
1554
1555                return toRSAPublicKey();
1556        }
1557
1558
1559        @Override
1560        public PrivateKey toPrivateKey()
1561                throws JOSEException {
1562
1563                return toRSAPrivateKey();
1564        }
1565
1566
1567        /**
1568         * Returns a standard {@code java.security.KeyPair} representation of 
1569         * this RSA JWK.
1570         * 
1571         * @return The RSA key pair. The private RSA key will be {@code null} 
1572         *         if not specified.
1573         * 
1574         * @throws JOSEException If RSA is not supported by the underlying Java
1575         *                       Cryptography (JCA) provider or if the JWK
1576         *                       parameters are invalid for a public and / or
1577         *                       private RSA key.
1578         */
1579        @Override
1580        public KeyPair toKeyPair() 
1581                throws JOSEException {
1582                
1583                return new KeyPair(toRSAPublicKey(), toRSAPrivateKey());
1584        }
1585
1586
1587        @Override
1588        public LinkedHashMap<String,?> getRequiredParams() {
1589
1590                // Put mandatory params in sorted order
1591                LinkedHashMap<String,String> requiredParams = new LinkedHashMap<>();
1592                requiredParams.put("e", e.toString());
1593                requiredParams.put("kty", getKeyType().getValue());
1594                requiredParams.put("n", n.toString());
1595                return requiredParams;
1596        }
1597
1598
1599        @Override
1600        public boolean isPrivate() {
1601
1602                // Check if 1st or 2nd form params are specified
1603                return d != null || p != null;
1604        }
1605
1606
1607        /**
1608         * Returns a copy of this RSA JWK with any private values removed.
1609         *
1610         * @return The copied public RSA JWK.
1611         */
1612        @Override
1613        public RSAKey toPublicJWK() {
1614
1615                return new RSAKey(getModulus(), getPublicExponent(),
1616                                  getKeyUse(), getKeyOperations(), getAlgorithm(), getKeyID(),
1617                                  getX509CertURL(), getX509CertThumbprint(), getX509CertChain());
1618        }
1619        
1620        
1621        @Override
1622        public JSONObject toJSONObject() {
1623
1624                JSONObject o = super.toJSONObject();
1625
1626                // Append public RSA key specific attributes
1627                o.put("n", n.toString());
1628                o.put("e", e.toString());
1629                if (d != null) {
1630                        o.put("d", d.toString());
1631                }
1632                if (p != null) {
1633                        o.put("p", p.toString());
1634                }
1635                if (q != null) {
1636                        o.put("q", q.toString());
1637                }
1638                if (dp != null) {
1639                        o.put("dp", dp.toString());
1640                }
1641                if (dq != null) {
1642                        o.put("dq", dq.toString());
1643                }
1644                if (qi != null) {
1645                        o.put("qi", qi.toString());
1646                }
1647                if (oth != null && !oth.isEmpty()) {
1648
1649                        JSONArray a = new JSONArray();
1650
1651                        for (OtherPrimesInfo other : oth) {
1652
1653                                JSONObject oo = new JSONObject();
1654                                oo.put("r", other.r.toString());
1655                                oo.put("d", other.d.toString());
1656                                oo.put("t", other.t.toString());
1657
1658                                a.add(oo);
1659                        }
1660
1661                        o.put("oth", a);
1662                }
1663
1664                return o;
1665        }
1666
1667
1668        /**
1669         * Parses a public / private RSA Curve JWK from the specified JSON
1670         * object string representation.
1671         *
1672         * @param s The JSON object string to parse. Must not be {@code null}.
1673         *
1674         * @return The public / private RSA JWK.
1675         *
1676         * @throws ParseException If the string couldn't be parsed to an RSA
1677         *                        JWK.
1678         */
1679        public static RSAKey parse(final String s)
1680                throws ParseException {
1681
1682                return parse(JSONObjectUtils.parse(s));
1683        }
1684
1685
1686        /**
1687         * Parses a public / private RSA JWK from the specified JSON object 
1688         * representation.
1689         *
1690         * @param jsonObject The JSON object to parse. Must not be 
1691         *                   {@code null}.
1692         *
1693         * @return The public / private RSA Key.
1694         *
1695         * @throws ParseException If the JSON object couldn't be parsed to an
1696         *                        RSA JWK.
1697         */
1698        public static RSAKey parse(final JSONObject jsonObject)
1699                throws ParseException {
1700
1701                // Parse the mandatory public key parameters first
1702                Base64URL n = new Base64URL(JSONObjectUtils.getString(jsonObject, "n"));
1703                Base64URL e = new Base64URL(JSONObjectUtils.getString(jsonObject, "e"));
1704
1705                // Check key type
1706                KeyType kty = KeyType.parse(JSONObjectUtils.getString(jsonObject, "kty"));
1707                if (kty != KeyType.RSA) {
1708                        throw new ParseException("The key type \"kty\" must be RSA", 0);
1709                }
1710                
1711                // Parse the optional private key parameters
1712
1713                // 1st private representation
1714                Base64URL d = null;
1715                if (jsonObject.containsKey("d")) {
1716                        d = new Base64URL(JSONObjectUtils.getString(jsonObject, "d"));
1717                }
1718
1719                // 2nd private (CRT) representation
1720                Base64URL p = null;
1721                if (jsonObject.containsKey("p")) {
1722                        p = new Base64URL(JSONObjectUtils.getString(jsonObject, "p"));
1723                }
1724                Base64URL q = null;
1725                if (jsonObject.containsKey("q")) {
1726                        q = new Base64URL(JSONObjectUtils.getString(jsonObject, "q"));
1727                }
1728                Base64URL dp = null;
1729                if (jsonObject.containsKey("dp")) {
1730                        dp = new Base64URL(JSONObjectUtils.getString(jsonObject, "dp"));
1731                }
1732                Base64URL dq= null;
1733                if (jsonObject.containsKey("dq")) {
1734                        dq = new Base64URL(JSONObjectUtils.getString(jsonObject, "dq"));
1735                }
1736                Base64URL qi = null;
1737                if (jsonObject.containsKey("qi")) {
1738                        qi = new Base64URL(JSONObjectUtils.getString(jsonObject, "qi"));
1739                }
1740                
1741                List<OtherPrimesInfo> oth = null;
1742                if (jsonObject.containsKey("oth")) {
1743
1744                        JSONArray arr = JSONObjectUtils.getJSONArray(jsonObject, "oth");
1745                        oth = new ArrayList<>(arr.size());
1746                        
1747                        for (Object o : arr) {
1748
1749                                if (o instanceof JSONObject) {
1750                                        JSONObject otherJson = (JSONObject)o;
1751
1752                                        Base64URL r = new Base64URL(JSONObjectUtils.getString(otherJson, "r"));
1753                                        Base64URL odq = new Base64URL(JSONObjectUtils.getString(otherJson, "dq"));
1754                                        Base64URL t = new Base64URL(JSONObjectUtils.getString(otherJson, "t"));
1755
1756                                        OtherPrimesInfo prime = new OtherPrimesInfo(r, odq, t);
1757                                        oth.add(prime);
1758                                }
1759                        }
1760                }
1761
1762                try {
1763                        return new RSAKey(n, e, d, p, q, dp, dq, qi, oth,
1764                                JWKMetadata.parseKeyUse(jsonObject),
1765                                JWKMetadata.parseKeyOperations(jsonObject),
1766                                JWKMetadata.parseAlgorithm(jsonObject),
1767                                JWKMetadata.parseKeyID(jsonObject),
1768                                JWKMetadata.parseX509CertURL(jsonObject),
1769                                JWKMetadata.parseX509CertThumbprint(jsonObject),
1770                                JWKMetadata.parseX509CertChain(jsonObject));
1771                
1772                } catch (IllegalArgumentException ex) {
1773
1774                        // Inconsistent 2nd spec, conflicting 'use' and 'key_ops'
1775                        throw new ParseException(ex.getMessage(), 0);
1776                }
1777        }
1778}