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 }