KeyFactory.java revision cff1616012dc0d56c2da9af2b9b1183e76c7e044
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security;
19
20import java.security.spec.InvalidKeySpecException;
21import java.security.spec.KeySpec;
22import org.apache.harmony.security.fortress.Engine;
23
24/**
25 * {@code KeyFactory} is an engine class that can be used to translate between
26 * public and private key objects and convert keys between their external
27 * representation, that can be easily transported and their internal
28 * representation.
29 */
30public class KeyFactory {
31    // The service name.
32    private static final String SERVICE = "KeyFactory";
33
34    // Used to access common engine functionality
35    private static final Engine ENGINE = new Engine(SERVICE);
36
37    // The provider
38    private final Provider provider;
39
40    // The SPI implementation.
41    private final KeyFactorySpi spiImpl;
42
43    // The algorithm.
44    private final String algorithm;
45
46    /**
47     * Constructs a new instance of {@code KeyFactory} with the specified
48     * arguments.
49     *
50     * @param keyFacSpi
51     *            the concrete key factory service.
52     * @param provider
53     *            the provider.
54     * @param algorithm
55     *            the algorithm to use.
56     */
57    protected KeyFactory(KeyFactorySpi keyFacSpi,
58                         Provider provider,
59                         String algorithm) {
60        this.provider = provider;
61        this.algorithm = algorithm;
62        this.spiImpl = keyFacSpi;
63    }
64
65    /**
66     * Returns a new instance of {@code KeyFactory} that utilizes the specified
67     * algorithm.
68     *
69     * @param algorithm
70     *            the name of the algorithm.
71     * @return a new instance of {@code KeyFactory} that utilizes the specified
72     *         algorithm.
73     * @throws NoSuchAlgorithmException
74     *             if no provider provides the requested algorithm.
75     */
76    public static KeyFactory getInstance(String algorithm)
77            throws NoSuchAlgorithmException {
78        if (algorithm == null) {
79            throw new NullPointerException("algorithm == null");
80        }
81        Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
82        return new KeyFactory((KeyFactorySpi) sap.spi, sap.provider, algorithm);
83    }
84
85    /**
86     * Returns a new instance of {@code KeyFactory} that utilizes the specified
87     * algorithm from the specified provider.
88     *
89     * @param algorithm
90     *            the name of the algorithm.
91     * @param provider
92     *            the name of the provider.
93     * @return a new instance of {@code KeyFactory} that utilizes the specified
94     *         algorithm from the specified provider.
95     * @throws NoSuchAlgorithmException
96     *             if the provider does not provide the requested algorithm.
97     * @throws NoSuchProviderException
98     *             if the requested provider is not available.
99     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
100     */
101    public static KeyFactory getInstance(String algorithm, String provider)
102            throws NoSuchAlgorithmException, NoSuchProviderException {
103        if (provider == null || provider.isEmpty()) {
104            throw new IllegalArgumentException();
105        }
106        Provider p = Security.getProvider(provider);
107        if (p == null) {
108            throw new NoSuchProviderException(provider);
109        }
110        return getInstance(algorithm, p);
111    }
112
113    /**
114     * Returns a new instance of {@code KeyFactory} that utilizes the specified
115     * algorithm from the specified provider.
116     *
117     * @param algorithm
118     *            the name of the algorithm.
119     * @param provider
120     *            the security provider.
121     * @return a new instance of {@code KeyFactory} that utilizes the specified
122     *         algorithm from the specified provider.
123     * @throws NoSuchAlgorithmException
124     *             if the provider does not provide the requested algorithm.
125     * @throws IllegalArgumentException if {@code provider == null}
126     */
127    public static KeyFactory getInstance(String algorithm, Provider provider)
128                                 throws NoSuchAlgorithmException {
129        if (provider == null) {
130            throw new IllegalArgumentException("provider == null");
131        }
132        if (algorithm == null) {
133            throw new NullPointerException("algorithm == null");
134        }
135        Object spi = ENGINE.getInstance(algorithm, provider, null);
136        return new KeyFactory((KeyFactorySpi) spi, provider, algorithm);
137    }
138
139    /**
140     * Returns the provider associated with this {@code KeyFactory}.
141     *
142     * @return the provider associated with this {@code KeyFactory}.
143     */
144    public final Provider getProvider() {
145        return provider;
146    }
147
148    /**
149     * Returns the name of the algorithm associated with this {@code
150     * KeyFactory}.
151     *
152     * @return the name of the algorithm associated with this {@code
153     *         KeyFactory}.
154     */
155    public final String getAlgorithm() {
156        return algorithm;
157    }
158
159    /**
160     * Generates a instance of {@code PublicKey} from the given key
161     * specification.
162     *
163     * @param keySpec
164     *            the specification of the public key
165     * @return the public key
166     * @throws InvalidKeySpecException
167     *             if the specified {@code keySpec} is invalid
168     */
169    public final PublicKey generatePublic(KeySpec keySpec)
170                                throws InvalidKeySpecException {
171        return spiImpl.engineGeneratePublic(keySpec);
172    }
173
174    /**
175     * Generates a instance of {@code PrivateKey} from the given key
176     * specification.
177     *
178     * @param keySpec
179     *            the specification of the private key.
180     * @return the private key.
181     * @throws InvalidKeySpecException
182     *             if the specified {@code keySpec} is invalid.
183     */
184    public final PrivateKey generatePrivate(KeySpec keySpec)
185                                throws InvalidKeySpecException {
186        return spiImpl.engineGeneratePrivate(keySpec);
187    }
188
189    /**
190     * Returns the key specification for the specified key.
191     *
192     * @param key
193     *            the key from which the specification is requested.
194     * @param keySpec
195     *            the type of the requested {@code KeySpec}.
196     * @return the key specification for the specified key.
197     * @throws InvalidKeySpecException
198     *             if the key can not be processed, or the requested requested
199     *             {@code KeySpec} is inappropriate for the given key.
200     */
201    public final <T extends KeySpec> T getKeySpec(Key key,
202                                    Class<T> keySpec)
203                            throws InvalidKeySpecException {
204        return spiImpl.engineGetKeySpec(key, keySpec);
205    }
206
207    /**
208     * Translates the given key into a key from this key factory.
209     *
210     * @param key
211     *            the key to translate.
212     * @return the translated key.
213     * @throws InvalidKeyException
214     *             if the specified key can not be translated by this key
215     *             factory.
216     */
217    public final Key translateKey(Key key)
218                        throws InvalidKeyException {
219        return spiImpl.engineTranslateKey(key);
220    }
221}
222