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