1 /*
2 * Copyright �, Aegeus Technology Limited. All rights reserved.
3 */
4 package jsdsi.util;
5
6 import java.net.URI;
7 import java.security.InvalidAlgorithmParameterException;
8 import java.security.KeyPair;
9 import java.security.KeyPairGenerator;
10 import java.security.NoSuchAlgorithmException;
11 import java.util.HashMap;
12 import java.util.Map;
13
14 import jsdsi.JsdsiRuntimeException;
15
16 /***
17 * Convenience class for generating <code>java.security.KeyPair</code> 's. <p/>This class
18 * maintains a cache of KeyPairGenerators retrieved from the JCE for performance. <p/><strong>Note:
19 * </strong> Care should be taken when creating Keys without specifying a keysize, SecureRandom, or
20 * any AlgorithmParameterSpec, as it has been noted that without, keys are predictable when using
21 * some Providers.
22 *
23 * @author Sean Radford
24 * @version $Revision: 1.7 $ $Date: 2004/11/12 09:53:49 $
25 */
26 public final class KeyPairFactory {
27
28 private static final int KEYSIZE_NOT_SPECIFIED = -1;
29
30 private static Map generators = new HashMap();
31
32 private static KeyPairFactory factory = null;
33
34 private KeyPairFactory() {
35 super();
36 }
37
38 /***
39 * Singleton constructor method.
40 *
41 * @return
42 */
43 private static synchronized KeyPairFactory getInstance() {
44 if (factory == null) {
45 factory = new KeyPairFactory();
46 }
47 return factory;
48 }
49
50 /***
51 * Generates a KeyPair of the given <code>keyEnum</code> type. The public key of the KeyPair
52 * is a {@link jsdsi.Principal jsdsi.Principal}.
53 *
54 * @param keyEnum the key algorithm.
55 * @return the new KeyPair
56 * @throws NoSuchAlgorithmException if the algorithm is not available in the environment.
57 */
58 public static KeyPair create(KeyEnum keyEnum) throws NoSuchAlgorithmException {
59 return create(keyEnum, KEYSIZE_NOT_SPECIFIED, (URI[]) null);
60 }
61
62 /***
63 * Generates a KeyPair of the given <code>keyEnum</code> type and key size. The public key of
64 * the KeyPair is a {@link jsdsi.Principal jsdsi.Principal}.
65 *
66 * @param keyEnum the key algorithm.
67 * @param keysize the keysize. This is an algorithm-specific metric, such as modulus length,
68 * specified in number of bits.
69 * @return the new KeyPair
70 * @throws NoSuchAlgorithmException if the algorithm is not available in the environment.
71 */
72 public static KeyPair create(KeyEnum keyEnum,
73 int keysize) throws NoSuchAlgorithmException {
74 return create(keyEnum, keysize, (URI[]) null);
75 }
76
77 /***
78 * Generates a KeyPair of the given <code>keyEnum</code> type with the given <code>uris</code>.
79 * The public key of the KeyPair is a {@link jsdsi.Principal jsdsi.Principal}.
80 *
81 * @param keyEnum the key algorithm.
82 * @param uris URI's where information about the Principal may be sought
83 * @return the new KeyPair
84 * @throws NoSuchAlgorithmException if the algorithm is not available in the environment.
85 */
86 public static KeyPair create(KeyEnum keyEnum,
87 URI[] uris) throws NoSuchAlgorithmException {
88 return create(keyEnum, KEYSIZE_NOT_SPECIFIED, uris);
89 }
90
91 /***
92 * Generates a KeyPair of the given <code>keyEnum</code> type and <code>uris</code>. The
93 * public key of the KeyPair is a {@link jsdsi.Principal jsdsi.Principal}.
94 *
95 * @param keyEnum the key algorithm.
96 * @param keysize the keysize. This is an algorithm-specific metric, such as modulus length,
97 * specified in number of bits.
98 * @param uris URI's where information about the Principal may be sought
99 * @return the new KeyPair
100 * @throws NoSuchAlgorithmException if the algorithm is not available in the environment.
101 */
102 public static KeyPair create(KeyEnum keyEnum, int keysize, URI[] uris)
103 throws NoSuchAlgorithmException {
104 KeyPairGenerator kpg = getKeyPairGenerator(keyEnum, keysize, uris);
105 return kpg.generateKeyPair();
106 }
107
108 /***
109 * Retrieves a KeyPairGenerator.
110 *
111 * @param keyEnum
112 * @param keysize
113 * @param uris
114 * @return the KeyPairGenerator
115 * @throws NoSuchAlgorithmException
116 */
117 public static synchronized KeyPairGenerator getKeyPairGenerator(KeyEnum keyEnum, int keysize,
118 URI[] uris) throws NoSuchAlgorithmException {
119 String key = calculateKey(keyEnum, keysize, uris);
120 KeyPairGenerator kpg = (KeyPairGenerator) generators.get(key);
121 if (kpg == null) {
122 kpg = createKeyPairGenerator(keyEnum, keysize, uris);
123 generators.put(key, kpg);
124 }
125 return kpg;
126 }
127
128 /***
129 * Calculates the key to use for the Map of <code>generators</code>.
130 *
131 * @param keyEnum key algorithm
132 * @param keysize length of key
133 * @param uris array of URIs for key
134 * @return the key
135 */
136 private static String calculateKey(KeyEnum keyEnum,
137 int keysize, URI[] uris) {
138 StringBuffer sb = new StringBuffer(keyEnum.spkiName());
139 if (keysize != KEYSIZE_NOT_SPECIFIED) {
140 sb.append('^');
141 sb.append(keysize);
142 }
143 if (uris != null) {
144 for (int i = 0; i < uris.length; i++) {
145 sb.append('^');
146 sb.append(uris[i].toString());
147 }
148
149 }
150 return sb.toString();
151 }
152
153 private static KeyPairGenerator createKeyPairGenerator(KeyEnum keyEnum,
154 int keysize,
155 URI[] uris) {
156 KeyPairGenerator kpg;
157 try {
158 kpg = KeyPairGenerator.getInstance("SPKI/" + keyEnum.jdkName());
159 } catch (NoSuchAlgorithmException e) {
160 throw new JsdsiRuntimeException(e.toString(), e);
161 }
162 if (keyEnum.equals(KeyEnum.RSA)) {
163 if (uris == null) {
164 if (keysize != KEYSIZE_NOT_SPECIFIED) {
165 kpg.initialize(keysize);
166 }
167 } else {
168 RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(keysize,
169 null,
170 uris);
171 try {
172 kpg.initialize(spec);
173 } catch (InvalidAlgorithmParameterException e) {
174 throw new JsdsiRuntimeException(e.toString(), e);
175 }
176 }
177 } else {
178 throw new IllegalArgumentException("Currently unsupported Key Algorithm");
179 }
180 return kpg;
181 }
182
183 }
This page was automatically generated by Maven