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