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