Merge from the pain train
[official-gcc.git] / libjava / gnu / java / security / provider / EncodedKeyFactory.java
blob7dc5ee9337b0be74fe78941ae157e8ea60b01894
1 /* EncodedKeyFactory.java -- encoded key factory.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.java.security.provider;
41 import gnu.java.security.OID;
42 import gnu.java.security.der.BitString;
43 import gnu.java.security.der.DERReader;
44 import gnu.java.security.der.DERValue;
46 import java.io.IOException;
48 import java.math.BigInteger;
50 import java.security.AlgorithmParameters;
51 import java.security.InvalidKeyException;
52 import java.security.Key;
53 import java.security.KeyFactorySpi;
54 import java.security.NoSuchAlgorithmException;
55 import java.security.PrivateKey;
56 import java.security.PublicKey;
58 import java.security.spec.DSAParameterSpec;
59 import java.security.spec.InvalidParameterSpecException;
60 import java.security.spec.InvalidKeySpecException;
61 import java.security.spec.KeySpec;
62 import java.security.spec.PKCS8EncodedKeySpec;
63 import java.security.spec.RSAPrivateCrtKeySpec;
64 import java.security.spec.RSAPublicKeySpec;
65 import java.security.spec.X509EncodedKeySpec;
67 import javax.crypto.spec.DHParameterSpec;
69 /**
70 * A factory for keys encoded in either the X.509 format (for public
71 * keys) or the PKCS#8 format (for private keys).
73 * @author Casey Marshall (rsdio@metastatic.org)
75 public class EncodedKeyFactory extends KeyFactorySpi
78 // Constants.
79 // ------------------------------------------------------------------------
81 private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
82 private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
83 private static final OID ID_DH = new OID("1.2.840.10046.2.1");
85 // Instance methods.
86 // ------------------------------------------------------------------------
88 public PublicKey engineGeneratePublic(KeySpec spec)
89 throws InvalidKeySpecException
91 if (!(spec instanceof X509EncodedKeySpec))
92 throw new InvalidKeySpecException("only supports X.509 key specs");
93 DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
94 try
96 DERValue spki = der.read();
97 if (!spki.isConstructed())
99 throw new InvalidKeySpecException("malformed encoded key");
101 DERValue alg = der.read();
102 if (!alg.isConstructed())
104 throw new InvalidKeySpecException("malformed encoded key");
106 DERValue val = der.read();
107 if (!(val.getValue() instanceof OID))
109 throw new InvalidKeySpecException("malformed encoded key");
111 OID algId = (OID) val.getValue();
112 byte[] algParams = null;
113 if (alg.getLength() > val.getEncodedLength())
115 val = der.read();
116 algParams = val.getEncoded();
117 if (val.isConstructed())
118 der.skip(val.getLength());
120 val = der.read();
121 if (!(val.getValue() instanceof BitString))
123 throw new InvalidKeySpecException("malformed encoded key");
125 byte[] publicKey = ((BitString) val.getValue()).toByteArray();
126 if (algId.equals(ID_DSA))
128 BigInteger p = null, g = null, q = null, Y;
129 if (algParams != null)
131 DERReader dsaParams = new DERReader(algParams);
132 val = dsaParams.read();
133 if (!val.isConstructed())
134 throw new InvalidKeySpecException("malformed DSA parameters");
135 val = dsaParams.read();
136 if (!(val.getValue() instanceof BigInteger))
137 throw new InvalidKeySpecException("malformed DSA parameters");
138 p = (BigInteger) val.getValue();
139 val = dsaParams.read();
140 if (!(val.getValue() instanceof BigInteger))
141 throw new InvalidKeySpecException("malformed DSA parameters");
142 q = (BigInteger) val.getValue();
143 val = dsaParams.read();
144 if (!(val.getValue() instanceof BigInteger))
145 throw new InvalidKeySpecException("malformed DSA parameters");
146 g = (BigInteger) val.getValue();
148 DERReader dsaPub = new DERReader(publicKey);
149 val = dsaPub.read();
150 if (!(val.getValue() instanceof BigInteger))
151 throw new InvalidKeySpecException("malformed DSA parameters");
152 Y = (BigInteger) val.getValue();
153 return new GnuDSAPublicKey(Y, p, q, g);
155 else if (algId.equals(ID_RSA))
157 DERReader rsaParams = new DERReader(publicKey);
158 if (!rsaParams.read().isConstructed())
160 throw new InvalidKeySpecException("malformed encoded key");
162 return new GnuRSAPublicKey(new RSAPublicKeySpec(
163 (BigInteger) rsaParams.read().getValue(),
164 (BigInteger) rsaParams.read().getValue()));
166 else if (algId.equals(ID_DH))
168 if (algParams == null)
169 throw new InvalidKeySpecException("missing DH parameters");
170 DERReader dhParams = new DERReader(algParams);
171 val = dhParams.read();
172 BigInteger p, g, q, Y;
173 if (!val.isConstructed())
174 throw new InvalidKeySpecException("malformed DH parameters");
175 val = dhParams.read();
176 if (!(val.getValue() instanceof BigInteger))
177 throw new InvalidKeySpecException("malformed DH parameters");
178 p = (BigInteger) val.getValue();
179 val = dhParams.read();
180 if (!(val.getValue() instanceof BigInteger))
181 throw new InvalidKeySpecException("malformed DH parameters");
182 g = (BigInteger) val.getValue();
183 val = dhParams.read();
184 if (!(val.getValue() instanceof BigInteger))
185 throw new InvalidKeySpecException("malformed DH parameters");
186 q = (BigInteger) val.getValue();
187 DERReader dhPub = new DERReader(publicKey);
188 val = dhPub.read();
189 if (!(val.getValue() instanceof BigInteger))
190 throw new InvalidKeySpecException("malformed DH parameters");
191 Y = (BigInteger) val.getValue();
192 return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
194 else
195 throw new InvalidKeySpecException("unknown algorithm: " + algId);
197 catch (IOException ioe)
199 throw new InvalidKeySpecException(ioe.getMessage());
203 public PrivateKey engineGeneratePrivate(KeySpec spec)
204 throws InvalidKeySpecException
206 if (!(spec instanceof PKCS8EncodedKeySpec))
208 throw new InvalidKeySpecException("only supports PKCS8 key specs");
210 DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
213 DERValue pki = der.read();
214 if (!pki.isConstructed())
216 throw new InvalidKeySpecException("malformed encoded key");
218 DERValue val = der.read();
219 if (!(val.getValue() instanceof BigInteger))
221 throw new InvalidKeySpecException("malformed encoded key");
223 DERValue alg = der.read();
224 if (!alg.isConstructed())
226 throw new InvalidKeySpecException("malformed encoded key");
228 val = der.read();
229 if (!(val.getValue() instanceof OID))
231 throw new InvalidKeySpecException("malformed encoded key");
233 OID algId = (OID) val.getValue();
234 byte[] algParams = null;
235 if (alg.getLength() > val.getEncodedLength())
237 val = der.read();
238 algParams = val.getEncoded();
239 if (val.isConstructed())
240 der.skip(val.getLength());
242 byte[] privateKey = (byte[]) der.read().getValue();
243 if (algId.equals(ID_DSA))
245 if (algParams == null)
247 throw new InvalidKeySpecException("missing DSA parameters");
249 AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
250 params.init(algParams);
251 DSAParameterSpec dsaSpec = (DSAParameterSpec)
252 params.getParameterSpec(DSAParameterSpec.class);
253 DERReader dsaPriv = new DERReader(privateKey);
254 return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
255 dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
257 else if (algId.equals(ID_RSA))
259 DERReader rsaParams = new DERReader(privateKey);
260 if (!rsaParams.read().isConstructed())
261 throw new InvalidKeySpecException("malformed encoded key");
262 return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
263 (BigInteger) rsaParams.read().getValue(), // n
264 (BigInteger) rsaParams.read().getValue(), // e
265 (BigInteger) rsaParams.read().getValue(), // d
266 (BigInteger) rsaParams.read().getValue(), // p
267 (BigInteger) rsaParams.read().getValue(), // q
268 (BigInteger) rsaParams.read().getValue(), // d mod (p - 1)
269 (BigInteger) rsaParams.read().getValue(), // d mod (q - 1)
270 (BigInteger) rsaParams.read().getValue())); // (inv q) mod p
272 else
273 throw new InvalidKeySpecException("unknown algorithm: " + algId);
275 catch (InvalidParameterSpecException iapse)
277 throw new InvalidKeySpecException(iapse.getMessage());
279 catch (NoSuchAlgorithmException nsae)
281 throw new InvalidKeySpecException(nsae.getMessage());
283 catch (IOException ioe)
285 throw new InvalidKeySpecException(ioe.getMessage());
289 public KeySpec engineGetKeySpec(Key key, Class speClass)
290 throws InvalidKeySpecException
292 if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
293 && speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
294 return new PKCS8EncodedKeySpec(key.getEncoded());
295 else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
296 && speClass.isAssignableFrom(X509EncodedKeySpec.class))
297 return new X509EncodedKeySpec(key.getEncoded());
298 else
299 throw new InvalidKeySpecException();
302 public Key engineTranslateKey(Key key) throws InvalidKeyException
304 throw new InvalidKeyException("translating keys not supported");