1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.handler;
21
22 import java.security.cert.X509Certificate;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.regex.Pattern;
32 import java.util.regex.PatternSyntaxException;
33
34 import javax.security.auth.callback.Callback;
35 import javax.security.auth.callback.CallbackHandler;
36
37 import org.apache.ws.security.WSConstants;
38 import org.apache.ws.security.WSEncryptionPart;
39 import org.apache.ws.security.WSPasswordCallback;
40 import org.apache.ws.security.WSSConfig;
41 import org.apache.ws.security.WSSecurityEngine;
42 import org.apache.ws.security.WSSecurityEngineResult;
43 import org.apache.ws.security.WSSecurityException;
44 import org.apache.ws.security.action.Action;
45 import org.apache.ws.security.components.crypto.AlgorithmSuite;
46 import org.apache.ws.security.components.crypto.Crypto;
47 import org.apache.ws.security.components.crypto.CryptoFactory;
48 import org.apache.ws.security.message.WSSecHeader;
49 import org.apache.ws.security.message.token.SignatureConfirmation;
50 import org.apache.ws.security.util.Loader;
51 import org.apache.ws.security.util.StringUtil;
52 import org.apache.ws.security.util.WSSecurityUtil;
53 import org.w3c.dom.Document;
54
55
56
57
58
59
60
61
62
63
64 public abstract class WSHandler {
65 private static org.apache.commons.logging.Log log =
66 org.apache.commons.logging.LogFactory.getLog(WSHandler.class);
67 protected WSSecurityEngine secEngine = new WSSecurityEngine();
68 protected Map<String, Crypto> cryptos = new ConcurrentHashMap<String, Crypto>();
69
70 private boolean doDebug = log.isDebugEnabled();
71
72
73
74
75
76
77
78
79
80
81
82
83 @SuppressWarnings("unchecked")
84 protected void doSenderAction(
85 int doAction,
86 Document doc,
87 RequestData reqData,
88 List<Integer> actions,
89 boolean isRequest
90 ) throws WSSecurityException {
91
92 boolean mu = decodeMustUnderstand(reqData);
93
94 WSSConfig wssConfig = reqData.getWssConfig();
95 if (wssConfig == null) {
96 wssConfig = secEngine.getWssConfig();
97 }
98
99 boolean enableSigConf = decodeEnableSignatureConfirmation(reqData);
100 wssConfig.setEnableSignatureConfirmation(
101 enableSigConf || ((doAction & WSConstants.SC) != 0)
102 );
103 wssConfig.setPasswordsAreEncoded(decodeUseEncodedPasswords(reqData));
104
105 wssConfig.setPrecisionInMilliSeconds(
106 decodeTimestampPrecision(reqData)
107 );
108 reqData.setWssConfig(wssConfig);
109
110 Object mc = reqData.getMsgContext();
111 String actor = getString(WSHandlerConstants.ACTOR, mc);
112 reqData.setActor(actor);
113
114 WSSecHeader secHeader = new WSSecHeader(actor, mu);
115 secHeader.insertSecurityHeader(doc);
116
117 reqData.setSecHeader(secHeader);
118 reqData.setSoapConstants(
119 WSSecurityUtil.getSOAPConstants(doc.getDocumentElement())
120 );
121 wssConfig.setWsiBSPCompliant(decodeBSPCompliance(reqData));
122
123
124
125
126 if ((doAction & WSConstants.UT) == WSConstants.UT) {
127 decodeUTParameter(reqData);
128 }
129
130
131
132
133 if ((doAction & WSConstants.UT_SIGN) == WSConstants.UT_SIGN) {
134 decodeUTParameter(reqData);
135 decodeSignatureParameter(reqData);
136 }
137
138
139
140
141 if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
142 if (reqData.getSigCrypto() == null) {
143 reqData.setSigCrypto(loadSignatureCrypto(reqData));
144 }
145 decodeSignatureParameter(reqData);
146 }
147
148
149
150
151
152 if ((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED) {
153 decodeSignatureParameter(reqData);
154 }
155
156
157
158
159 if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
160 if (reqData.getEncCrypto() == null) {
161 reqData.setEncCrypto(loadEncryptionCrypto(reqData));
162 }
163 decodeEncryptionParameter(reqData);
164 }
165
166
167
168
169
170
171 if (reqData.getSignatureParts().isEmpty()) {
172 WSEncryptionPart encP = new WSEncryptionPart(reqData.getSoapConstants()
173 .getBodyQName().getLocalPart(), reqData.getSoapConstants()
174 .getEnvelopeURI(), "Content");
175 reqData.getSignatureParts().add(encP);
176 }
177
178
179
180
181
182
183 if (wssConfig.isEnableSignatureConfirmation() && !isRequest) {
184 String done =
185 (String)getProperty(reqData.getMsgContext(), WSHandlerConstants.SIG_CONF_DONE);
186 if (done == null) {
187 wssConfig.getAction(WSConstants.SC).execute(this, WSConstants.SC, doc, reqData);
188 }
189 }
190
191
192
193
194 List<Integer> actionsToPerform = actions;
195 if (actions.contains(WSConstants.SIGN) && actions.contains(WSConstants.TS)
196 && (actions.indexOf(WSConstants.SIGN) < actions.indexOf(WSConstants.TS))) {
197 boolean signTimestamp = false;
198 for (WSEncryptionPart encP : reqData.getSignatureParts()) {
199 if (WSConstants.WSU_NS.equals(encP.getNamespace())
200 && "Timestamp".equals(encP.getName())) {
201 signTimestamp = true;
202 }
203 }
204 if (signTimestamp) {
205 actionsToPerform = new ArrayList<Integer>(actions);
206 Collections.copy(actionsToPerform, actions);
207 actionsToPerform.remove(actions.indexOf(WSConstants.SIGN));
208 actionsToPerform.add(WSConstants.SIGN);
209 reqData.setAppendSignatureAfterTimestamp(true);
210 }
211 }
212
213
214
215
216
217 for (Integer actionToDo : actionsToPerform) {
218 if (doDebug) {
219 log.debug("Performing Action: " + actionToDo);
220 }
221
222 switch (actionToDo) {
223 case WSConstants.UT:
224 case WSConstants.ENCR:
225 case WSConstants.SIGN:
226 case WSConstants.ST_SIGNED:
227 case WSConstants.ST_UNSIGNED:
228 case WSConstants.TS:
229 case WSConstants.UT_SIGN:
230 wssConfig.getAction(actionToDo).execute(this, actionToDo, doc, reqData);
231 break;
232
233
234
235
236
237 default:
238 Action doit = null;
239 try {
240 doit = wssConfig.getAction(actionToDo);
241 } catch (final WSSecurityException e) {
242 log.warn(
243 "Error trying to locate a custom action (" + actionToDo + ")",
244 e
245 );
246 }
247 if (doit != null) {
248 doit.execute(this, actionToDo, doc, reqData);
249 }
250 }
251 }
252
253
254
255
256
257
258 if (wssConfig.isEnableSignatureConfirmation()
259 && isRequest && reqData.getSignatureValues().size() > 0) {
260 List<byte[]> savedSignatures =
261 (List<byte[]>)getProperty(reqData.getMsgContext(), WSHandlerConstants.SEND_SIGV);
262 if (savedSignatures == null) {
263 savedSignatures = new ArrayList<byte[]>();
264 setProperty(
265 reqData.getMsgContext(), WSHandlerConstants.SEND_SIGV, savedSignatures
266 );
267 }
268 savedSignatures.addAll(reqData.getSignatureValues());
269 }
270 }
271
272 protected void doReceiverAction(int doAction, RequestData reqData)
273 throws WSSecurityException {
274
275 WSSConfig wssConfig = reqData.getWssConfig();
276 if (wssConfig == null) {
277 wssConfig = secEngine.getWssConfig();
278 }
279 boolean enableSigConf = decodeEnableSignatureConfirmation(reqData);
280 wssConfig.setEnableSignatureConfirmation(
281 enableSigConf || ((doAction & WSConstants.SC) != 0)
282 );
283 wssConfig.setTimeStampStrict(decodeTimestampStrict(reqData));
284 if (decodePasswordTypeStrict(reqData)) {
285 String passwordType = decodePasswordType(reqData);
286 wssConfig.setRequiredPasswordType(passwordType);
287 }
288 wssConfig.setTimeStampTTL(decodeTimeToLive(reqData));
289 wssConfig.setTimeStampFutureTTL(decodeFutureTimeToLive(reqData));
290 wssConfig.setHandleCustomPasswordTypes(decodeCustomPasswordTypes(reqData));
291 wssConfig.setPasswordsAreEncoded(decodeUseEncodedPasswords(reqData));
292 wssConfig.setAllowNamespaceQualifiedPasswordTypes(
293 decodeNamespaceQualifiedPasswordTypes(reqData)
294 );
295 wssConfig.setSecretKeyLength(reqData.getSecretKeyLength());
296 wssConfig.setWsiBSPCompliant(decodeBSPCompliance(reqData));
297 reqData.setWssConfig(wssConfig);
298
299 if ((doAction & WSConstants.SIGN) == WSConstants.SIGN) {
300 decodeSignatureParameter2(reqData);
301 }
302
303 if (((doAction & WSConstants.ST_SIGNED) == WSConstants.ST_SIGNED)
304 || ((doAction & WSConstants.ST_UNSIGNED) == WSConstants.ST_UNSIGNED)) {
305 decodeSignatureParameter2(reqData);
306 }
307
308 if ((doAction & WSConstants.ENCR) == WSConstants.ENCR) {
309 decodeDecryptionParameter(reqData);
310 }
311 decodeRequireSignedEncryptedDataElements(reqData);
312 }
313
314 protected boolean checkReceiverResults(
315 List<WSSecurityEngineResult> wsResult, List<Integer> actions
316 ) {
317 int size = actions.size();
318 int ai = 0;
319 for (WSSecurityEngineResult result : wsResult) {
320 final Integer actInt = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
321 int act = actInt.intValue();
322 if (act == WSConstants.SC || act == WSConstants.BST) {
323 continue;
324 }
325
326 if (ai >= size || actions.get(ai++).intValue() != act) {
327 return false;
328 }
329 }
330
331 if (ai != size) {
332 return false;
333 }
334
335 return true;
336 }
337
338 protected boolean checkReceiverResultsAnyOrder(
339 List<WSSecurityEngineResult> wsResult, List<Integer> actions
340 ) {
341 List<Integer> recordedActions = new ArrayList<Integer>(actions.size());
342 for (Integer action : actions) {
343 recordedActions.add(action);
344 }
345
346 for (WSSecurityEngineResult result : wsResult) {
347 final Integer actInt = (Integer) result.get(WSSecurityEngineResult.TAG_ACTION);
348 int act = actInt.intValue();
349 if (act == WSConstants.SC || act == WSConstants.BST) {
350 continue;
351 }
352
353 if (!recordedActions.remove(actInt)) {
354 return false;
355 }
356 }
357
358 if (!recordedActions.isEmpty()) {
359 return false;
360 }
361
362 return true;
363 }
364
365 @SuppressWarnings("unchecked")
366 protected void checkSignatureConfirmation(
367 RequestData reqData,
368 List<WSSecurityEngineResult> resultList
369 ) throws WSSecurityException{
370 if (doDebug) {
371 log.debug("Check Signature confirmation");
372 }
373
374
375
376 List<byte[]> savedSignatures =
377 (List<byte[]>) getProperty(reqData.getMsgContext(), WSHandlerConstants.SEND_SIGV);
378
379
380
381
382
383 List<WSSecurityEngineResult> sigConf = new ArrayList<WSSecurityEngineResult>();
384 WSSecurityUtil.fetchAllActionResults(resultList, WSConstants.SC, sigConf);
385
386
387
388
389
390
391
392 for (WSSecurityEngineResult result : sigConf) {
393 SignatureConfirmation sc =
394 (SignatureConfirmation)result.get(
395 WSSecurityEngineResult.TAG_SIGNATURE_CONFIRMATION
396 );
397
398 byte[] sigVal = sc.getSignatureValue();
399 if (sigVal != null) {
400 if (savedSignatures == null || savedSignatures.size() == 0) {
401
402
403
404
405 if (sigVal.length != 0) {
406 throw new WSSecurityException(
407 "Received a SignatureConfirmation element, but there are no stored"
408 + " signature values"
409 );
410 }
411 } else {
412 boolean found = false;
413 for (int j = 0; j < savedSignatures.size(); j++) {
414 byte[] storedValue = (byte[]) savedSignatures.get(j);
415 if (Arrays.equals(sigVal, storedValue)) {
416 found = true;
417 savedSignatures.remove(j);
418 break;
419 }
420 }
421 if (!found) {
422 throw new WSSecurityException(
423 "Received a SignatureConfirmation element, but there are no matching"
424 + " stored signature values"
425 );
426 }
427 }
428 }
429 }
430
431
432
433
434
435 if (!reqData.isNoSerialization()) {
436 if (doDebug) {
437 log.debug("Check Signature confirmation - last handler");
438 }
439 if (savedSignatures != null && !savedSignatures.isEmpty()) {
440 throw new WSSecurityException(
441 "Check Signature confirmation: the stored signature values list is not empty"
442 );
443 }
444 }
445 }
446
447 protected void decodeUTParameter(RequestData reqData)
448 throws WSSecurityException {
449 Object mc = reqData.getMsgContext();
450
451 String type = getString(WSHandlerConstants.PASSWORD_TYPE, mc);
452 if (type != null) {
453 if (WSConstants.PW_TEXT.equals(type)) {
454 reqData.setPwType(WSConstants.PASSWORD_TEXT);
455 } else if (WSConstants.PW_DIGEST.equals(type)) {
456 reqData.setPwType(WSConstants.PASSWORD_DIGEST);
457 } else if (WSConstants.PW_NONE.equals(type)) {
458 reqData.setPwType(null);
459 } else {
460 throw new WSSecurityException("Unknown password type encoding: " + type);
461 }
462 }
463
464 String add = getString(WSHandlerConstants.ADD_UT_ELEMENTS, mc);
465 if (add != null) {
466 reqData.setUtElements(StringUtil.split(add, ' '));
467 }
468
469 String derived = getString(WSHandlerConstants.USE_DERIVED_KEY, mc);
470 if (derived != null) {
471 boolean useDerivedKey = Boolean.parseBoolean(derived);
472 reqData.setUseDerivedKey(useDerivedKey);
473 }
474
475 String derivedMAC = getString(WSHandlerConstants.USE_DERIVED_KEY_FOR_MAC, mc);
476 boolean useDerivedKeyForMAC = Boolean.parseBoolean(derivedMAC);
477 if (useDerivedKeyForMAC) {
478 reqData.setUseDerivedKeyForMAC(useDerivedKeyForMAC);
479 }
480
481 String iterations = getString(WSHandlerConstants.DERIVED_KEY_ITERATIONS, mc);
482 if (iterations != null) {
483 int iIterations = Integer.parseInt(iterations);
484 reqData.setDerivedKeyIterations(iIterations);
485 }
486 }
487
488 protected void decodeSignatureParameter(RequestData reqData)
489 throws WSSecurityException {
490 Object mc = reqData.getMsgContext();
491 String signatureUser = getString(WSHandlerConstants.SIGNATURE_USER, mc);
492
493 if (signatureUser != null) {
494 reqData.setSignatureUser(signatureUser);
495 } else {
496 reqData.setSignatureUser(reqData.getUsername());
497 }
498
499 String keyId = getString(WSHandlerConstants.SIG_KEY_ID, mc);
500 if (keyId != null) {
501 Integer id = (Integer) WSHandlerConstants.getKeyIdentifier(keyId);
502 if (id == null) {
503 throw new WSSecurityException(
504 "WSHandler: Signature: unknown key identification"
505 );
506 }
507 int tmp = id.intValue();
508 if (!(tmp == WSConstants.ISSUER_SERIAL
509 || tmp == WSConstants.BST_DIRECT_REFERENCE
510 || tmp == WSConstants.X509_KEY_IDENTIFIER
511 || tmp == WSConstants.SKI_KEY_IDENTIFIER
512 || tmp == WSConstants.THUMBPRINT_IDENTIFIER
513 || tmp == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER)) {
514 throw new WSSecurityException(
515 "WSHandler: Signature: illegal key identification"
516 );
517 }
518 reqData.setSigKeyId(tmp);
519 }
520 String algo = getString(WSHandlerConstants.SIG_ALGO, mc);
521 reqData.setSigAlgorithm(algo);
522
523 String digestAlgo = getString(WSHandlerConstants.SIG_DIGEST_ALGO, mc);
524 reqData.setSigDigestAlgorithm(digestAlgo);
525
526 String parts = getString(WSHandlerConstants.SIGNATURE_PARTS, mc);
527 if (parts != null) {
528 splitEncParts(parts, reqData.getSignatureParts(), reqData);
529 }
530
531 String secretKeyLength = getString(WSHandlerConstants.WSE_SECRET_KEY_LENGTH, mc);
532 if (secretKeyLength != null) {
533 int iSecretKeyLength = Integer.parseInt(secretKeyLength);
534 reqData.setSecretKeyLength(iSecretKeyLength);
535 }
536
537 boolean useSingleCert = decodeUseSingleCertificate(reqData);
538 reqData.setUseSingleCert(useSingleCert);
539 }
540
541 protected void decodeAlgorithmSuite(RequestData reqData) throws WSSecurityException {
542 Object mc = reqData.getMsgContext();
543 if (mc == null || reqData.getAlgorithmSuite() != null) {
544 return;
545 }
546
547 AlgorithmSuite algorithmSuite = new AlgorithmSuite();
548
549 String signatureAlgorithm = getString(WSHandlerConstants.SIG_ALGO, mc);
550 if (signatureAlgorithm != null && !"".equals(signatureAlgorithm)) {
551 algorithmSuite.addSignatureMethod(signatureAlgorithm);
552 }
553 String signatureDigestAlgorithm = getString(WSHandlerConstants.SIG_DIGEST_ALGO, mc);
554 if (signatureDigestAlgorithm != null && !"".equals(signatureDigestAlgorithm)) {
555 algorithmSuite.addDigestAlgorithm(signatureDigestAlgorithm);
556 }
557
558 String encrAlgorithm = getString(WSHandlerConstants.ENC_SYM_ALGO, mc);
559 if (encrAlgorithm != null && !"".equals(encrAlgorithm)) {
560 algorithmSuite.addEncryptionMethod(encrAlgorithm);
561 }
562 String transportAlgorithm = getString(WSHandlerConstants.ENC_KEY_TRANSPORT, mc);
563 if (transportAlgorithm != null && !"".equals(transportAlgorithm)) {
564 algorithmSuite.addKeyWrapAlgorithm(transportAlgorithm);
565 }
566
567 reqData.setAlgorithmSuite(algorithmSuite);
568 }
569
570 protected void decodeEncryptionParameter(RequestData reqData)
571 throws WSSecurityException {
572 Object mc = reqData.getMsgContext();
573 String encUser = getString(WSHandlerConstants.ENCRYPTION_USER, mc);
574
575 if (encUser != null) {
576 reqData.setEncUser(encUser);
577 } else {
578 reqData.setEncUser(reqData.getUsername());
579 }
580 if (reqData.getEncUser() == null) {
581 throw new WSSecurityException("WSHandler: Encryption: no username");
582 }
583
584
585
586
587
588 handleSpecialUser(reqData);
589
590
591
592
593
594 String encKeyId = getString(WSHandlerConstants.ENC_KEY_ID, mc);
595 if (encKeyId != null) {
596 Integer id = (Integer) WSHandlerConstants.getKeyIdentifier(encKeyId);
597 if (id == null) {
598 throw new WSSecurityException(
599 "WSHandler: Encryption: unknown key identification"
600 );
601 }
602 int tmp = id.intValue();
603 reqData.setEncKeyId(tmp);
604 if (!(tmp == WSConstants.ISSUER_SERIAL
605 || tmp == WSConstants.X509_KEY_IDENTIFIER
606 || tmp == WSConstants.SKI_KEY_IDENTIFIER
607 || tmp == WSConstants.BST_DIRECT_REFERENCE
608 || tmp == WSConstants.EMBEDDED_KEYNAME
609 || tmp == WSConstants.THUMBPRINT_IDENTIFIER
610 || tmp == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER)) {
611 throw new WSSecurityException(
612 "WSHandler: Encryption: illegal key identification"
613 );
614 }
615 }
616 String encSymAlgo = getString(WSHandlerConstants.ENC_SYM_ALGO, mc);
617 reqData.setEncSymmAlgo(encSymAlgo);
618
619 String encKeyTransport =
620 getString(WSHandlerConstants.ENC_KEY_TRANSPORT, mc);
621 reqData.setEncKeyTransport(encKeyTransport);
622
623 String digestAlgo = getString(WSHandlerConstants.ENC_DIGEST_ALGO, mc);
624 reqData.setEncDigestAlgorithm(digestAlgo);
625
626 String encSymEncKey = getString(WSHandlerConstants.ENC_SYM_ENC_KEY, mc);
627 if (encSymEncKey != null) {
628 boolean encSymEndKeyBoolean = Boolean.parseBoolean(encSymEncKey);
629 reqData.setEncryptSymmetricEncryptionKey(encSymEndKeyBoolean);
630 }
631
632 String encParts = getString(WSHandlerConstants.ENCRYPTION_PARTS, mc);
633 if (encParts != null) {
634 splitEncParts(encParts, reqData.getEncryptParts(), reqData);
635 }
636 }
637
638 public int decodeTimeToLive(RequestData reqData) {
639 String ttl =
640 getString(WSHandlerConstants.TTL_TIMESTAMP, reqData.getMsgContext());
641 int ttlI = 0;
642 if (ttl != null) {
643 try {
644 ttlI = Integer.parseInt(ttl);
645 } catch (NumberFormatException e) {
646 ttlI = reqData.getTimeToLive();
647 }
648 }
649 if (ttlI <= 0) {
650 ttlI = reqData.getTimeToLive();
651 }
652 return ttlI;
653 }
654
655 protected int decodeFutureTimeToLive(RequestData reqData) {
656 String ttl =
657 getString(WSHandlerConstants.TTL_FUTURE_TIMESTAMP, reqData.getMsgContext());
658 int defaultFutureTimeToLive = 60;
659 if (ttl != null) {
660 try {
661 int ttlI = Integer.parseInt(ttl);
662 if (ttlI < 0) {
663 return defaultFutureTimeToLive;
664 }
665 return ttlI;
666 } catch (NumberFormatException e) {
667 return defaultFutureTimeToLive;
668 }
669 }
670 return defaultFutureTimeToLive;
671 }
672
673 protected boolean decodeBSPCompliance(RequestData reqData)
674 throws WSSecurityException {
675 return decodeBooleanConfigValue(
676 reqData, WSHandlerConstants.IS_BSP_COMPLIANT, true
677 );
678 }
679
680 protected String decodePasswordType(RequestData reqData) throws WSSecurityException {
681 String type = getString(WSHandlerConstants.PASSWORD_TYPE, reqData.getMsgContext());
682 if (type != null) {
683 if (WSConstants.PW_TEXT.equals(type)) {
684 return WSConstants.PASSWORD_TEXT;
685 } else if (WSConstants.PW_DIGEST.equals(type)) {
686 return WSConstants.PASSWORD_DIGEST;
687 }
688 }
689 return null;
690 }
691
692 protected boolean decodeMustUnderstand(RequestData reqData)
693 throws WSSecurityException {
694 return decodeBooleanConfigValue(
695 reqData, WSHandlerConstants.MUST_UNDERSTAND, true
696 );
697 }
698
699 protected boolean decodeEnableSignatureConfirmation(
700 RequestData reqData
701 ) throws WSSecurityException {
702 return decodeBooleanConfigValue(
703 reqData, WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, false
704 );
705 }
706
707 protected boolean decodeTimestampPrecision(
708 RequestData reqData
709 ) throws WSSecurityException {
710 return decodeBooleanConfigValue(
711 reqData, WSHandlerConstants.TIMESTAMP_PRECISION, true
712 );
713 }
714
715 protected boolean decodeCustomPasswordTypes(
716 RequestData reqData
717 ) throws WSSecurityException {
718 return decodeBooleanConfigValue(
719 reqData, WSHandlerConstants.HANDLE_CUSTOM_PASSWORD_TYPES, false
720 );
721 }
722
723 protected boolean decodeUseEncodedPasswords(RequestData reqData)
724 throws WSSecurityException {
725 return decodeBooleanConfigValue(
726 reqData, WSHandlerConstants.USE_ENCODED_PASSWORDS, false
727 );
728 }
729
730 protected boolean decodeNamespaceQualifiedPasswordTypes(RequestData reqData)
731 throws WSSecurityException {
732 return decodeBooleanConfigValue(
733 reqData, WSHandlerConstants.ALLOW_NAMESPACE_QUALIFIED_PASSWORD_TYPES, false
734 );
735 }
736
737 protected boolean decodeTimestampStrict(RequestData reqData)
738 throws WSSecurityException {
739 return decodeBooleanConfigValue(
740 reqData, WSHandlerConstants.TIMESTAMP_STRICT, true
741 );
742 }
743
744 protected boolean decodePasswordTypeStrict(RequestData reqData)
745 throws WSSecurityException {
746 return decodeBooleanConfigValue(
747 reqData, WSHandlerConstants.PASSWORD_TYPE_STRICT, false
748 );
749 }
750
751 protected boolean decodeUseSingleCertificate(RequestData reqData)
752 throws WSSecurityException {
753 return decodeBooleanConfigValue(
754 reqData, WSHandlerConstants.USE_SINGLE_CERTIFICATE, true
755 );
756 }
757
758 protected void decodeRequireSignedEncryptedDataElements(RequestData reqData)
759 throws WSSecurityException {
760 reqData.setRequireSignedEncryptedDataElements(decodeBooleanConfigValue(
761 reqData, WSHandlerConstants.REQUIRE_SIGNED_ENCRYPTED_DATA_ELEMENTS, false
762 ));
763 }
764
765 protected boolean decodeBooleanConfigValue(
766 RequestData reqData, String configTag, boolean defaultToTrue
767 ) throws WSSecurityException {
768
769 String value = getString(configTag, reqData.getMsgContext());
770
771 if (value == null) {
772 return defaultToTrue;
773 }
774 if ("0".equals(value) || "false".equals(value)) {
775 return false;
776 }
777 if ("1".equals(value) || "true".equals(value)) {
778 return true;
779 }
780
781 throw new WSSecurityException(
782 "WSHandler: illegal " + configTag + " parameter"
783 );
784 }
785
786
787
788
789
790
791
792
793 public Crypto loadSignatureCrypto(RequestData requestData) throws WSSecurityException {
794 return
795 loadCrypto(
796 WSHandlerConstants.SIG_PROP_FILE,
797 WSHandlerConstants.SIG_PROP_REF_ID,
798 requestData
799 );
800 }
801
802
803
804
805
806
807
808
809 protected Crypto loadDecryptionCrypto(RequestData requestData) throws WSSecurityException {
810 return
811 loadCrypto(
812 WSHandlerConstants.DEC_PROP_FILE,
813 WSHandlerConstants.DEC_PROP_REF_ID,
814 requestData
815 );
816 }
817
818
819
820
821
822
823
824
825 protected Crypto loadEncryptionCrypto(RequestData requestData) throws WSSecurityException {
826 return
827 loadCrypto(
828 WSHandlerConstants.ENC_PROP_FILE,
829 WSHandlerConstants.ENC_PROP_REF_ID,
830 requestData
831 );
832 }
833
834
835
836
837
838
839
840
841
842 protected Crypto loadCrypto(
843 String cryptoPropertyFile,
844 String cryptoPropertyRefId,
845 RequestData requestData
846 ) throws WSSecurityException {
847 Object mc = requestData.getMsgContext();
848 Crypto crypto = null;
849
850
851
852
853 String refId = getString(cryptoPropertyRefId, mc);
854 if (refId != null) {
855 crypto = cryptos.get(refId);
856 if (crypto == null) {
857 Object obj = getProperty(mc, refId);
858 if (obj instanceof Properties) {
859 crypto = CryptoFactory.getInstance((Properties)obj);
860 cryptos.put(refId, crypto);
861 } else if (obj instanceof Crypto) {
862 crypto = (Crypto)obj;
863 cryptos.put(refId, crypto);
864 }
865 }
866 }
867
868
869
870
871 if (crypto == null) {
872 String propFile = getString(cryptoPropertyFile, mc);
873 if (propFile != null) {
874 crypto = cryptos.get(propFile);
875 if (crypto == null) {
876 crypto = loadCryptoFromPropertiesFile(propFile, requestData);
877 cryptos.put(propFile, crypto);
878 }
879 }
880 }
881 return crypto;
882 }
883
884
885
886
887
888
889
890
891 protected Crypto loadCryptoFromPropertiesFile(
892 String propFilename,
893 RequestData reqData
894 ) throws WSSecurityException {
895 return
896 CryptoFactory.getInstance(
897 propFilename, this.getClassLoader(reqData.getMsgContext())
898 );
899 }
900
901
902
903
904
905
906
907
908
909
910
911
912 public CallbackHandler getCallbackHandler(
913 String callbackHandlerClass,
914 String callbackHandlerRef,
915 RequestData requestData
916 ) throws WSSecurityException {
917 Object mc = requestData.getMsgContext();
918 CallbackHandler cbHandler = (CallbackHandler) getOption(callbackHandlerRef);
919 if (cbHandler == null) {
920 cbHandler = (CallbackHandler) getProperty(mc, callbackHandlerRef);
921 }
922 if (cbHandler == null) {
923 String callback = getString(callbackHandlerClass, mc);
924 if (callback != null) {
925 cbHandler = loadCallbackHandler(callback, requestData);
926 }
927 }
928 return cbHandler;
929 }
930
931
932
933
934
935
936
937 public CallbackHandler getPasswordCallbackHandler(RequestData reqData)
938 throws WSSecurityException {
939 return
940 getCallbackHandler(
941 WSHandlerConstants.PW_CALLBACK_CLASS,
942 WSHandlerConstants.PW_CALLBACK_REF,
943 reqData
944 );
945 }
946
947
948
949
950
951
952
953
954 private CallbackHandler loadCallbackHandler(
955 String callbackHandlerClass,
956 RequestData requestData
957 ) throws WSSecurityException {
958
959 Class<? extends CallbackHandler> cbClass = null;
960 CallbackHandler cbHandler = null;
961 try {
962 cbClass =
963 Loader.loadClass(getClassLoader(requestData.getMsgContext()),
964 callbackHandlerClass,
965 CallbackHandler.class);
966 } catch (ClassNotFoundException e) {
967 throw new WSSecurityException(
968 "WSHandler: cannot load callback handler class: " + callbackHandlerClass, e
969 );
970 }
971 try {
972 cbHandler = (CallbackHandler) cbClass.newInstance();
973 } catch (Exception e) {
974 throw new WSSecurityException(
975 "WSHandler: cannot create instance of callback handler: " + callbackHandlerClass, e
976 );
977 }
978 return cbHandler;
979 }
980
981
982
983
984
985
986
987
988
989
990 public WSPasswordCallback getPasswordCB(
991 String username,
992 int doAction,
993 CallbackHandler callbackHandler,
994 RequestData requestData
995 ) throws WSSecurityException {
996
997 if (callbackHandler != null) {
998 return performPasswordCallback(callbackHandler, username, doAction);
999 } else {
1000
1001
1002
1003
1004 String password = getPassword(requestData.getMsgContext());
1005 if (password == null) {
1006 String err = "provided null or empty password";
1007 throw new WSSecurityException("WSHandler: application " + err);
1008 }
1009 WSPasswordCallback pwCb = constructPasswordCallback(username, doAction);
1010 pwCb.setPassword(password);
1011 return pwCb;
1012 }
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 private WSPasswordCallback performPasswordCallback(
1024 CallbackHandler cbHandler,
1025 String username,
1026 int doAction
1027 ) throws WSSecurityException {
1028
1029 WSPasswordCallback pwCb = constructPasswordCallback(username, doAction);
1030 Callback[] callbacks = new Callback[1];
1031 callbacks[0] = pwCb;
1032
1033
1034
1035 try {
1036 cbHandler.handle(callbacks);
1037 } catch (Exception e) {
1038 throw new WSSecurityException("WSHandler: password callback failed", e);
1039 }
1040 return pwCb;
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050 private WSPasswordCallback constructPasswordCallback(
1051 String username,
1052 int doAction
1053 ) throws WSSecurityException {
1054
1055 int reason = WSPasswordCallback.UNKNOWN;
1056
1057 switch (doAction) {
1058 case WSConstants.UT:
1059 case WSConstants.UT_SIGN:
1060 reason = WSPasswordCallback.USERNAME_TOKEN;
1061 break;
1062 case WSConstants.SIGN:
1063 reason = WSPasswordCallback.SIGNATURE;
1064 break;
1065 case WSConstants.ENCR:
1066 reason = WSPasswordCallback.SECRET_KEY;
1067 break;
1068 }
1069 return new WSPasswordCallback(username, reason);
1070 }
1071
1072 private void splitEncParts(String tmpS, List<WSEncryptionPart> parts, RequestData reqData)
1073 throws WSSecurityException {
1074 WSEncryptionPart encPart = null;
1075 String[] rawParts = StringUtil.split(tmpS, ';');
1076
1077 for (int i = 0; i < rawParts.length; i++) {
1078 String[] partDef = StringUtil.split(rawParts[i], '}');
1079
1080 if (partDef.length == 1) {
1081 if (doDebug) {
1082 log.debug("single partDef: '" + partDef[0] + "'");
1083 }
1084 encPart =
1085 new WSEncryptionPart(partDef[0].trim(),
1086 reqData.getSoapConstants().getEnvelopeURI(),
1087 "Content");
1088 } else if (partDef.length == 3) {
1089 String mode = partDef[0].trim();
1090 if (mode.length() <= 1) {
1091 mode = "Content";
1092 } else {
1093 mode = mode.substring(1);
1094 }
1095 String nmSpace = partDef[1].trim();
1096 if (nmSpace.length() <= 1) {
1097 nmSpace = reqData.getSoapConstants().getEnvelopeURI();
1098 } else {
1099 nmSpace = nmSpace.substring(1);
1100 if (nmSpace.equals(WSConstants.NULL_NS)) {
1101 nmSpace = null;
1102 }
1103 }
1104 String element = partDef[2].trim();
1105 if (doDebug) {
1106 log.debug(
1107 "partDefs: '" + mode + "' ,'" + nmSpace + "' ,'" + element + "'"
1108 );
1109 }
1110 encPart = new WSEncryptionPart(element, nmSpace, mode);
1111 } else {
1112 throw new WSSecurityException("WSHandler: wrong part definition: " + tmpS);
1113 }
1114 parts.add(encPart);
1115 }
1116 }
1117
1118 @SuppressWarnings("unchecked")
1119 private void handleSpecialUser(RequestData reqData) {
1120 if (!WSHandlerConstants.USE_REQ_SIG_CERT.equals(reqData.getEncUser())) {
1121 return;
1122 }
1123 List<WSHandlerResult> results =
1124 (List<WSHandlerResult>) getProperty(
1125 reqData.getMsgContext(), WSHandlerConstants.RECV_RESULTS
1126 );
1127 if (results == null) {
1128 return;
1129 }
1130
1131
1132
1133
1134 for (WSHandlerResult rResult : results) {
1135 String hActor = rResult.getActor();
1136 if (!WSSecurityUtil.isActorEqual(reqData.getActor(), hActor)) {
1137 continue;
1138 }
1139 List<WSSecurityEngineResult> wsSecEngineResults = rResult.getResults();
1140
1141
1142
1143
1144
1145 for (WSSecurityEngineResult wser : wsSecEngineResults) {
1146 int wserAction =
1147 ((java.lang.Integer)wser.get(WSSecurityEngineResult.TAG_ACTION)).intValue();
1148 if (wserAction == WSConstants.SIGN) {
1149 X509Certificate cert =
1150 (X509Certificate)wser.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);
1151 reqData.setEncCert(cert);
1152 return;
1153 }
1154 }
1155 }
1156 }
1157
1158 protected void decodeSignatureParameter2(RequestData reqData)
1159 throws WSSecurityException {
1160 if (reqData.getSigCrypto() == null) {
1161 reqData.setSigCrypto(loadSignatureCrypto(reqData));
1162 }
1163 boolean enableRevocation =
1164 decodeBooleanConfigValue(
1165 reqData, WSHandlerConstants.ENABLE_REVOCATION, false
1166 );
1167 reqData.setEnableRevocation(enableRevocation);
1168
1169 String certConstraints =
1170 getString(WSHandlerConstants.SIG_SUBJECT_CERT_CONSTRAINTS, reqData.getMsgContext());
1171 if (certConstraints != null) {
1172 String[] certConstraintsList = certConstraints.split(",");
1173 if (certConstraintsList != null) {
1174 Collection<Pattern> subjectCertConstraints =
1175 new ArrayList<Pattern>(certConstraintsList.length);
1176 for (String certConstraint : certConstraintsList) {
1177 try {
1178 subjectCertConstraints.add(Pattern.compile(certConstraint.trim()));
1179 } catch (PatternSyntaxException ex) {
1180 log.debug(ex.getMessage(), ex);
1181 throw new WSSecurityException(ex.getMessage(), ex);
1182 }
1183 }
1184 reqData.setSubjectCertConstraints(subjectCertConstraints);
1185 }
1186 }
1187 }
1188
1189
1190
1191
1192
1193 protected void decodeDecryptionParameter(RequestData reqData)
1194 throws WSSecurityException {
1195 if (reqData.getDecCrypto() == null) {
1196 reqData.setDecCrypto(loadDecryptionCrypto(reqData));
1197 }
1198 }
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209 public String getString(String key, Object mc) {
1210 if (key == null) {
1211 throw new IllegalArgumentException("Key cannot be null");
1212 }
1213 String s = getStringOption(key);
1214 if (s != null) {
1215 return s;
1216 }
1217 if (mc == null) {
1218 throw new IllegalArgumentException("Message context cannot be null");
1219 }
1220 return (String) getProperty(mc, key);
1221 }
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231 public String getStringOption(String key) {
1232 Object o = getOption(key);
1233 if (o instanceof String){
1234 return (String) o;
1235 } else {
1236 return null;
1237 }
1238 }
1239
1240
1241
1242
1243
1244
1245 public ClassLoader getClassLoader(Object msgCtx) {
1246 try {
1247 return Loader.getTCL();
1248 } catch (Exception ex) {
1249 return null;
1250 }
1251 }
1252
1253 public abstract Object getOption(String key);
1254 public abstract Object getProperty(Object msgContext, String key);
1255
1256 public abstract void setProperty(Object msgContext, String key,
1257 Object value);
1258
1259
1260 public abstract String getPassword(Object msgContext);
1261
1262 public abstract void setPassword(Object msgContext, String password);
1263 }