Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
38830 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.rsa;2627import java.io.IOException;28import java.math.BigInteger;2930import java.security.*;31import java.security.spec.*;32import java.security.interfaces.*;3334import sun.security.util.*;3536import sun.security.x509.AlgorithmId;37import sun.security.pkcs.PKCS8Key;3839import static sun.security.rsa.RSAUtil.KeyType;4041/**42* RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form.43* For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes44* to ensure correct behavior in instanceof checks, etc.45*46* Note: RSA keys must be at least 512 bits long47*48* @see RSAPrivateKeyImpl49* @see RSAKeyFactory50*51* @since 1.552* @author Andreas Sterbenz53*/54public final class RSAPrivateCrtKeyImpl55extends PKCS8Key implements RSAPrivateCrtKey {5657private static final long serialVersionUID = -1326088454257084918L;5859private BigInteger n; // modulus60private BigInteger e; // public exponent61private BigInteger d; // private exponent62private BigInteger p; // prime p63private BigInteger q; // prime q64private BigInteger pe; // prime exponent p65private BigInteger qe; // prime exponent q66private BigInteger coeff; // CRT coeffcient6768// Optional parameters associated with this RSA key69// specified in the encoding of its AlgorithmId.70// Must be null for "RSA" keys.71private AlgorithmParameterSpec keyParams;7273/**74* Generate a new key from its encoding. Returns a CRT key if possible75* and a non-CRT key otherwise. Used by RSAKeyFactory.76*/77public static RSAPrivateKey newKey(byte[] encoded)78throws InvalidKeyException {79RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);80// check all CRT-specific components are available, if any one81// missing, return a non-CRT key instead82if ((key.getPublicExponent().signum() == 0) ||83(key.getPrimeExponentP().signum() == 0) ||84(key.getPrimeExponentQ().signum() == 0) ||85(key.getPrimeP().signum() == 0) ||86(key.getPrimeQ().signum() == 0) ||87(key.getCrtCoefficient().signum() == 0)) {88return new RSAPrivateKeyImpl(89key.algid,90key.getModulus(),91key.getPrivateExponent()92);93} else {94return key;95}96}9798/**99* Generate a new key from the specified type and components.100* Returns a CRT key if possible and a non-CRT key otherwise.101* Used by SunPKCS11 provider.102*/103public static RSAPrivateKey newKey(KeyType type,104AlgorithmParameterSpec params,105BigInteger n, BigInteger e, BigInteger d,106BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,107BigInteger coeff) throws InvalidKeyException {108RSAPrivateKey key;109AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params);110if ((e.signum() == 0) || (p.signum() == 0) ||111(q.signum() == 0) || (pe.signum() == 0) ||112(qe.signum() == 0) || (coeff.signum() == 0)) {113// if any component is missing, return a non-CRT key114return new RSAPrivateKeyImpl(rsaId, n, d);115} else {116return new RSAPrivateCrtKeyImpl(rsaId, n, e, d,117p, q, pe, qe, coeff);118}119}120121/**122* Construct a key from its encoding. Called from newKey above.123*/124RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {125if (encoded == null || encoded.length == 0) {126throw new InvalidKeyException("Missing key encoding");127}128129decode(encoded);130RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);131try {132// this will check the validity of params133this.keyParams = RSAUtil.getParamSpec(algid);134} catch (ProviderException e) {135throw new InvalidKeyException(e);136}137}138139/**140* Construct a RSA key from its components. Used by the141* RSAKeyFactory and the RSAKeyPairGenerator.142*/143RSAPrivateCrtKeyImpl(AlgorithmId rsaId,144BigInteger n, BigInteger e, BigInteger d,145BigInteger p, BigInteger q, BigInteger pe, BigInteger qe,146BigInteger coeff) throws InvalidKeyException {147RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);148149this.n = n;150this.e = e;151this.d = d;152this.p = p;153this.q = q;154this.pe = pe;155this.qe = qe;156this.coeff = coeff;157this.keyParams = RSAUtil.getParamSpec(rsaId);158159// generate the encoding160algid = rsaId;161try {162DerOutputStream out = new DerOutputStream();163out.putInteger(0); // version must be 0164out.putInteger(n);165out.putInteger(e);166out.putInteger(d);167out.putInteger(p);168out.putInteger(q);169out.putInteger(pe);170out.putInteger(qe);171out.putInteger(coeff);172DerValue val =173new DerValue(DerValue.tag_Sequence, out.toByteArray());174key = val.toByteArray();175} catch (IOException exc) {176// should never occur177throw new InvalidKeyException(exc);178}179}180181// see JCA doc182@Override183public String getAlgorithm() {184return algid.getName();185}186187// see JCA doc188@Override189public BigInteger getModulus() {190return n;191}192193// see JCA doc194@Override195public BigInteger getPublicExponent() {196return e;197}198199// see JCA doc200@Override201public BigInteger getPrivateExponent() {202return d;203}204205// see JCA doc206@Override207public BigInteger getPrimeP() {208return p;209}210211// see JCA doc212@Override213public BigInteger getPrimeQ() {214return q;215}216217// see JCA doc218@Override219public BigInteger getPrimeExponentP() {220return pe;221}222223// see JCA doc224@Override225public BigInteger getPrimeExponentQ() {226return qe;227}228229// see JCA doc230@Override231public BigInteger getCrtCoefficient() {232return coeff;233}234235// see JCA doc236@Override237public AlgorithmParameterSpec getParams() {238return keyParams;239}240241// return a string representation of this key for debugging242@Override243public String toString() {244return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength()245+ " bits" + "\n params: " + keyParams + "\n modulus: " + n246+ "\n private exponent: " + d;247}248249/**250* Parse the key. Called by PKCS8Key.251*/252protected void parseKeyBits() throws InvalidKeyException {253try {254DerInputStream in = new DerInputStream(key);255DerValue derValue = in.getDerValue();256if (derValue.tag != DerValue.tag_Sequence) {257throw new IOException("Not a SEQUENCE");258}259DerInputStream data = derValue.data;260int version = data.getInteger();261if (version != 0) {262throw new IOException("Version must be 0");263}264265/*266* Some implementations do not correctly encode ASN.1 INTEGER values267* in 2's complement format, resulting in a negative integer when268* decoded. Correct the error by converting it to a positive integer.269*270* See CR 6255949271*/272n = data.getPositiveBigInteger();273e = data.getPositiveBigInteger();274d = data.getPositiveBigInteger();275p = data.getPositiveBigInteger();276q = data.getPositiveBigInteger();277pe = data.getPositiveBigInteger();278qe = data.getPositiveBigInteger();279coeff = data.getPositiveBigInteger();280if (derValue.data.available() != 0) {281throw new IOException("Extra data available");282}283} catch (IOException e) {284throw new InvalidKeyException("Invalid RSA private key", e);285}286}287}288289290