You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2014/08/21 13:12:58 UTC
svn commit: r1619359 - in /webservices/wss4j/trunk/ws-security-dom/src:
main/java/org/apache/wss4j/dom/processor/
main/java/org/apache/wss4j/dom/util/ test/java/org/apache/wss4j/dom/message/
Author: coheigea
Date: Thu Aug 21 11:12:58 2014
New Revision: 1619359
URL: http://svn.apache.org/r1619359
Log:
Improving required signed elements detection
Modified:
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/RequireSignedEncryptedDataElementsTest.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TestMessageTransformer.java
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java Thu Aug 21 11:12:58 2014
@@ -91,7 +91,7 @@ public class EncryptedDataProcessor impl
);
if (elem != null && request.isRequireSignedEncryptedDataElements()) {
- WSSecurityUtil.verifySignedElement(elem, elem.getOwnerDocument(), wsDocInfo.getSecurityHeader());
+ WSSecurityUtil.verifySignedElement(elem, wsDocInfo);
}
SecretKey key = null;
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java Thu Aug 21 11:12:58 2014
@@ -448,7 +448,7 @@ public class EncryptedKeyProcessor imple
Element encryptedDataElement =
ReferenceListProcessor.findEncryptedDataElement(doc, docInfo, dataRefURI);
if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
- WSSecurityUtil.verifySignedElement(encryptedDataElement, doc, docInfo.getSecurityHeader());
+ WSSecurityUtil.verifySignedElement(encryptedDataElement, docInfo);
}
//
// Prepare the SecretKey object to decrypt EncryptedData
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java Thu Aug 21 11:12:58 2014
@@ -149,7 +149,7 @@ public class ReferenceListProcessor impl
Element encryptedDataElement = findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
if (encryptedDataElement != null && asymBinding && data.isRequireSignedEncryptedDataElements()) {
- WSSecurityUtil.verifySignedElement(encryptedDataElement, doc, wsDocInfo.getSecurityHeader());
+ WSSecurityUtil.verifySignedElement(encryptedDataElement, wsDocInfo);
}
//
// Prepare the SecretKey object to decrypt EncryptedData
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/WSSecurityUtil.java Thu Aug 21 11:12:58 2014
@@ -24,6 +24,7 @@ import org.apache.wss4j.dom.SOAP12Consta
import org.apache.wss4j.dom.SOAPConstants;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDataRef;
+import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.WSSecurityEngineResult;
import org.apache.wss4j.dom.WSSConfig;
import org.apache.wss4j.common.WSEncryptionPart;
@@ -51,10 +52,8 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
/**
* WS-Security Utility methods. <p/>
@@ -1238,56 +1237,44 @@ public final class WSSecurityUtil {
}
}
- public static void verifySignedElement(Element elem, Document doc, Element securityHeader)
+ public static void verifySignedElement(Element elem, WSDocInfo wsDocInfo)
throws WSSecurityException {
- final Element envelope = doc.getDocumentElement();
- final Set<String> signatureRefIDs = getSignatureReferenceIDs(securityHeader);
- if (!signatureRefIDs.isEmpty()) {
- Node cur = elem;
- while (!cur.isSameNode(envelope)) {
- if (cur.getNodeType() == Node.ELEMENT_NODE) {
- if (WSConstants.SIG_LN.equals(cur.getLocalName())
- && WSConstants.SIG_NS.equals(cur.getNamespaceURI())) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK,
- "requiredElementNotSigned", elem);
- } else if (isLinkedBySignatureRefs((Element)cur, signatureRefIDs)) {
- return;
+ List<WSSecurityEngineResult> signedResults =
+ wsDocInfo.getResultsByTag(WSConstants.SIGN);
+ if (signedResults != null) {
+ for (WSSecurityEngineResult signedResult : signedResults) {
+ @SuppressWarnings("unchecked")
+ List<WSDataRef> dataRefs =
+ (List<WSDataRef>)signedResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ if (dataRefs != null) {
+ for (WSDataRef dataRef : dataRefs) {
+ if (isElementOrAncestorSigned(elem, dataRef.getProtectedElement())) {
+ return;
+ }
}
}
- cur = cur.getParentNode();
}
}
+
throw new WSSecurityException(
WSSecurityException.ErrorCode.FAILED_CHECK, "requiredElementNotSigned", elem);
}
- private static boolean isLinkedBySignatureRefs(Element elem, Set<String> allIDs) {
- // Try the wsu:Id first
- String attributeNS = elem.getAttributeNS(WSConstants.WSU_NS, "Id");
- if (!"".equals(attributeNS) && allIDs.contains(attributeNS)) {
- return true;
- }
- attributeNS = elem.getAttributeNS(null, "Id");
- return !"".equals(attributeNS) && allIDs.contains(attributeNS);
- }
-
- private static Set<String> getSignatureReferenceIDs(Element wsseHeader) throws WSSecurityException {
- final Set<String> refs = new HashSet<String>();
- final List<Element> signatures = WSSecurityUtil.getDirectChildElements(wsseHeader, WSConstants.SIG_LN, WSConstants.SIG_NS);
- for (Element signature : signatures) {
- Element sigInfo = WSSecurityUtil.getDirectChildElement(signature, WSConstants.SIG_INFO_LN, WSConstants.SIG_NS);
- List<Element> references = WSSecurityUtil.getDirectChildElements(sigInfo, WSConstants.REF_LN, WSConstants.SIG_NS);
- for (Element reference : references) {
- String uri = reference.getAttributeNS(null, "URI");
- if (!"".equals(uri)) {
- boolean added = refs.add(WSSecurityUtil.getIDFromReference(uri));
- if (!added) {
- LOG.warn("Duplicated reference uri: " + uri);
- }
- }
+ /**
+ * Does the current element or some ancestor of it correspond to the known "signedElement"?
+ */
+ private static boolean isElementOrAncestorSigned(Element elem, Element signedElement)
+ throws WSSecurityException {
+ final Element envelope = elem.getOwnerDocument().getDocumentElement();
+ Node cur = elem;
+ while (!cur.isSameNode(envelope)) {
+ if (cur.getNodeType() == Node.ELEMENT_NODE && cur.equals(signedElement)) {
+ return true;
}
+ cur = cur.getParentNode();
}
- return refs;
+
+ return false;
}
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/RequireSignedEncryptedDataElementsTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/RequireSignedEncryptedDataElementsTest.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/RequireSignedEncryptedDataElementsTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/RequireSignedEncryptedDataElementsTest.java Thu Aug 21 11:12:58 2014
@@ -228,6 +228,44 @@ public class RequireSignedEncryptedDataE
}
}
+ @org.junit.Test
+ public void testEncryptedKeyRefAndDuplicatedEncDataInWsseWrapperBody() throws Exception {
+ Document encryptedSignedDoc = getRequestDocumentEncryptionFirst();
+ RequestData reqData = getRequestData(false);
+ TestMessageTransformer.duplicateEncryptedDataInWrapperBody(encryptedSignedDoc.getDocumentElement());
+ try {
+ verify(encryptedSignedDoc, reqData);
+ fail("WSSecurityException expected");
+ } catch (WSSecurityException e) {
+ assertTrue(e.getMessage().contains("The signature or decryption was invalid"));
+ }
+
+ encryptedSignedDoc = getRequestDocumentEncryptionFirst();
+ TestMessageTransformer.duplicateEncryptedDataInWrapperBody(encryptedSignedDoc.getDocumentElement());
+ reqData = getRequestData(true);
+
+ try {
+ verify(encryptedSignedDoc, reqData);
+ fail("WSSecurityException expected");
+ } catch (WSSecurityException e) {
+ assertTrue(e.getMessage().contains("is not included in the signature"));
+ }
+ }
+
+ @org.junit.Test
+ public void testEncryptedKeyRefAndDuplicatedEncDataAfterWsseWrapperBody() throws Exception {
+ Document encryptedSignedDoc = getRequestDocumentEncryptionFirst();
+ TestMessageTransformer.duplicateEncryptedDataAfterWrapperBody(encryptedSignedDoc.getDocumentElement());
+
+ RequestData reqData = getRequestData(true);
+ try {
+ verify(encryptedSignedDoc, reqData);
+ fail("WSSecurityException expected");
+ } catch (WSSecurityException e) {
+ assertTrue(e.getMessage().contains("is not included in the signature"));
+ }
+ }
+
private static void checkFailure(Element attackElement, WSSecurityException e) {
final String mex = MessageFormat.format(resources.getString("requiredElementNotSigned"), attackElement);
assertTrue(e.getMessage().contains(mex));
@@ -278,6 +316,38 @@ public class RequireSignedEncryptedDataE
}
return encryptedSignedDoc;
}
+
+ private Document getRequestDocumentEncryptionFirst() throws Exception {
+ WSSecEncrypt encrypt = new WSSecEncrypt();
+ WSSecSignature sign = new WSSecSignature();
+ encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
+ sign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ LOG.info("Before Encryption....");
+ Document doc = SOAPUtil.toSOAPPart(SOAPMSG);
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document signedDoc = sign.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("After Signing....");
+ String outputString =
+ XMLUtils.PrettyDocumentToString(signedDoc);
+ LOG.debug(outputString);
+ }
+
+ Document encryptedDoc = encrypt.build(signedDoc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("After Encryption....");
+ String outputString =
+ XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ return encryptedDoc;
+ }
private List<WSSecurityEngineResult> verify(Document doc, RequestData reqData) throws Exception {
Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TestMessageTransformer.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TestMessageTransformer.java?rev=1619359&r1=1619358&r2=1619359&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TestMessageTransformer.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/TestMessageTransformer.java Thu Aug 21 11:12:58 2014
@@ -119,6 +119,78 @@ public class TestMessageTransformer exte
print(saaj.getOwnerDocument());
return newEncData;
}
+
+ public static Element duplicateEncryptedDataInWrapperBody(Element saaj) throws TransformerException {
+ Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
+ "Body"), true);
+ Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
+ "EncryptedData"), true);
+ Element newEncData = createNewEncryptedData(encData);
+ Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
+ "Header"), true);
+ Element signature = getFirstChildElement(sh, new QName("http://www.w3.org/2000/09/xmldsig#",
+ "Signature"), true);
+
+ Node wsseHeader = signature.getParentNode();
+ Node newWsseHeader = wsseHeader.cloneNode(false);
+ Node cur = wsseHeader.getFirstChild();
+ String newId = newEncData.getAttributeNS(null, "Id");
+ while (!cur.isSameNode(signature)) {
+ cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
+ }
+ Element wrapper = encData.getOwnerDocument().createElementNS(null, "a");
+ wrapper.appendChild(newEncData);
+
+ body.appendChild(wrapper);
+ while (cur != null) {
+ cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
+ }
+
+ updateEncryptedKeyRefList(newWsseHeader, newId);
+
+ Node parent = wsseHeader.getParentNode();
+ parent.removeChild(wsseHeader);
+ parent.appendChild(newWsseHeader);
+ print(saaj.getOwnerDocument());
+ return newEncData;
+ }
+
+ public static Element duplicateEncryptedDataAfterWrapperBody(Element saaj) throws TransformerException {
+ Element body = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
+ "Body"), true);
+ Element encData = getFirstChildElement(body, new QName("http://www.w3.org/2001/04/xmlenc#",
+ "EncryptedData"), true);
+ Element newEncData = createNewEncryptedData(encData);
+ Element sh = getFirstChildElement(saaj, new QName("http://schemas.xmlsoap.org/soap/envelope/",
+ "Header"), true);
+ Element signature = getFirstChildElement(sh, new QName("http://www.w3.org/2000/09/xmldsig#",
+ "Signature"), true);
+
+ Node wsseHeader = signature.getParentNode();
+ Node newWsseHeader = wsseHeader.cloneNode(false);
+ Node cur = wsseHeader.getFirstChild();
+ String newId = newEncData.getAttributeNS(null, "Id");
+ while (!cur.isSameNode(signature)) {
+ cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
+ }
+ Element wrapper = encData.getOwnerDocument().createElementNS(null, "a");
+ Node clonedBody = body.cloneNode(false);
+ clonedBody.appendChild(newEncData);
+ wrapper.appendChild(clonedBody);
+
+ body.getParentNode().appendChild(wrapper);
+ while (cur != null) {
+ cur = copyHeadersAndUpdateRefList(cur, newWsseHeader, newId);
+ }
+
+ updateEncryptedKeyRefList(newWsseHeader, newId);
+
+ Node parent = wsseHeader.getParentNode();
+ parent.removeChild(wsseHeader);
+ parent.appendChild(newWsseHeader);
+ print(saaj.getOwnerDocument());
+ return newEncData;
+ }
public static Element duplicateEncryptedDataInExternalWrapperElement(Element saaj,
boolean moveReferenceList) throws TransformerException {