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