1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.common.crypto;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.lang.reflect.Constructor;
25 import java.util.Map;
26 import java.util.Properties;
27
28 import org.apache.wss4j.common.ext.WSSecurityException;
29 import org.apache.wss4j.common.util.Loader;
30
31
32
33
34 public abstract class CryptoFactory {
35 private static final org.slf4j.Logger LOG =
36 org.slf4j.LoggerFactory.getLogger(CryptoFactory.class);
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public static Crypto getInstance() throws WSSecurityException {
55 return getInstance("crypto.properties");
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public static Crypto getInstance(Properties properties) throws WSSecurityException {
73 if (properties == null) {
74 LOG.debug("Cannot load Crypto instance as properties object is null");
75 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
76 "empty", new Object[] {"Cannot load Crypto instance as properties object is null"});
77 }
78 return getInstance(properties, Loader.getClassLoader(CryptoFactory.class), null);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public static Crypto getInstance(
99 Properties properties,
100 ClassLoader classLoader,
101 PasswordEncryptor passwordEncryptor
102 ) throws WSSecurityException {
103 if (properties == null) {
104 LOG.debug("Cannot load Crypto instance as properties object is null");
105 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
106 "empty", new Object[] {"Cannot load Crypto instance as properties object is null"});
107 }
108
109 String cryptoClassName = properties.getProperty("org.apache.wss4j.crypto.provider");
110 if (cryptoClassName == null) {
111 cryptoClassName = properties.getProperty("org.apache.ws.security.crypto.provider");
112 }
113
114 Class<? extends Crypto> cryptoClass = null;
115 if (cryptoClassName == null
116 || cryptoClassName.equals("org.apache.wss4j.common.crypto.Merlin")
117 || cryptoClassName.equals("org.apache.ws.security.components.crypto.Merlin")) {
118 try {
119 return new Merlin(properties, classLoader, passwordEncryptor);
120 } catch (Exception e) {
121 LOG.debug("Unable to instantiate Merlin", e);
122 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "empty",
123 new Object[] {"Cannot create Crypto class " + cryptoClassName});
124 }
125 } else {
126 try {
127
128 cryptoClass = Loader.loadClass(cryptoClassName, Crypto.class);
129 } catch (ClassNotFoundException ex) {
130 LOG.debug(ex.getMessage(), ex);
131 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex,
132 "empty", new Object[] {cryptoClassName + " Not Found"});
133 }
134 }
135 return loadClass(cryptoClass, properties, classLoader);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 public static Crypto getInstance(
156 Class<? extends Crypto> cryptoClass,
157 Map<Object, Object> map
158 ) throws WSSecurityException {
159 return loadClass(cryptoClass, map, Loader.getClassLoader(CryptoFactory.class));
160 }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public static Crypto getInstance(String propFilename) throws WSSecurityException {
179 return getInstance(propFilename, Loader.getClassLoader(CryptoFactory.class));
180 }
181
182 public static Crypto getInstance(
183 String propFilename,
184 ClassLoader customClassLoader
185 ) throws WSSecurityException {
186 Properties properties = getProperties(propFilename, customClassLoader);
187 return getInstance(properties, customClassLoader, null);
188 }
189
190
191
192
193
194
195
196
197 private static Crypto loadClass(
198 Class<? extends Crypto> cryptoClass,
199 Map<Object, Object> map,
200 ClassLoader loader
201 ) throws WSSecurityException {
202 LOG.debug("Using Crypto Engine [{}]", cryptoClass);
203 try {
204 Constructor<? extends Crypto> c = null;
205 try {
206 Class<?>[] classes = new Class[]{Map.class, ClassLoader.class};
207 c = cryptoClass.getConstructor(classes);
208 return c.newInstance(map, loader);
209 } catch (NoSuchMethodException ex) {
210 Class<?>[] classes =
211 new Class[]{Properties.class, Map.class, PasswordEncryptor.class};
212 c = cryptoClass.getConstructor(classes);
213 return c.newInstance(map, loader, null);
214 }
215 } catch (Exception e) {
216 if (LOG.isDebugEnabled()) {
217 LOG.debug("Unable to instantiate: " + cryptoClass.getName(), e);
218 }
219 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
220 "empty", new Object[] {cryptoClass + " cannot create instance"});
221 }
222 }
223
224
225
226
227
228
229
230
231 private static Crypto loadClass(
232 Class<? extends Crypto> cryptoClass,
233 Properties map,
234 ClassLoader loader
235 ) throws WSSecurityException {
236 LOG.debug("Using Crypto Engine [{}]", cryptoClass);
237 try {
238 Constructor<? extends Crypto> c = null;
239 try {
240 Class<?>[] classes = new Class[]{Properties.class, ClassLoader.class};
241 c = cryptoClass.getConstructor(classes);
242 return c.newInstance(map, loader);
243 } catch (NoSuchMethodException ex) {
244 Class<?>[] classes =
245 new Class[]{Properties.class, ClassLoader.class, PasswordEncryptor.class};
246 c = cryptoClass.getConstructor(classes);
247 return c.newInstance(map, loader, null);
248 }
249 } catch (Exception e) {
250 if (LOG.isDebugEnabled()) {
251 LOG.debug("Unable to instantiate: " + cryptoClass.getName(), e);
252 }
253 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e,
254 "empty", new Object[] {cryptoClass + " cannot create instance"});
255 }
256 }
257
258
259
260
261
262
263
264
265 public static Properties getProperties(
266 String propFilename,
267 ClassLoader loader
268 ) throws WSSecurityException {
269 Properties properties = new Properties();
270 try (InputStream is = Loader.loadInputStream(loader, propFilename)) {
271 if (is == null) {
272 throw new WSSecurityException(
273 WSSecurityException.ErrorCode.FAILURE,
274 "resourceNotFound",
275 new Object[] {propFilename}
276 );
277 }
278 properties.load(is);
279 } catch (IOException e) {
280 if (LOG.isDebugEnabled()) {
281 LOG.debug("Cannot find resource: " + propFilename, e);
282 }
283 throw new WSSecurityException(
284 WSSecurityException.ErrorCode.FAILURE, e,
285 "resourceNotFound", new Object[] {propFilename}
286 );
287 }
288 return properties;
289 }
290
291 }
292