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