001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the 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
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.util.jce.provider;
020    
021    import java.io.ByteArrayOutputStream;
022    import java.io.IOException;
023    import java.math.BigInteger;
024    import java.security.interfaces.RSAPrivateCrtKey;
025    import java.security.spec.RSAPrivateCrtKeySpec;
026    
027    import org.apache.geronimo.util.asn1.ASN1Sequence;
028    import org.apache.geronimo.util.asn1.DERNull;
029    import org.apache.geronimo.util.asn1.DEROutputStream;
030    import org.apache.geronimo.util.asn1.pkcs.PKCSObjectIdentifiers;
031    import org.apache.geronimo.util.asn1.pkcs.PrivateKeyInfo;
032    import org.apache.geronimo.util.asn1.pkcs.RSAPrivateKeyStructure;
033    import org.apache.geronimo.util.asn1.x509.AlgorithmIdentifier;
034    import org.apache.geronimo.util.crypto.params.RSAPrivateCrtKeyParameters;
035    
036    /**
037     * A provider representation for a RSA private key, with CRT factors included.
038     */
039    public class JCERSAPrivateCrtKey
040        extends JCERSAPrivateKey
041        implements RSAPrivateCrtKey
042    {
043        private BigInteger  publicExponent;
044        private BigInteger  primeP;
045        private BigInteger  primeQ;
046        private BigInteger  primeExponentP;
047        private BigInteger  primeExponentQ;
048        private BigInteger  crtCoefficient;
049    
050        /**
051         * construct a private key from it's org.apache.geronimo.util.crypto equivalent.
052         *
053         * @param key the parameters object representing the private key.
054         */
055        JCERSAPrivateCrtKey(
056            RSAPrivateCrtKeyParameters key)
057        {
058            super(key);
059    
060            this.publicExponent = key.getPublicExponent();
061            this.primeP = key.getP();
062            this.primeQ = key.getQ();
063            this.primeExponentP = key.getDP();
064            this.primeExponentQ = key.getDQ();
065            this.crtCoefficient = key.getQInv();
066        }
067    
068        /**
069         * construct a private key from an RSAPrivateCrtKeySpec
070         *
071         * @param spec the spec to be used in construction.
072         */
073        JCERSAPrivateCrtKey(
074            RSAPrivateCrtKeySpec spec)
075        {
076            this.modulus = spec.getModulus();
077            this.publicExponent = spec.getPublicExponent();
078            this.privateExponent = spec.getPrivateExponent();
079            this.primeP = spec.getPrimeP();
080            this.primeQ = spec.getPrimeQ();
081            this.primeExponentP = spec.getPrimeExponentP();
082            this.primeExponentQ = spec.getPrimeExponentQ();
083            this.crtCoefficient = spec.getCrtCoefficient();
084        }
085    
086        /**
087         * construct a private key from another RSAPrivateCrtKey.
088         *
089         * @param key the object implementing the RSAPrivateCrtKey interface.
090         */
091        JCERSAPrivateCrtKey(
092            RSAPrivateCrtKey key)
093        {
094            this.modulus = key.getModulus();
095            this.publicExponent = key.getPublicExponent();
096            this.privateExponent = key.getPrivateExponent();
097            this.primeP = key.getPrimeP();
098            this.primeQ = key.getPrimeQ();
099            this.primeExponentP = key.getPrimeExponentP();
100            this.primeExponentQ = key.getPrimeExponentQ();
101            this.crtCoefficient = key.getCrtCoefficient();
102        }
103    
104        /**
105         * construct an RSA key from a private key info object.
106         */
107        JCERSAPrivateCrtKey(
108            PrivateKeyInfo  info)
109        {
110            this(new RSAPrivateKeyStructure((ASN1Sequence)info.getPrivateKey()));
111        }
112    
113        /**
114         * construct an RSA key from a ASN.1 RSA private key object.
115         */
116        JCERSAPrivateCrtKey(
117            RSAPrivateKeyStructure  key)
118        {
119            this.modulus = key.getModulus();
120            this.publicExponent = key.getPublicExponent();
121            this.privateExponent = key.getPrivateExponent();
122            this.primeP = key.getPrime1();
123            this.primeQ = key.getPrime2();
124            this.primeExponentP = key.getExponent1();
125            this.primeExponentQ = key.getExponent2();
126            this.crtCoefficient = key.getCoefficient();
127        }
128    
129        /**
130         * return the encoding format we produce in getEncoded().
131         *
132         * @return the encoding format we produce in getEncoded().
133         */
134        public String getFormat()
135        {
136            return "PKCS#8";
137        }
138    
139        /**
140         * Return a PKCS8 representation of the key. The sequence returned
141         * represents a full PrivateKeyInfo object.
142         *
143         * @return a PKCS8 representation of the key.
144         */
145        public byte[] getEncoded()
146        {
147            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
148            DEROutputStream         dOut = new DEROutputStream(bOut);
149            PrivateKeyInfo          info = new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPrivateKeyStructure(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient()).getDERObject());
150    
151            try
152            {
153                dOut.writeObject(info);
154                dOut.close();
155            }
156            catch (IOException e)
157            {
158                throw new RuntimeException("Error encoding RSA public key");
159            }
160    
161            return bOut.toByteArray();
162        }
163    
164        /**
165         * return the public exponent.
166         *
167         * @return the public exponent.
168         */
169        public BigInteger getPublicExponent()
170        {
171            return publicExponent;
172        }
173    
174        /**
175         * return the prime P.
176         *
177         * @return the prime P.
178         */
179        public BigInteger getPrimeP()
180        {
181            return primeP;
182        }
183    
184        /**
185         * return the prime Q.
186         *
187         * @return the prime Q.
188         */
189        public BigInteger getPrimeQ()
190        {
191            return primeQ;
192        }
193    
194        /**
195         * return the prime exponent for P.
196         *
197         * @return the prime exponent for P.
198         */
199        public BigInteger getPrimeExponentP()
200        {
201            return primeExponentP;
202        }
203    
204        /**
205         * return the prime exponent for Q.
206         *
207         * @return the prime exponent for Q.
208         */
209        public BigInteger getPrimeExponentQ()
210        {
211            return primeExponentQ;
212        }
213    
214        /**
215         * return the CRT coefficient.
216         *
217         * @return the CRT coefficient.
218         */
219        public BigInteger getCrtCoefficient()
220        {
221            return crtCoefficient;
222        }
223    
224        public boolean equals(Object o)
225        {
226            if ( !(o instanceof RSAPrivateCrtKey) )
227            {
228                return false;
229            }
230    
231            if ( o == this )
232            {
233                return true;
234            }
235    
236            RSAPrivateCrtKey key = (RSAPrivateCrtKey)o;
237    
238            return this.getModulus().equals(key.getModulus())
239             && this.getPublicExponent().equals(key.getPublicExponent())
240             && this.getPrivateExponent().equals(key.getPrivateExponent())
241             && this.getPrimeP().equals(key.getPrimeP())
242             && this.getPrimeQ().equals(key.getPrimeQ())
243             && this.getPrimeExponentP().equals(key.getPrimeExponentP())
244             && this.getPrimeExponentQ().equals(key.getPrimeExponentQ())
245             && this.getCrtCoefficient().equals(key.getCrtCoefficient());
246        }
247    
248        public String toString()
249        {
250            StringBuffer    buf = new StringBuffer();
251            String          nl = System.getProperty("line.separator");
252    
253            buf.append("RSA Private CRT Key" + nl);
254            buf.append("            modulus: " + this.getModulus().toString(16) + nl);
255            buf.append("    public exponent: " + this.getPublicExponent().toString(16) + nl);
256            buf.append("   private exponent: " + this.getPrivateExponent().toString(16) + nl);
257            buf.append("             primeP: " + this.getPrimeP().toString(16) + nl);
258            buf.append("             primeQ: " + this.getPrimeQ().toString(16) + nl);
259            buf.append("     primeExponentP: " + this.getPrimeExponentP().toString(16) + nl);
260            buf.append("     primeExponentQ: " + this.getPrimeExponentQ().toString(16) + nl);
261            buf.append("     crtCoefficient: " + this.getCrtCoefficient().toString(16) + nl);
262    
263            return buf.toString();
264        }
265    }