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.processor;
21
22 import java.security.Key;
23 import java.security.NoSuchProviderException;
24 import java.security.Principal;
25 import java.security.PublicKey;
26 import java.security.cert.X509Certificate;
27 import java.security.spec.AlgorithmParameterSpec;
28 import java.text.DateFormat;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import javax.xml.crypto.MarshalException;
37 import javax.xml.crypto.NodeSetData;
38 import javax.xml.crypto.XMLStructure;
39 import javax.xml.crypto.dom.DOMStructure;
40 import javax.xml.crypto.dsig.Manifest;
41 import javax.xml.crypto.dsig.Reference;
42 import javax.xml.crypto.dsig.SignedInfo;
43 import javax.xml.crypto.dsig.Transform;
44 import javax.xml.crypto.dsig.XMLObject;
45 import javax.xml.crypto.dsig.XMLSignature;
46 import javax.xml.crypto.dsig.XMLSignatureFactory;
47 import javax.xml.crypto.dsig.XMLValidateContext;
48 import javax.xml.crypto.dsig.dom.DOMValidateContext;
49 import javax.xml.crypto.dsig.keyinfo.KeyInfo;
50 import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
51 import javax.xml.crypto.dsig.keyinfo.KeyValue;
52 import javax.xml.crypto.dsig.spec.HMACParameterSpec;
53
54 import org.apache.ws.security.PublicKeyPrincipal;
55 import org.apache.ws.security.WSConstants;
56 import org.apache.ws.security.WSDataRef;
57 import org.apache.ws.security.WSDerivedKeyTokenPrincipal;
58 import org.apache.ws.security.WSDocInfo;
59 import org.apache.ws.security.WSSConfig;
60 import org.apache.ws.security.WSSecurityEngine;
61 import org.apache.ws.security.WSSecurityEngineResult;
62 import org.apache.ws.security.WSSecurityException;
63 import org.apache.ws.security.WSUsernameTokenPrincipal;
64 import org.apache.ws.security.cache.ReplayCache;
65 import org.apache.ws.security.components.crypto.AlgorithmSuite;
66 import org.apache.ws.security.components.crypto.AlgorithmSuiteValidator;
67 import org.apache.ws.security.components.crypto.Crypto;
68 import org.apache.ws.security.components.crypto.CryptoType;
69 import org.apache.ws.security.handler.RequestData;
70 import org.apache.ws.security.message.CallbackLookup;
71 import org.apache.ws.security.message.DOMCallbackLookup;
72 import org.apache.ws.security.message.token.SecurityTokenReference;
73 import org.apache.ws.security.message.token.Timestamp;
74 import org.apache.ws.security.str.STRParser;
75 import org.apache.ws.security.str.STRParser.REFERENCE_TYPE;
76 import org.apache.ws.security.str.SignatureSTRParser;
77 import org.apache.ws.security.transform.STRTransform;
78 import org.apache.ws.security.transform.STRTransformUtil;
79 import org.apache.ws.security.util.WSSecurityUtil;
80 import org.apache.ws.security.util.XmlSchemaDateFormat;
81 import org.apache.ws.security.validate.Credential;
82 import org.apache.ws.security.validate.Validator;
83 import org.w3c.dom.Document;
84 import org.w3c.dom.Element;
85 import org.w3c.dom.Node;
86
87 public class SignatureProcessor implements Processor {
88 private static final org.apache.commons.logging.Log LOG =
89 org.apache.commons.logging.LogFactory.getLog(SignatureProcessor.class);
90
91 private XMLSignatureFactory signatureFactory;
92 private KeyInfoFactory keyInfoFactory;
93
94 public SignatureProcessor() {
95
96
97 try {
98 signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
99 } catch (NoSuchProviderException ex) {
100 signatureFactory = XMLSignatureFactory.getInstance("DOM");
101 }
102 try {
103 keyInfoFactory = KeyInfoFactory.getInstance("DOM", "ApacheXMLDSig");
104 } catch (NoSuchProviderException ex) {
105 keyInfoFactory = KeyInfoFactory.getInstance("DOM");
106 }
107 }
108
109 public List<WSSecurityEngineResult> handleToken(
110 Element elem,
111 RequestData data,
112 WSDocInfo wsDocInfo
113 ) throws WSSecurityException {
114 if (LOG.isDebugEnabled()) {
115 LOG.debug("Found signature element");
116 }
117 Element keyInfoElement =
118 WSSecurityUtil.getDirectChildElement(
119 elem,
120 "KeyInfo",
121 WSConstants.SIG_NS
122 );
123 X509Certificate[] certs = null;
124 Principal principal = null;
125 PublicKey publicKey = null;
126 byte[] secretKey = null;
127 String signatureMethod = getSignatureMethod(elem);
128 REFERENCE_TYPE referenceType = null;
129
130 Validator validator = data.getValidator(WSSecurityEngine.SIGNATURE);
131 if (keyInfoElement == null) {
132 certs = getDefaultCerts(data.getSigCrypto());
133 principal = certs[0].getSubjectX500Principal();
134 } else {
135 List<Element> strElements =
136 WSSecurityUtil.getDirectChildElements(
137 keyInfoElement,
138 SecurityTokenReference.SECURITY_TOKEN_REFERENCE,
139 WSConstants.WSSE_NS
140 );
141 if (data.getWssConfig().isWsiBSPCompliant()) {
142 if (strElements.isEmpty()) {
143 throw new WSSecurityException(
144 WSSecurityException.INVALID_SECURITY, "noSecurityTokenReference"
145 );
146 } else if (strElements.size() > 1) {
147 throw new WSSecurityException(
148 WSSecurityException.INVALID_SECURITY, "badSecurityTokenReference"
149 );
150 }
151 }
152
153 if (strElements.isEmpty()) {
154 publicKey = parseKeyValue(keyInfoElement);
155 if (validator != null) {
156 Credential credential = new Credential();
157 credential.setPublicKey(publicKey);
158 principal = new PublicKeyPrincipal(publicKey);
159 credential.setPrincipal(principal);
160 validator.validate(credential, data);
161 }
162 } else {
163 STRParser strParser = new SignatureSTRParser();
164 Map<String, Object> parameters = new HashMap<String, Object>();
165 parameters.put(SignatureSTRParser.SIGNATURE_METHOD, signatureMethod);
166 parameters.put(
167 SignatureSTRParser.SECRET_KEY_LENGTH, Integer.valueOf(data.getWssConfig().getSecretKeyLength())
168 );
169 strParser.parseSecurityTokenReference(
170 strElements.get(0), data, wsDocInfo, parameters
171 );
172 principal = strParser.getPrincipal();
173 certs = strParser.getCertificates();
174 publicKey = strParser.getPublicKey();
175 secretKey = strParser.getSecretKey();
176 referenceType = strParser.getCertificatesReferenceType();
177
178 boolean trusted = strParser.isTrustedCredential();
179 if (trusted && LOG.isDebugEnabled()) {
180 LOG.debug("Direct Trust for SAML/BST credential");
181 }
182 if (!trusted && (publicKey != null || certs != null) && (validator != null)) {
183 Credential credential = new Credential();
184 credential.setPublicKey(publicKey);
185 credential.setCertificates(certs);
186 credential.setPrincipal(principal);
187 validator.validate(credential, data);
188 }
189 }
190 }
191
192
193
194
195
196 if ((certs == null || certs.length == 0 || certs[0] == null)
197 && secretKey == null
198 && publicKey == null) {
199 throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
200 }
201
202
203 AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
204 if (algorithmSuite != null) {
205 AlgorithmSuiteValidator algorithmSuiteValidator = new
206 AlgorithmSuiteValidator(algorithmSuite);
207
208 if (principal instanceof WSDerivedKeyTokenPrincipal) {
209 algorithmSuiteValidator.checkDerivedKeyAlgorithm(
210 ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
211 );
212 algorithmSuiteValidator.checkSignatureDerivedKeyLength(
213 ((WSDerivedKeyTokenPrincipal)principal).getLength()
214 );
215 } else {
216 Key key = null;
217 if (certs != null && certs[0] != null) {
218 key = certs[0].getPublicKey();
219 } else if (publicKey != null) {
220 key = publicKey;
221 }
222
223 if (key instanceof PublicKey) {
224 algorithmSuiteValidator.checkAsymmetricKeyLength((PublicKey)key);
225 } else {
226 algorithmSuiteValidator.checkSymmetricKeyLength(secretKey.length);
227 }
228 }
229 }
230
231 XMLSignature xmlSignature =
232 verifyXMLSignature(elem, certs, publicKey, secretKey, signatureMethod, data, wsDocInfo);
233 byte[] signatureValue = xmlSignature.getSignatureValue().getValue();
234 String c14nMethod = xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
235
236 List<WSDataRef> dataRefs =
237 buildProtectedRefs(
238 elem.getOwnerDocument(), xmlSignature.getSignedInfo(), data.getWssConfig(), wsDocInfo
239 );
240 if (dataRefs.size() == 0) {
241 throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
242 }
243
244 int actionPerformed = WSConstants.SIGN;
245 if (principal instanceof WSUsernameTokenPrincipal) {
246 actionPerformed = WSConstants.UT_SIGN;
247 }
248
249 WSSecurityEngineResult result = new WSSecurityEngineResult(
250 actionPerformed, principal,
251 certs, dataRefs, signatureValue);
252 result.put(WSSecurityEngineResult.TAG_SIGNATURE_METHOD, signatureMethod);
253 result.put(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD, c14nMethod);
254 result.put(WSSecurityEngineResult.TAG_ID, elem.getAttribute("Id"));
255 result.put(WSSecurityEngineResult.TAG_SECRET, secretKey);
256 result.put(WSSecurityEngineResult.TAG_PUBLIC_KEY, publicKey);
257 result.put(WSSecurityEngineResult.TAG_X509_REFERENCE_TYPE, referenceType);
258 if (validator != null) {
259 result.put(WSSecurityEngineResult.TAG_VALIDATED_TOKEN, Boolean.TRUE);
260 }
261 wsDocInfo.addResult(result);
262 wsDocInfo.addTokenElement(elem);
263 return java.util.Collections.singletonList(result);
264 }
265
266
267
268
269
270
271
272 private X509Certificate[] getDefaultCerts(
273 Crypto crypto
274 ) throws WSSecurityException {
275 if (crypto == null) {
276 throw new WSSecurityException(WSSecurityException.FAILURE, "noSigCryptoFile");
277 }
278 if (crypto.getDefaultX509Identifier() != null) {
279 CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
280 cryptoType.setAlias(crypto.getDefaultX509Identifier());
281 return crypto.getX509Certificates(cryptoType);
282 } else {
283 throw new WSSecurityException(
284 WSSecurityException.INVALID_SECURITY, "unsupportedKeyInfo"
285 );
286 }
287 }
288
289 private PublicKey parseKeyValue(
290 Element keyInfoElement
291 ) throws WSSecurityException {
292 KeyValue keyValue = null;
293 try {
294
295
296
297 keyValue = getKeyValue(keyInfoElement);
298 } catch (javax.xml.crypto.MarshalException ex) {
299 throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, ex);
300 }
301
302 if (keyValue != null) {
303 try {
304
305
306
307 return keyValue.getPublicKey();
308 } catch (java.security.KeyException ex) {
309 LOG.error(ex.getMessage(), ex);
310 throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, ex);
311 }
312 } else {
313 throw new WSSecurityException(
314 WSSecurityException.INVALID_SECURITY, "unsupportedKeyInfo"
315 );
316 }
317 }
318
319
320
321
322 private KeyValue getKeyValue(
323 Element keyInfoElement
324 ) throws MarshalException {
325 XMLStructure keyInfoStructure = new DOMStructure(keyInfoElement);
326 KeyInfo keyInfo = keyInfoFactory.unmarshalKeyInfo(keyInfoStructure);
327 List<?> list = keyInfo.getContent();
328
329 for (int i = 0; i < list.size(); i++) {
330 XMLStructure xmlStructure = (XMLStructure) list.get(i);
331 if (xmlStructure instanceof KeyValue) {
332 return (KeyValue)xmlStructure;
333 }
334 }
335 return null;
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370 private XMLSignature verifyXMLSignature(
371 Element elem,
372 X509Certificate[] certs,
373 PublicKey publicKey,
374 byte[] secretKey,
375 String signatureMethod,
376 RequestData data,
377 WSDocInfo wsDocInfo
378 ) throws WSSecurityException {
379 if (LOG.isDebugEnabled()) {
380 LOG.debug("Verify XML Signature");
381 }
382
383
384
385
386
387 Key key = null;
388 if (certs != null && certs[0] != null) {
389 key = certs[0].getPublicKey();
390 } else if (publicKey != null) {
391 key = publicKey;
392 } else {
393 key = WSSecurityUtil.prepareSecretKey(signatureMethod, secretKey);
394 }
395
396 XMLValidateContext context = new DOMValidateContext(key, elem);
397 context.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
398 context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
399 context.setProperty(STRTransform.TRANSFORM_WS_DOC_INFO, wsDocInfo);
400
401 try {
402 XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
403 if (data.getWssConfig().isWsiBSPCompliant()) {
404 checkBSPCompliance(xmlSignature);
405 }
406
407
408 AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
409 if (algorithmSuite != null) {
410 AlgorithmSuiteValidator algorithmSuiteValidator = new
411 AlgorithmSuiteValidator(algorithmSuite);
412 algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
413 }
414
415
416 testMessageReplay(elem, xmlSignature.getSignatureValue().getValue(), data, wsDocInfo);
417
418 setElementsOnContext(xmlSignature, (DOMValidateContext)context, wsDocInfo, elem.getOwnerDocument());
419 boolean signatureOk = xmlSignature.validate(context);
420 if (signatureOk) {
421 return xmlSignature;
422 }
423
424
425
426 if (LOG.isDebugEnabled()) {
427 LOG.debug("XML Signature verification has failed");
428 boolean signatureValidationCheck =
429 xmlSignature.getSignatureValue().validate(context);
430 LOG.debug("Signature Validation check: " + signatureValidationCheck);
431 java.util.Iterator<?> referenceIterator =
432 xmlSignature.getSignedInfo().getReferences().iterator();
433 while (referenceIterator.hasNext()) {
434 Reference reference = (Reference)referenceIterator.next();
435 boolean referenceValidationCheck = reference.validate(context);
436 String id = reference.getId();
437 if (id == null) {
438 id = reference.getURI();
439 }
440 LOG.debug("Reference " + id + " check: " + referenceValidationCheck);
441 }
442 }
443 } catch (WSSecurityException ex) {
444 throw ex;
445 } catch (Exception ex) {
446 throw new WSSecurityException(
447 WSSecurityException.FAILED_CHECK, null, null, ex
448 );
449 }
450 throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
451 }
452
453
454
455
456
457
458
459
460
461 private void setElementsOnContext(
462 XMLSignature xmlSignature,
463 DOMValidateContext context,
464 WSDocInfo wsDocInfo,
465 Document doc
466 ) throws WSSecurityException {
467 java.util.Iterator<?> referenceIterator =
468 xmlSignature.getSignedInfo().getReferences().iterator();
469 CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
470 if (callbackLookup == null) {
471 callbackLookup = new DOMCallbackLookup(doc);
472 }
473 while (referenceIterator.hasNext()) {
474 Reference reference = (Reference)referenceIterator.next();
475 String uri = reference.getURI();
476 Element element = callbackLookup.getElement(uri, null, true);
477 if (element == null) {
478 element = wsDocInfo.getTokenElement(uri);
479 }
480 if (element != null) {
481 WSSecurityUtil.storeElementInContext(((DOMValidateContext)context), uri, element);
482 }
483 }
484 }
485
486
487
488
489
490
491 private static String getSignatureMethod(
492 Element signatureElement
493 ) {
494 Element signedInfoElement =
495 WSSecurityUtil.getDirectChildElement(
496 signatureElement,
497 "SignedInfo",
498 WSConstants.SIG_NS
499 );
500 if (signedInfoElement != null) {
501 Element signatureMethodElement =
502 WSSecurityUtil.getDirectChildElement(
503 signedInfoElement,
504 "SignatureMethod",
505 WSConstants.SIG_NS
506 );
507 if (signatureMethodElement != null) {
508 return signatureMethodElement.getAttributeNS(null, "Algorithm");
509 }
510 }
511 return null;
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525
526 private List<WSDataRef> buildProtectedRefs(
527 Document doc,
528 SignedInfo signedInfo,
529 WSSConfig wssConfig,
530 WSDocInfo wsDocInfo
531 ) throws WSSecurityException {
532 List<WSDataRef> protectedRefs = new java.util.ArrayList<WSDataRef>();
533 List<?> referencesList = signedInfo.getReferences();
534 for (int i = 0; i < referencesList.size(); i++) {
535 Reference siRef = (Reference)referencesList.get(i);
536 String uri = siRef.getURI();
537
538 if (!"".equals(uri)) {
539 Element se = dereferenceSTR(doc, siRef, wssConfig, wsDocInfo);
540
541 if (se == null) {
542 NodeSetData data = (NodeSetData)siRef.getDereferencedData();
543 if (data != null) {
544 java.util.Iterator<?> iter = data.iterator();
545
546 while (iter.hasNext()) {
547 Node n = (Node)iter.next();
548 if (n instanceof Element) {
549 se = (Element)n;
550 break;
551 }
552 }
553 }
554 }
555 if (se == null) {
556 throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
557 }
558
559 WSDataRef ref = new WSDataRef();
560 ref.setWsuId(uri);
561 ref.setProtectedElement(se);
562 ref.setAlgorithm(signedInfo.getSignatureMethod().getAlgorithm());
563 ref.setDigestAlgorithm(siRef.getDigestMethod().getAlgorithm());
564
565
566 @SuppressWarnings("unchecked")
567 List<Transform> transforms = (List<Transform>)siRef.getTransforms();
568 List<String> transformAlgorithms = new ArrayList<String>(transforms.size());
569 for (Transform transform : transforms) {
570 transformAlgorithms.add(transform.getAlgorithm());
571 }
572 ref.setTransformAlgorithms(transformAlgorithms);
573
574 ref.setXpath(ReferenceListProcessor.getXPath(se));
575 protectedRefs.add(ref);
576 }
577 }
578 return protectedRefs;
579 }
580
581
582
583
584
585 private Element dereferenceSTR(
586 Document doc,
587 Reference siRef,
588 WSSConfig wssConfig,
589 WSDocInfo wsDocInfo
590 ) throws WSSecurityException {
591 List<?> transformsList = siRef.getTransforms();
592
593 for (int j = 0; j < transformsList.size(); j++) {
594
595 Transform transform = (Transform)transformsList.get(j);
596
597 if (STRTransform.TRANSFORM_URI.equals(transform.getAlgorithm())) {
598 NodeSetData data = (NodeSetData)siRef.getDereferencedData();
599 if (data != null) {
600 java.util.Iterator<?> iter = data.iterator();
601
602 Node securityTokenReference = null;
603 while (iter.hasNext()) {
604 Node node = (Node)iter.next();
605 if ("SecurityTokenReference".equals(node.getLocalName())) {
606 securityTokenReference = node;
607 break;
608 }
609 }
610
611 if (securityTokenReference != null) {
612 SecurityTokenReference secTokenRef =
613 new SecurityTokenReference(
614 (Element)securityTokenReference,
615 wssConfig.isWsiBSPCompliant()
616 );
617 Element se = STRTransformUtil.dereferenceSTR(doc, secTokenRef, wsDocInfo);
618 if (se != null) {
619 return se;
620 }
621 }
622 }
623 }
624 }
625 return null;
626 }
627
628
629
630
631
632
633
634
635
636 private void testMessageReplay(
637 Element signatureElement,
638 byte[] signatureValue,
639 RequestData requestData,
640 WSDocInfo wsDocInfo
641 ) throws WSSecurityException {
642 ReplayCache replayCache = requestData.getTimestampReplayCache();
643 if (replayCache == null) {
644 return;
645 }
646
647
648 List<WSSecurityEngineResult> foundResults = wsDocInfo.getResultsByTag(WSConstants.TS);
649 Timestamp timeStamp = null;
650 if (foundResults.isEmpty()) {
651
652 Node sibling = signatureElement.getNextSibling();
653 while (sibling != null) {
654 if (sibling instanceof Element
655 && WSConstants.TIMESTAMP_TOKEN_LN.equals(((Element)sibling).getLocalName())
656 && WSConstants.WSU_NS.equals(((Element)sibling).getNamespaceURI())) {
657 timeStamp = new Timestamp((Element)sibling, requestData.getWssConfig().isWsiBSPCompliant());
658 break;
659 }
660 sibling = sibling.getNextSibling();
661 }
662 } else {
663 timeStamp = (Timestamp)foundResults.get(0).get(WSSecurityEngineResult.TAG_TIMESTAMP);
664 }
665 if (timeStamp == null) {
666 return;
667 }
668
669
670 Date created = timeStamp.getCreated();
671 DateFormat zulu = new XmlSchemaDateFormat();
672 String identifier = zulu.format(created) + "" + Arrays.hashCode(signatureValue);
673
674 if (replayCache.contains(identifier)) {
675 throw new WSSecurityException(
676 WSSecurityException.INVALID_SECURITY,
677 "invalidTimestamp",
678 new Object[] {"A replay attack has been detected"}
679 );
680 }
681
682
683 Date expires = timeStamp.getExpires();
684 if (expires != null) {
685 Date rightNow = new Date();
686 long currentTime = rightNow.getTime();
687 long expiresTime = expires.getTime();
688 replayCache.add(identifier, ((expiresTime - currentTime) / 1000L));
689 } else {
690 replayCache.add(identifier);
691 }
692
693 }
694
695
696
697
698
699 private void checkBSPCompliance(
700 XMLSignature xmlSignature
701 ) throws WSSecurityException {
702
703 for (Object object : xmlSignature.getObjects()) {
704 if (object instanceof XMLObject) {
705 XMLObject xmlObject = (XMLObject)object;
706 for (Object xmlStructure : xmlObject.getContent()) {
707 if (xmlStructure instanceof Manifest) {
708 throw new WSSecurityException(
709 WSSecurityException.INVALID_SECURITY, "R5403"
710 );
711 }
712 }
713 }
714 }
715
716
717 String c14nMethod =
718 xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
719 if (!WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(c14nMethod)) {
720 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "badC14nAlgo");
721 }
722
723
724 AlgorithmParameterSpec parameterSpec =
725 xmlSignature.getSignedInfo().getSignatureMethod().getParameterSpec();
726 if (parameterSpec instanceof HMACParameterSpec) {
727 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "R5401");
728 }
729
730
731
732
733
734
735
736
737
738
739
740 for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
741 Reference reference = (Reference)refObject;
742 if (reference.getTransforms().isEmpty()) {
743 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "R5416");
744 }
745 for (int i = 0; i < reference.getTransforms().size(); i++) {
746 Transform transform = (Transform)reference.getTransforms().get(i);
747 String algorithm = transform.getAlgorithm();
748 if (!(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(algorithm)
749 || STRTransform.TRANSFORM_URI.equals(algorithm)
750 || WSConstants.NS_XMLDSIG_FILTER2.equals(algorithm)
751 || WSConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE.equals(algorithm)
752 || WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS.equals(algorithm)
753 || WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS.equals(algorithm))) {
754 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "R5423");
755 }
756 if (i == (reference.getTransforms().size() - 1)
757 && (!(WSConstants.C14N_EXCL_OMIT_COMMENTS.equals(algorithm)
758 || STRTransform.TRANSFORM_URI.equals(algorithm)
759 || WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS.equals(algorithm)
760 || WSConstants.SWA_ATTACHMENT_CONTENT_SIG_TRANS.equals(algorithm)))) {
761 throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "R5412");
762 }
763
764
765
766
767
768
769
770
771
772
773
774
775 }
776 }
777 }
778
779 }