1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.ws.security;
21
22 import java.lang.reflect.Field;
23 import java.security.AccessController;
24 import java.security.PrivilegedAction;
25 import java.security.PrivilegedExceptionAction;
26 import java.security.Provider;
27 import java.security.Security;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import javax.xml.namespace.QName;
32
33 import org.apache.ws.security.action.Action;
34 import org.apache.ws.security.processor.Processor;
35 import org.apache.ws.security.util.Loader;
36 import org.apache.ws.security.util.UUIDGenerator;
37 import org.apache.ws.security.validate.Validator;
38 import org.apache.xml.security.utils.XMLUtils;
39
40 /**
41 * WSSConfig <p/> Carries configuration data so the WSS4J spec compliance can be
42 * modified in runtime. Configure an instance of this object only if you need
43 * WSS4J to emulate certain industry clients or previous OASIS specifications
44 * for WS-Security interoperability testing purposes. <p/> The default settings
45 * follow the latest OASIS and changing anything might violate the OASIS specs.
46 * <p/> <b>WARNING: changing the default settings will break the compliance with
47 * the latest specs. Do this only if you know what you are doing.</b> <p/>
48 *
49 * @author Rami Jaamour (rjaamour@parasoft.com)
50 * @author Werner Dittmann (werner@apache.org)
51 */
52 public class WSSConfig {
53
54 private static final org.apache.commons.logging.Log LOG =
55 org.apache.commons.logging.LogFactory.getLog(WSSConfig.class);
56
57 /**
58 * The default collection of actions supported by the toolkit.
59 */
60 private static final Map<Integer, Class<?>> DEFAULT_ACTIONS;
61 static {
62 final Map<Integer, Class<?>> tmp = new HashMap<Integer, Class<?>>();
63 try {
64 tmp.put(
65 Integer.valueOf(WSConstants.UT),
66 org.apache.ws.security.action.UsernameTokenAction.class
67 );
68 tmp.put(
69 Integer.valueOf(WSConstants.ENCR),
70 org.apache.ws.security.action.EncryptionAction.class
71 );
72 tmp.put(
73 Integer.valueOf(WSConstants.SIGN),
74 org.apache.ws.security.action.SignatureAction.class
75 );
76 tmp.put(
77 Integer.valueOf(WSConstants.ST_SIGNED),
78 org.apache.ws.security.action.SAMLTokenSignedAction.class
79 );
80 tmp.put(
81 Integer.valueOf(WSConstants.ST_UNSIGNED),
82 org.apache.ws.security.action.SAMLTokenUnsignedAction.class
83 );
84 tmp.put(
85 Integer.valueOf(WSConstants.TS),
86 org.apache.ws.security.action.TimestampAction.class
87 );
88 tmp.put(
89 Integer.valueOf(WSConstants.UT_SIGN),
90 org.apache.ws.security.action.UsernameTokenSignedAction.class
91 );
92 tmp.put(
93 Integer.valueOf(WSConstants.SC),
94 org.apache.ws.security.action.SignatureConfirmationAction.class
95 );
96 } catch (final Exception ex) {
97 if (LOG.isDebugEnabled()) {
98 LOG.debug(ex.getMessage(), ex);
99 }
100 }
101 DEFAULT_ACTIONS = java.util.Collections.unmodifiableMap(tmp);
102 }
103
104 /**
105 * The default collection of processors supported by the toolkit
106 */
107 private static final Map<QName, Class<?>> DEFAULT_PROCESSORS;
108 static {
109 final Map<QName, Class<?>> tmp = new HashMap<QName, Class<?>>();
110 try {
111 tmp.put(
112 WSSecurityEngine.SAML_TOKEN,
113 org.apache.ws.security.processor.SAMLTokenProcessor.class
114 );
115 tmp.put(
116 WSSecurityEngine.SAML2_TOKEN,
117 org.apache.ws.security.processor.SAMLTokenProcessor.class
118 );
119 tmp.put(
120 WSSecurityEngine.ENCRYPTED_KEY,
121 org.apache.ws.security.processor.EncryptedKeyProcessor.class
122 );
123 tmp.put(
124 WSSecurityEngine.SIGNATURE,
125 org.apache.ws.security.processor.SignatureProcessor.class
126 );
127 tmp.put(
128 WSSecurityEngine.TIMESTAMP,
129 org.apache.ws.security.processor.TimestampProcessor.class
130 );
131 tmp.put(
132 WSSecurityEngine.USERNAME_TOKEN,
133 org.apache.ws.security.processor.UsernameTokenProcessor.class
134 );
135 tmp.put(
136 WSSecurityEngine.REFERENCE_LIST,
137 org.apache.ws.security.processor.ReferenceListProcessor.class
138 );
139 tmp.put(
140 WSSecurityEngine.SIGNATURE_CONFIRMATION,
141 org.apache.ws.security.processor.SignatureConfirmationProcessor.class
142 );
143 tmp.put(
144 WSSecurityEngine.DERIVED_KEY_TOKEN_05_02,
145 org.apache.ws.security.processor.DerivedKeyTokenProcessor.class
146 );
147 tmp.put(
148 WSSecurityEngine.DERIVED_KEY_TOKEN_05_12,
149 tmp.get(WSSecurityEngine.DERIVED_KEY_TOKEN_05_02)
150 );
151 tmp.put(
152 WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02,
153 org.apache.ws.security.processor.SecurityContextTokenProcessor.class
154 );
155 tmp.put(
156 WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_12,
157 tmp.get(WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02)
158 );
159 tmp.put(
160 WSSecurityEngine.BINARY_TOKEN,
161 org.apache.ws.security.processor.BinarySecurityTokenProcessor.class
162 );
163 tmp.put(
164 WSSecurityEngine.ENCRYPTED_DATA,
165 org.apache.ws.security.processor.EncryptedDataProcessor.class
166 );
167 } catch (final Exception ex) {
168 if (LOG.isDebugEnabled()) {
169 LOG.debug(ex.getMessage(), ex);
170 }
171 }
172 DEFAULT_PROCESSORS = java.util.Collections.unmodifiableMap(tmp);
173 }
174
175 /**
176 * The default collection of validators supported by the toolkit
177 */
178 private static final Map<QName, Class<?>> DEFAULT_VALIDATORS;
179 static {
180 final Map<QName, Class<?>> tmp = new HashMap<QName, Class<?>>();
181 try {
182 tmp.put(
183 WSSecurityEngine.SAML_TOKEN,
184 org.apache.ws.security.validate.SamlAssertionValidator.class
185 );
186 tmp.put(
187 WSSecurityEngine.SAML2_TOKEN,
188 org.apache.ws.security.validate.SamlAssertionValidator.class
189 );
190 tmp.put(
191 WSSecurityEngine.SIGNATURE,
192 org.apache.ws.security.validate.SignatureTrustValidator.class
193 );
194 tmp.put(
195 WSSecurityEngine.TIMESTAMP,
196 org.apache.ws.security.validate.TimestampValidator.class
197 );
198 tmp.put(
199 WSSecurityEngine.USERNAME_TOKEN,
200 org.apache.ws.security.validate.UsernameTokenValidator.class
201 );
202 } catch (final Exception ex) {
203 if (LOG.isDebugEnabled()) {
204 LOG.debug(ex.getMessage(), ex);
205 }
206 }
207 DEFAULT_VALIDATORS = java.util.Collections.unmodifiableMap(tmp);
208 }
209
210 protected boolean wsiBSPCompliant = true;
211
212 /**
213 * Set the timestamp precision mode. If set to <code>true</code> then use
214 * timestamps with milliseconds, otherwise omit the milliseconds. As per XML
215 * Date/Time specification the default is to include the milliseconds.
216 */
217 protected boolean precisionInMilliSeconds = true;
218
219 protected boolean enableSignatureConfirmation = false;
220
221 /**
222 * If set to true then the timestamp handling will throw an exception if the
223 * timestamp contains an expires element and the semantics are expired.
224 *
225 * If set to false, no exception will be thrown, even if the semantics are
226 * expired.
227 */
228 protected boolean timeStampStrict = true;
229
230 /**
231 * If this value is not null, then username token handling will throw an
232 * exception if the password type of the Username Token does not match this value
233 */
234 protected String requiredPasswordType = null;
235
236 /**
237 * The time in seconds between creation and expiry for a Timestamp. The default
238 * is 300 seconds (5 minutes).
239 */
240 protected int timeStampTTL = 300;
241
242 /**
243 * The time in seconds in the future within which the Created time of an incoming
244 * Timestamp is valid. The default is 60 seconds.
245 */
246 protected int timeStampFutureTTL = 60;
247
248 /**
249 * This variable controls whether types other than PasswordDigest or PasswordText
250 * are allowed when processing UsernameTokens.
251 *
252 * By default this is set to false so that the user doesn't have to explicitly
253 * reject custom token types in the callback handler.
254 */
255 protected boolean handleCustomPasswordTypes = false;
256
257 /**
258 * This variable controls whether (wsse) namespace qualified password types are
259 * accepted when processing UsernameTokens.
260 *
261 * By default this is set to false.
262 */
263 protected boolean allowNamespaceQualifiedPasswordTypes = false;
264
265 /**
266 * The secret key length to be used for UT_SIGN.
267 */
268 protected int secretKeyLength = WSConstants.WSE_DERIVED_KEY_LEN;
269
270 /**
271 * Whether the password should be treated as a binary value. This
272 * is needed to properly handle password equivalence for UsernameToken
273 * passwords. Binary passwords are Base64 encoded so they can be
274 * treated as strings in most places, but when the password digest
275 * is calculated or a key is derived from the password, the password
276 * will be Base64 decoded before being used. This is most useful for
277 * hashed passwords as password equivalents.
278 *
279 * See https://issues.apache.org/jira/browse/WSS-239
280 */
281 protected boolean passwordsAreEncoded = false;
282
283 /**
284 * The default wsu:Id allocator is a simple "start at 1 and increment up"
285 * thing that is very fast.
286 */
287 public static final WsuIdAllocator DEFAULT_ID_ALLOCATOR = new WsuIdAllocator() {
288 int i;
289 private synchronized String next() {
290 return Integer.toString(++i);
291 }
292 public String createId(String prefix, Object o) {
293 if (prefix == null) {
294 return next();
295 }
296 return prefix + next();
297 }
298
299 public String createSecureId(String prefix, Object o) {
300 if (prefix == null) {
301 return UUIDGenerator.getUUID();
302 }
303 return prefix + UUIDGenerator.getUUID();
304 }
305 };
306 protected WsuIdAllocator idAllocator = DEFAULT_ID_ALLOCATOR;
307
308 /**
309 * The known actions. This map is of the form <Integer, Class<?>> or
310 * <Integer, Action>.
311 * The known actions are initialized from a set of defaults,
312 * but the list may be modified via the setAction operations.
313 */
314 private final Map<Integer, Object> actionMap =
315 new HashMap<Integer, Object>(DEFAULT_ACTIONS);
316
317 /**
318 * The known processors. This map is of the form <QName, Class<?>> or
319 * <QName, Processor>.
320 * The known processors are initialized from a set of defaults,
321 * but the list may be modified via the setProcessor operations.
322 */
323 private final Map<QName, Object> processorMap =
324 new HashMap<QName, Object>(DEFAULT_PROCESSORS);
325
326 /**
327 * The known validators. This map is of the form <QName, Class<?>> or
328 * <QName, Validator>.
329 * The known validators are initialized from a set of defaults,
330 * but the list may be modified via the setValidator operations.
331 */
332 private final Map<QName, Object> validatorMap =
333 new HashMap<QName, Object>(DEFAULT_VALIDATORS);
334
335 /**
336 * a static boolean flag that determines whether default JCE providers
337 * should be added at the time of construction.
338 *
339 * These providers, and the order in which they are added, can interfere
340 * with some JVMs (such as IBMs).
341 */
342 private static boolean addJceProviders = true;
343
344 /**
345 * a boolean flag to record whether we have already been statically
346 * initialized. This flag prevents repeated and unnecessary calls
347 * to static initialization code at construction time.
348 */
349 private static boolean staticallyInitialized = false;
350
351 /**
352 * Set the value of the internal addJceProviders flag. This flag
353 * turns on (or off) automatic registration of known JCE providers
354 * that provide necessary cryptographic algorithms for use with WSS4J.
355 * By default, this flag is true. You may wish (or need) to initialize
356 * the JCE manually, e.g., in some JVMs.
357 */
358 public static void setAddJceProviders(boolean value) {
359 addJceProviders = value;
360 }
361
362 private static void setXmlSecIgnoreLineBreak() {
363 //really need to make sure ignoreLineBreaks is set to
364 boolean wasSet = false;
365 try {
366 // Don't override if it was set explicitly
367 wasSet = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
368 public Boolean run() {
369 String lineBreakPropName = "org.apache.xml.security.ignoreLineBreaks";
370 if (System.getProperty(lineBreakPropName) == null) {
371 System.setProperty(lineBreakPropName, "true");
372 return false;
373 }
374 return true;
375 }
376 });
377 } catch (Throwable t) { //NOPMD
378 //ignore
379 }
380 org.apache.xml.security.Init.init();
381 if (!wasSet) {
382 try {
383 AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
384 public Boolean run() throws Exception {
385 Field f = XMLUtils.class.getDeclaredField("ignoreLineBreaks");
386 f.setAccessible(true);
387 f.set(null, Boolean.TRUE);
388 return false;
389 }
390 });
391 } catch (Throwable t) { //NOPMD
392 //ignore
393 }
394 }
395 }
396
397 public static synchronized void init() {
398 if (!staticallyInitialized) {
399 if (addJceProviders) {
400 setXmlSecIgnoreLineBreak();
401 AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
402 public Boolean run() {
403 addXMLDSigRI();
404 addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
405 Security.removeProvider("STRTransform");
406 appendJceProvider(
407 "STRTransform", new org.apache.ws.security.transform.STRTransformProvider()
408 );
409
410 return true;
411 }
412 });
413 }
414 staticallyInitialized = true;
415 }
416 }
417
418 private static void addXMLDSigRI() {
419 try {
420 addXMLDSigRIInternal();
421 } catch (Throwable t) {
422 //ignore - may be a NoClassDefFound if XMLDSigRI isn't avail
423 return;
424 }
425 }
426
427 public static void addXMLDSigRIInternal() {
428 addJceProvider("ApacheXMLDSig", SantuarioUtil.getSantuarioProvider());
429 }
430
431 /**
432 * @return a new WSSConfig instance configured with the default values
433 */
434 public static WSSConfig getNewInstance() {
435 init();
436 return new WSSConfig();
437 }
438
439 /**
440 * Checks if we are in WS-I Basic Security Profile compliance mode
441 *
442 * @return whether we are in WS-I Basic Security Profile compliance mode
443 */
444 public boolean isWsiBSPCompliant() {
445 return wsiBSPCompliant;
446 }
447
448 /**
449 * Set the WS-I Basic Security Profile compliance mode. The default is true.
450 *
451 * @param wsiBSPCompliant
452 */
453 public void setWsiBSPCompliant(boolean wsiBSPCompliant) {
454 this.wsiBSPCompliant = wsiBSPCompliant;
455 }
456
457 /**
458 * Checks if we need to use milliseconds in timestamps
459 *
460 * @return whether to use precision in milliseconds for timestamps
461 */
462 public boolean isPrecisionInMilliSeconds() {
463 return precisionInMilliSeconds;
464 }
465
466 /**
467 * Set the precision in milliseconds for timestamps
468 *
469 * @param precisionInMilliSeconds whether to use precision in milliseconds for timestamps
470 */
471 public void setPrecisionInMilliSeconds(boolean precisionInMilliSeconds) {
472 this.precisionInMilliSeconds = precisionInMilliSeconds;
473 }
474
475 /**
476 * @return Returns the enableSignatureConfirmation.
477 */
478 public boolean isEnableSignatureConfirmation() {
479 return enableSignatureConfirmation;
480 }
481
482 /**
483 * @param enableSignatureConfirmation
484 * The enableSignatureConfirmation to set.
485 */
486 public void setEnableSignatureConfirmation(boolean enableSignatureConfirmation) {
487 this.enableSignatureConfirmation = enableSignatureConfirmation;
488 }
489
490 /**
491 * @param handleCustomTypes
492 * whether to handle custom UsernameToken password types or not
493 */
494 public void setHandleCustomPasswordTypes(boolean handleCustomTypes) {
495 this.handleCustomPasswordTypes = handleCustomTypes;
496 }
497
498 /**
499 * @return whether custom UsernameToken password types are allowed or not
500 */
501 public boolean getHandleCustomPasswordTypes() {
502 return handleCustomPasswordTypes;
503 }
504
505 /**
506 * @param allowNamespaceQualifiedTypes
507 * whether (wsse) namespace qualified password types are accepted or not
508 */
509 public void setAllowNamespaceQualifiedPasswordTypes(boolean allowNamespaceQualifiedTypes) {
510 allowNamespaceQualifiedPasswordTypes = allowNamespaceQualifiedTypes;
511 }
512
513 /**
514 * @return whether (wsse) namespace qualified password types are accepted or not
515 */
516 public boolean getAllowNamespaceQualifiedPasswordTypes() {
517 return allowNamespaceQualifiedPasswordTypes;
518 }
519
520 /**
521 * @return Returns if we shall throw an exception on expired request
522 * semantic
523 */
524 public boolean isTimeStampStrict() {
525 return timeStampStrict;
526 }
527
528 /**
529 * @param timeStampStrict
530 * If true throw an exception on expired request semantic
531 */
532 public void setTimeStampStrict(boolean timeStampStrict) {
533 this.timeStampStrict = timeStampStrict;
534 }
535
536 /**
537 * @return the required password type when processing a UsernameToken
538 */
539 public String getRequiredPasswordType() {
540 return requiredPasswordType;
541 }
542
543 /**
544 * @param requiredPasswordType The required password type when processing
545 * a Username Token.
546 */
547 public void setRequiredPasswordType(String requiredPasswordType) {
548 this.requiredPasswordType = requiredPasswordType;
549 }
550
551 /**
552 * @return Returns the TTL of a Timestamp in seconds
553 */
554 public int getTimeStampTTL() {
555 return timeStampTTL;
556 }
557
558 /**
559 * @param timeStampTTL The new value for timeStampTTL
560 */
561 public void setTimeStampTTL(int timeStampTTL) {
562 this.timeStampTTL = timeStampTTL;
563 }
564
565 /**
566 * @return Returns the Future TTL of a Timestamp in seconds
567 */
568 public int getTimeStampFutureTTL() {
569 return timeStampFutureTTL;
570 }
571
572 /**
573 * @param timeStampFutureTTL the new value for timeStampFutureTTL
574 */
575 public void setTimeStampFutureTTL(int timeStampFutureTTL) {
576 this.timeStampFutureTTL = timeStampFutureTTL;
577 }
578
579 /**
580 * Set the secret key length to be used for UT_SIGN.
581 */
582 public void setSecretKeyLength(int length) {
583 secretKeyLength = length;
584 }
585
586 /**
587 * Get the secret key length to be used for UT_SIGN.
588 */
589 public int getSecretKeyLength() {
590 return secretKeyLength;
591 }
592
593 /**
594 * @param passwordsAreEncoded
595 * whether passwords are encoded
596 */
597 public void setPasswordsAreEncoded(boolean passwordsAreEncoded) {
598 this.passwordsAreEncoded = passwordsAreEncoded;
599 }
600
601 /**
602 * @return whether passwords are encoded
603 */
604 public boolean getPasswordsAreEncoded() {
605 return passwordsAreEncoded;
606 }
607
608 /**
609 * @return Returns the WsuIdAllocator used to generate wsu:Id attributes
610 */
611 public WsuIdAllocator getIdAllocator() {
612 return idAllocator;
613 }
614
615 public void setIdAllocator(WsuIdAllocator idAllocator) {
616 this.idAllocator = idAllocator;
617 }
618
619 /**
620 * Associate an action instance with a specific action code.
621 *
622 * This operation allows applications to supply their own
623 * actions for well-known operations.
624 *
625 * Please note that the Action object does NOT get class-loaded per invocation, and so
626 * it is up to the implementing class to ensure that it is thread-safe.
627 */
628 public Class<?> setAction(int code, Action action) {
629 Object result = actionMap.put(Integer.valueOf(code), action);
630 if (result instanceof Class<?>) {
631 return (Class<?>)result;
632 } else if (result instanceof Action) {
633 return result.getClass();
634 }
635 return null;
636 }
637
638 /**
639 * Associate an action instance with a specific action code.
640 *
641 * This operation allows applications to supply their own
642 * actions for well-known operations.
643 */
644 public Class<?> setAction(int code, Class<?> clazz) {
645 Object result = actionMap.put(Integer.valueOf(code), clazz);
646 if (result instanceof Class<?>) {
647 return (Class<?>)result;
648 } else if (result instanceof Action) {
649 return result.getClass();
650 }
651 return null;
652 }
653
654 /**
655 * Lookup action
656 *
657 * @param action
658 * @return An action class to create a security token
659 * @throws WSSecurityException
660 */
661 public Action getAction(int action) throws WSSecurityException {
662 final Object actionObject = actionMap.get(Integer.valueOf(action));
663
664 if (actionObject instanceof Class<?>) {
665 try {
666 return (Action)((Class<?>)actionObject).newInstance();
667 } catch (Throwable t) {
668 if (LOG.isDebugEnabled()) {
669 LOG.debug(t.getMessage(), t);
670 }
671 throw new WSSecurityException(WSSecurityException.FAILURE,
672 "unableToLoadClass", new Object[] { ((Class<?>)actionObject).getName() }, t);
673 }
674 } else if (actionObject instanceof Action) {
675 return (Action)actionObject;
676 }
677 return null;
678 }
679
680 /**
681 * Associate a SOAP processor name with a specified SOAP Security header
682 * element QName. Processors registered under this QName will be
683 * called when processing header elements with the specified type.
684 *
685 * Please note that the Processor object does NOT get class-loaded per invocation, and so
686 * it is up to the implementing class to ensure that it is thread-safe.
687 */
688 public Class<?> setProcessor(QName el, Processor processor) {
689 Object result = processorMap.put(el, processor);
690 if (result instanceof Class<?>) {
691 return (Class<?>)result;
692 } else if (result instanceof Processor) {
693 return result.getClass();
694 }
695 return null;
696 }
697
698 /**
699 * Associate a SOAP processor name with a specified SOAP Security header
700 * element QName. Processors registered under this QName will be
701 * called when processing header elements with the specified type.
702 */
703 public Class<?> setProcessor(QName el, Class<?> clazz) {
704 Object result = processorMap.put(el, clazz);
705 if (result instanceof Class<?>) {
706 return (Class<?>)result;
707 } else if (result instanceof Processor) {
708 return result.getClass();
709 }
710 return null;
711 }
712
713 /**
714 * Associate a SOAP validator name with a specified SOAP Security header
715 * element QName. Validators registered under this QName will be
716 * called when processing header elements with the specified type.
717 *
718 * Please note that the Validator object does NOT get class-loaded per invocation, and so
719 * it is up to the implementing class to ensure that it is thread-safe.
720 */
721 public Class<?> setValidator(QName el, Validator validator) {
722 Object result = validatorMap.put(el, validator);
723 if (result instanceof Class<?>) {
724 return (Class<?>)result;
725 } else if (result instanceof Validator) {
726 return result.getClass();
727 }
728 return null;
729 }
730
731 /**
732 * Associate a SOAP validator name with a specified SOAP Security header
733 * element QName. validator registered under this QName will be
734 * called when processing header elements with the specified type.
735 */
736 public Class<?> setValidator(QName el, Class<?> clazz) {
737 Object result = validatorMap.put(el, clazz);
738 if (result instanceof Class<?>) {
739 return (Class<?>)result;
740 } else if (result instanceof Validator) {
741 return result.getClass();
742 }
743 return null;
744 }
745
746 /**
747 * @return the SOAP Validator associated with the specified
748 * QName. The QName is intended to refer to an element
749 * in a SOAP security header. This operation returns
750 * null if there is no Validator associated with the
751 * specified QName.
752 */
753 public Validator getValidator(QName el) throws WSSecurityException {
754 final Object validatorObject = validatorMap.get(el);
755
756 if (validatorObject instanceof Class<?>) {
757 try {
758 return (Validator)((Class<?>)validatorObject).newInstance();
759 } catch (Throwable t) {
760 if (LOG.isDebugEnabled()) {
761 LOG.debug(t.getMessage(), t);
762 }
763 throw new WSSecurityException(WSSecurityException.FAILURE,
764 "unableToLoadClass", new Object[] { ((Class<?>)validatorObject).getName() }, t);
765 }
766 } else if (validatorObject instanceof Validator) {
767 return (Validator)validatorObject;
768 }
769 return null;
770 }
771
772 /**
773 * @return the SOAP processor associated with the specified
774 * QName. The QName is intended to refer to an element
775 * in a SOAP security header. This operation returns
776 * null if there is no processor associated with the
777 * specified QName.
778 */
779 public Processor getProcessor(QName el) throws WSSecurityException {
780 final Object processorObject = processorMap.get(el);
781
782 if (processorObject instanceof Class<?>) {
783 try {
784 return (Processor)((Class<?>)processorObject).newInstance();
785 } catch (Throwable t) {
786 if (LOG.isDebugEnabled()) {
787 LOG.debug(t.getMessage(), t);
788 }
789 throw new WSSecurityException(WSSecurityException.FAILURE,
790 "unableToLoadClass", new Object[] { ((Class<?>)processorObject).getName() }, t);
791 }
792 } else if (processorObject instanceof Processor) {
793 return (Processor)processorObject;
794 }
795 return null;
796 }
797
798 /**
799 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
800 * either the name of the previously loaded provider, the name of the new loaded provider, or
801 * null if there's an exception in loading the provider. Add the provider either after the SUN
802 * provider (see WSS-99), or the IBMJCE provider. Otherwise fall back to the old behaviour of
803 * inserting the provider in position 2.
804 *
805 * @param name
806 * The name string of the provider (this may not be the real name of the provider)
807 * @param className
808 * Name of the class the implements the provider. This class must
809 * be a subclass of <code>java.security.Provider</code>
810 *
811 * @return Returns the actual name of the provider that was loaded
812 */
813 public static String addJceProvider(String name, String className) {
814 Provider currentProvider = Security.getProvider(name);
815 if (currentProvider == null) {
816 try {
817 Class<? extends Provider> clazz = Loader.loadClass(className, false, Provider.class);
818 Provider provider = clazz.newInstance();
819 return addJceProvider(name, provider);
820 } catch (Throwable t) {
821 if (LOG.isDebugEnabled()) {
822 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
823 }
824 return null;
825 }
826 }
827 return currentProvider.getName();
828 }
829
830 /**
831 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
832 * either the name of the previously loaded provider, the name of the new loaded provider, or
833 * null if there's an exception in loading the provider. Add the provider either after the SUN
834 * provider (see WSS-99), or the IBMJCE provider. Otherwise fall back to the old behaviour of
835 * inserting the provider in position 2.
836 *
837 * @param name
838 * The name string of the provider (this may not be the real name of the provider)
839 * @param provider
840 * A subclass of <code>java.security.Provider</code>
841 *
842 * @return Returns the actual name of the provider that was loaded
843 */
844 public static String addJceProvider(String name, Provider provider) {
845 Provider currentProvider = Security.getProvider(name);
846 if (currentProvider == null) {
847 try {
848 //
849 // Install the provider after the SUN provider (see WSS-99)
850 // Otherwise fall back to the old behaviour of inserting
851 // the provider in position 2. For AIX, install it after
852 // the IBMJCE provider.
853 //
854 int ret = 0;
855 Provider[] provs = Security.getProviders();
856 for (int i = 0; i < provs.length; i++) {
857 if ("SUN".equals(provs[i].getName())
858 || "IBMJCE".equals(provs[i].getName())) {
859 ret = Security.insertProviderAt(provider, i + 2);
860 break;
861 }
862 }
863 if (ret == 0) {
864 ret = Security.insertProviderAt(provider, 2);
865 }
866 if (LOG.isDebugEnabled()) {
867 LOG.debug(
868 "The provider " + provider.getName() + " - "
869 + provider.getVersion() + " was added at position: " + ret
870 );
871 }
872 return provider.getName();
873 } catch (Throwable t) {
874 if (LOG.isDebugEnabled()) {
875 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
876 }
877 return null;
878 }
879 }
880 return currentProvider.getName();
881 }
882
883
884 /**
885 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
886 * either the name of the previously loaded provider, the name of the new loaded provider, or
887 * null if there's an exception in loading the provider. Append the provider to the provider
888 * list.
889 *
890 * @param name
891 * The name string of the provider (this may not be the real name of the provider)
892 * @param className
893 * Name of the class the implements the provider. This class must
894 * be a subclass of <code>java.security.Provider</code>
895 *
896 * @return Returns the actual name of the provider that was loaded
897 */
898 public static String appendJceProvider(String name, String className) {
899 Provider currentProvider = Security.getProvider(name);
900 if (currentProvider == null) {
901 try {
902 Class<? extends Provider> clazz = Loader.loadClass(className, false, Provider.class);
903 Provider provider = clazz.newInstance();
904
905 int ret = Security.addProvider(provider);
906 if (LOG.isDebugEnabled()) {
907 LOG.debug(
908 "The provider " + provider.getName()
909 + " was added at position: " + ret
910 );
911 }
912 return provider.getName();
913 } catch (Throwable t) {
914 if (LOG.isDebugEnabled()) {
915 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
916 }
917 return null;
918 }
919 }
920 return currentProvider.getName();
921 }
922
923 /**
924 * Add a new JCE security provider to use for WSS4J, of the specified name and class. Return
925 * either the name of the previously loaded provider, the name of the new loaded provider, or
926 * null if there's an exception in loading the provider. Append the provider to the provider
927 * list.
928 *
929 * @param name
930 * The name string of the provider (this may not be the real name of the provider)
931 * @param provider
932 * A subclass of <code>java.security.Provider</code>
933 *
934 * @return Returns the actual name of the provider that was loaded
935 */
936 public static String appendJceProvider(String name, Provider provider) {
937 Provider currentProvider = Security.getProvider(name);
938 if (currentProvider == null) {
939 try {
940 int ret = Security.addProvider(provider);
941 if (LOG.isDebugEnabled()) {
942 LOG.debug(
943 "The provider " + provider.getName()
944 + " was added at position: " + ret
945 );
946 }
947 return provider.getName();
948 } catch (Throwable t) {
949 if (LOG.isDebugEnabled()) {
950 LOG.debug("The provider " + name + " could not be added: " + t.getMessage(), t);
951 }
952 return null;
953 }
954 }
955 return currentProvider.getName();
956 }
957
958 }