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 }