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