001: /*
002: * @(#)DSAKeyFactory.java 1.19 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.security.provider;
029:
030: import java.util.*;
031: import java.lang.*;
032: import java.security.Key;
033: import java.security.PublicKey;
034: import java.security.PrivateKey;
035: import java.security.KeyFactorySpi;
036: import java.security.InvalidKeyException;
037: import java.security.interfaces.DSAParams;
038: import java.security.spec.DSAPublicKeySpec;
039: import java.security.spec.DSAPrivateKeySpec;
040: import java.security.spec.KeySpec;
041: import java.security.spec.InvalidKeySpecException;
042: import java.security.spec.X509EncodedKeySpec;
043: import java.security.spec.PKCS8EncodedKeySpec;
044:
045: /**
046: * This class implements the DSA key factory of the Sun provider.
047: *
048: * @author Jan Luehe
049: *
050: * @version 1.13, 02/02/00
051: *
052: * @since JDK1.2
053: */
054:
055: public class DSAKeyFactory extends KeyFactorySpi {
056:
057: /**
058: * Generates a public key object from the provided key specification
059: * (key material).
060: *
061: * @param keySpec the specification (key material) of the public key
062: *
063: * @return the public key
064: *
065: * @exception InvalidKeySpecException if the given key specification
066: * is inappropriate for this key factory to produce a public key.
067: */
068: protected PublicKey engineGeneratePublic(KeySpec keySpec)
069: throws InvalidKeySpecException {
070: try {
071: if (keySpec instanceof DSAPublicKeySpec) {
072: DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec) keySpec;
073: return new DSAPublicKey(dsaPubKeySpec.getY(),
074: dsaPubKeySpec.getP(), dsaPubKeySpec.getQ(),
075: dsaPubKeySpec.getG());
076:
077: } else if (keySpec instanceof X509EncodedKeySpec) {
078: return new DSAPublicKey(((X509EncodedKeySpec) keySpec)
079: .getEncoded());
080:
081: } else {
082: throw new InvalidKeySpecException(
083: "Inappropriate key specification");
084: }
085: } catch (InvalidKeyException e) {
086: throw new InvalidKeySpecException(
087: "Inappropriate key specification: "
088: + e.getMessage());
089: }
090: }
091:
092: /**
093: * Generates a private key object from the provided key specification
094: * (key material).
095: *
096: * @param keySpec the specification (key material) of the private key
097: *
098: * @return the private key
099: *
100: * @exception InvalidKeySpecException if the given key specification
101: * is inappropriate for this key factory to produce a private key.
102: */
103: protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
104: throws InvalidKeySpecException {
105: try {
106: if (keySpec instanceof DSAPrivateKeySpec) {
107: DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec) keySpec;
108: return new DSAPrivateKey(dsaPrivKeySpec.getX(),
109: dsaPrivKeySpec.getP(), dsaPrivKeySpec.getQ(),
110: dsaPrivKeySpec.getG());
111:
112: } else if (keySpec instanceof PKCS8EncodedKeySpec) {
113: return new DSAPrivateKey(
114: ((PKCS8EncodedKeySpec) keySpec).getEncoded());
115:
116: } else {
117: throw new InvalidKeySpecException(
118: "Inappropriate key specification");
119: }
120: } catch (InvalidKeyException e) {
121: throw new InvalidKeySpecException(
122: "Inappropriate key specification: "
123: + e.getMessage());
124: }
125: }
126:
127: /**
128: * Returns a specification (key material) of the given key object
129: * in the requested format.
130: *
131: * @param key the key
132: *
133: * @param keySpec the requested format in which the key material shall be
134: * returned
135: *
136: * @return the underlying key specification (key material) in the
137: * requested format
138: *
139: * @exception InvalidKeySpecException if the requested key specification is
140: * inappropriate for the given key, or the given key cannot be processed
141: * (e.g., the given key has an unrecognized algorithm or format).
142: */
143: protected KeySpec engineGetKeySpec(Key key, Class keySpec)
144: throws InvalidKeySpecException {
145:
146: DSAParams params;
147:
148: try {
149:
150: if (key instanceof java.security.interfaces.DSAPublicKey) {
151:
152: // Determine valid key specs
153: Class dsaPubKeySpec = Class
154: .forName("java.security.spec.DSAPublicKeySpec");
155: Class x509KeySpec = Class
156: .forName("java.security.spec.X509EncodedKeySpec");
157:
158: if (dsaPubKeySpec.isAssignableFrom(keySpec)) {
159: java.security.interfaces.DSAPublicKey dsaPubKey = (java.security.interfaces.DSAPublicKey) key;
160: params = dsaPubKey.getParams();
161: return new DSAPublicKeySpec(dsaPubKey.getY(),
162: params.getP(), params.getQ(), params.getG());
163:
164: } else if (x509KeySpec.isAssignableFrom(keySpec)) {
165: return new X509EncodedKeySpec(key.getEncoded());
166:
167: } else {
168: throw new InvalidKeySpecException(
169: "Inappropriate key specification");
170: }
171:
172: } else if (key instanceof java.security.interfaces.DSAPrivateKey) {
173:
174: // Determine valid key specs
175: Class dsaPrivKeySpec = Class
176: .forName("java.security.spec.DSAPrivateKeySpec");
177: Class pkcs8KeySpec = Class
178: .forName("java.security.spec.PKCS8EncodedKeySpec");
179:
180: if (dsaPrivKeySpec.isAssignableFrom(keySpec)) {
181: java.security.interfaces.DSAPrivateKey dsaPrivKey = (java.security.interfaces.DSAPrivateKey) key;
182: params = dsaPrivKey.getParams();
183: return new DSAPrivateKeySpec(dsaPrivKey.getX(),
184: params.getP(), params.getQ(), params.getG());
185:
186: } else if (pkcs8KeySpec.isAssignableFrom(keySpec)) {
187: return new PKCS8EncodedKeySpec(key.getEncoded());
188:
189: } else {
190: throw new InvalidKeySpecException(
191: "Inappropriate key specification");
192: }
193:
194: } else {
195: throw new InvalidKeySpecException(
196: "Inappropriate key type");
197: }
198:
199: } catch (ClassNotFoundException e) {
200: throw new InvalidKeySpecException(
201: "Unsupported key specification: " + e.getMessage());
202: }
203: }
204:
205: /**
206: * Translates a key object, whose provider may be unknown or potentially
207: * untrusted, into a corresponding key object of this key factory.
208: *
209: * @param key the key whose provider is unknown or untrusted
210: *
211: * @return the translated key
212: *
213: * @exception InvalidKeyException if the given key cannot be processed by
214: * this key factory.
215: */
216: protected Key engineTranslateKey(Key key)
217: throws InvalidKeyException {
218:
219: try {
220:
221: if (key instanceof java.security.interfaces.DSAPublicKey) {
222: // Check if key originates from this factory
223: if (key instanceof sun.security.provider.DSAPublicKey) {
224: return key;
225: }
226: // Convert key to spec
227: DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec) engineGetKeySpec(
228: key, DSAPublicKeySpec.class);
229: // Create key from spec, and return it
230: return engineGeneratePublic(dsaPubKeySpec);
231:
232: } else if (key instanceof java.security.interfaces.DSAPrivateKey) {
233: // Check if key originates from this factory
234: if (key instanceof sun.security.provider.DSAPrivateKey) {
235: return key;
236: }
237: // Convert key to spec
238: DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec) engineGetKeySpec(
239: key, DSAPrivateKeySpec.class);
240: // Create key from spec, and return it
241: return engineGeneratePrivate(dsaPrivKeySpec);
242:
243: } else {
244: throw new InvalidKeyException("Wrong algorithm type");
245: }
246:
247: } catch (InvalidKeySpecException e) {
248: throw new InvalidKeyException("Cannot translate key: "
249: + e.getMessage());
250: }
251: }
252: }
|