1 /*
   2  * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.security.spec;
  27 
  28 import java.math.BigInteger;
  29 
  30 /**
  31  * This class specifies an RSA multi-prime private key, as defined in the
  32  * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information
  33  * values for efficiency.
  34  *
  35  * @author Valerie Peng
  36  *
  37  *
  38  * @see java.security.Key
  39  * @see java.security.KeyFactory
  40  * @see KeySpec
  41  * @see PKCS8EncodedKeySpec
  42  * @see RSAPrivateKeySpec
  43  * @see RSAPublicKeySpec
  44  * @see RSAOtherPrimeInfo
  45  *
  46  * @since 1.4
  47  */
  48 
  49 public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec {
  50 
  51     private final BigInteger publicExponent;
  52     private final BigInteger primeP;
  53     private final BigInteger primeQ;
  54     private final BigInteger primeExponentP;
  55     private final BigInteger primeExponentQ;
  56     private final BigInteger crtCoefficient;
  57     private final RSAOtherPrimeInfo otherPrimeInfo[];
  58 
  59    /**
  60     * Creates a new <code>RSAMultiPrimePrivateCrtKeySpec</code>
  61     * given the modulus, publicExponent, privateExponent,
  62     * primeP, primeQ, primeExponentP, primeExponentQ,
  63     * crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1.
  64     *
  65     * <p>Note that the contents of <code>otherPrimeInfo</code>
  66     * are copied to protect against subsequent modification when
  67     * constructing this object.
  68     *
  69     * @param modulus the modulus n.
  70     * @param publicExponent the public exponent e.
  71     * @param privateExponent the private exponent d.
  72     * @param primeP the prime factor p of n.
  73     * @param primeQ the prime factor q of n.
  74     * @param primeExponentP this is d mod (p-1).
  75     * @param primeExponentQ this is d mod (q-1).
  76     * @param crtCoefficient the Chinese Remainder Theorem
  77     * coefficient q-1 mod p.
  78     * @param otherPrimeInfo triplets of the rest of primes, null can be
  79     * specified if there are only two prime factors (p and q).
  80     * @exception NullPointerException if any of the parameters, i.e.
  81     * <code>modulus</code>,
  82     * <code>publicExponent</code>, <code>privateExponent</code>,
  83     * <code>primeP</code>, <code>primeQ</code>,
  84     * <code>primeExponentP</code>, <code>primeExponentQ</code>,
  85     * <code>crtCoefficient</code>, is null.
  86     * @exception IllegalArgumentException if an empty, i.e. 0-length,
  87     * <code>otherPrimeInfo</code> is specified.
  88     */
  89     public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus,
  90                                 BigInteger publicExponent,
  91                                 BigInteger privateExponent,
  92                                 BigInteger primeP,
  93                                 BigInteger primeQ,
  94                                 BigInteger primeExponentP,
  95                                 BigInteger primeExponentQ,
  96                                 BigInteger crtCoefficient,
  97                                 RSAOtherPrimeInfo[] otherPrimeInfo) {
  98         super(modulus, privateExponent);
  99         if (modulus == null) {
 100             throw new NullPointerException("the modulus parameter must be " +
 101                                             "non-null");
 102         }
 103         if (publicExponent == null) {
 104             throw new NullPointerException("the publicExponent parameter " +
 105                                             "must be non-null");
 106         }
 107         if (privateExponent == null) {
 108             throw new NullPointerException("the privateExponent parameter " +
 109                                             "must be non-null");
 110         }
 111         if (primeP == null) {
 112             throw new NullPointerException("the primeP parameter " +
 113                                             "must be non-null");
 114         }
 115         if (primeQ == null) {
 116             throw new NullPointerException("the primeQ parameter " +
 117                                             "must be non-null");
 118         }
 119         if (primeExponentP == null) {
 120             throw new NullPointerException("the primeExponentP parameter " +
 121                                             "must be non-null");
 122         }
 123         if (primeExponentQ == null) {
 124             throw new NullPointerException("the primeExponentQ parameter " +
 125                                             "must be non-null");
 126         }
 127         if (crtCoefficient == null) {
 128             throw new NullPointerException("the crtCoefficient parameter " +
 129                                             "must be non-null");
 130         }
 131         this.publicExponent = publicExponent;
 132         this.primeP = primeP;
 133         this.primeQ = primeQ;
 134         this.primeExponentP = primeExponentP;
 135         this.primeExponentQ = primeExponentQ;
 136         this.crtCoefficient = crtCoefficient;
 137         if (otherPrimeInfo == null)  {
 138             this.otherPrimeInfo = null;
 139         } else if (otherPrimeInfo.length == 0) {
 140             throw new IllegalArgumentException("the otherPrimeInfo " +
 141                                                 "parameter must not be empty");
 142         } else {
 143             this.otherPrimeInfo = otherPrimeInfo.clone();
 144         }
 145     }
 146 
 147     /**
 148      * Returns the public exponent.
 149      *
 150      * @return the public exponent.
 151      */
 152     public BigInteger getPublicExponent() {
 153         return this.publicExponent;
 154     }
 155 
 156     /**
 157      * Returns the primeP.
 158      *
 159      * @return the primeP.
 160      */
 161     public BigInteger getPrimeP() {
 162         return this.primeP;
 163     }
 164 
 165     /**
 166      * Returns the primeQ.
 167      *
 168      * @return the primeQ.
 169      */
 170     public BigInteger getPrimeQ() {
 171         return this.primeQ;
 172     }
 173 
 174     /**
 175      * Returns the primeExponentP.
 176      *
 177      * @return the primeExponentP.
 178      */
 179     public BigInteger getPrimeExponentP() {
 180         return this.primeExponentP;
 181     }
 182 
 183     /**
 184      * Returns the primeExponentQ.
 185      *
 186      * @return the primeExponentQ.
 187      */
 188     public BigInteger getPrimeExponentQ() {
 189         return this.primeExponentQ;
 190     }
 191 
 192     /**
 193      * Returns the crtCoefficient.
 194      *
 195      * @return the crtCoefficient.
 196      */
 197     public BigInteger getCrtCoefficient() {
 198         return this.crtCoefficient;
 199     }
 200 
 201     /**
 202      * Returns a copy of the otherPrimeInfo or null if there are
 203      * only two prime factors (p and q).
 204      *
 205      * @return the otherPrimeInfo. Returns a new array each
 206      * time this method is called.
 207      */
 208     public RSAOtherPrimeInfo[] getOtherPrimeInfo() {
 209         if (otherPrimeInfo == null) return null;
 210         return otherPrimeInfo.clone();
 211     }
 212 }