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 2015/05/22 16:34:20 UTC
svn commit: r1681129 - in
/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src:
main/java/org/apache/wss4j/dom/ main/java/org/apache/wss4j/dom/processor/
main/java/org/apache/wss4j/dom/util/ test/java/org/apache/wss4j/dom/message/
Author: coheigea
Date: Fri May 22 14:34:20 2015
New Revision: 1681129
URL: http://svn.apache.org/r1681129
Log:
Initial support added to the DOM code to support xop:Include processing
Conflicts:
ws-security-common/src/main/java/org/apache/wss4j/common/WSS4JConstants.java
ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
Added:
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java
- copied, changed from r1680507, webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
Removed:
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java
Modified:
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/WSConstants.java Fri May 22 14:34:20 2015
@@ -102,6 +102,7 @@ public final class WSConstants {
"http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Content-Only";
public static final String SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE =
"http://docs.oasis-open.org/wss/oasis-wss-SwAProfile-1.1#Attachment-Complete";
+ public static final String XOP_NS = "http://www.w3.org/2004/08/xop/include";
public static final String KEYTRANSPORT_RSA15 =
"http://www.w3.org/2001/04/xmlenc#rsa-1_5";
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedDataProcessor.java Fri May 22 14:34:20 2015
@@ -45,7 +45,9 @@ import org.apache.wss4j.dom.bsp.BSPEnfor
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.str.STRParser;
import org.apache.wss4j.dom.str.SecurityTokenRefSTRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.apache.wss4j.dom.util.X509Util;
/**
* This will process incoming <code>xenc:EncryptedData</code> elements.
@@ -141,7 +143,7 @@ public class EncryptedDataProcessor impl
algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
}
- WSDataRef dataRef = ReferenceListProcessor.decryptEncryptedData(
+ WSDataRef dataRef = EncryptionUtils.decryptEncryptedData(
elem.getOwnerDocument(), encryptedDataId, elem, key, symEncAlgo, request);
WSSecurityEngineResult result =
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java Fri May 22 14:34:20 2015
@@ -20,6 +20,7 @@
package org.apache.wss4j.dom.processor;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
@@ -34,6 +35,9 @@ import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -43,6 +47,8 @@ import org.apache.wss4j.common.bsp.BSPRu
import org.apache.wss4j.common.crypto.AlgorithmSuite;
import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.KeyUtils;
import org.apache.wss4j.dom.WSConstants;
@@ -55,10 +61,13 @@ import org.apache.wss4j.dom.message.toke
import org.apache.wss4j.dom.message.token.SecurityTokenReference;
import org.apache.wss4j.dom.str.EncryptedKeySTRParser;
import org.apache.wss4j.dom.str.STRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.apache.wss4j.dom.util.X509Util;
import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.exceptions.Base64DecodingException;
import org.apache.xml.security.utils.Base64;
+import org.apache.xml.security.utils.JavaUtils;
public class EncryptedKeyProcessor implements Processor {
private static final org.slf4j.Logger LOG =
@@ -204,8 +213,16 @@ public class EncryptedKeyProcessor imple
byte[] encryptedEphemeralKey = null;
byte[] decryptedBytes = null;
+
try {
- encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue);
+ // Get the key bytes from CipherValue directly or via an attachment
+ String xopUri = EncryptionUtils.getXOPURIFromCipherValue(xencCipherValue);
+ if (xopUri != null && xopUri.startsWith("cid:")) {
+ encryptedEphemeralKey = getDecryptedKeyBytesFromAttachment(xopUri, data);
+ } else {
+ encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue);
+ }
+
String keyAlgorithm = JCEMapper.translateURItoJCEID(encryptedKeyTransportMethod);
decryptedBytes = cipher.unwrap(encryptedEphemeralKey, keyAlgorithm, Cipher.SECRET_KEY).getEncoded();
} catch (IllegalStateException ex) {
@@ -238,6 +255,40 @@ public class EncryptedKeyProcessor imple
return java.util.Collections.singletonList(result);
}
+ private byte[] getDecryptedKeyBytesFromAttachment(
+ String xopUri, RequestData data
+ ) throws WSSecurityException {
+ CallbackHandler attachmentCallbackHandler = data.getAttachmentCallbackHandler();
+ if (attachmentCallbackHandler == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+ }
+
+ final String attachmentId = xopUri.substring(4);
+
+ AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
+ attachmentRequestCallback.setAttachmentId(attachmentId);
+
+ try {
+ attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
+
+ List<Attachment> attachments = attachmentRequestCallback.getAttachments();
+ if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.INVALID_SECURITY,
+ "empty", new Object[] {"Attachment not found"}
+ );
+ }
+ Attachment attachment = attachments.get(0);
+ InputStream inputStream = attachment.getSourceStream();
+
+ return JavaUtils.getBytesFromStream(inputStream);
+ } catch (UnsupportedCallbackException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (IOException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ }
+ }
+
/**
* Generates a random secret key using the algorithm specified in the
* first DataReference URI
@@ -253,7 +304,7 @@ public class EncryptedKeyProcessor imple
int size = 16;
if (!dataRefURIs.isEmpty()) {
String uri = dataRefURIs.iterator().next();
- Element ee = ReferenceListProcessor.findEncryptedDataElement(doc, wsDocInfo, uri);
+ Element ee = EncryptionUtils.findEncryptedDataElement(doc, wsDocInfo, uri);
String algorithmURI = X509Util.getEncAlgo(ee);
alg = JCEMapper.getJCEKeyAlgorithmFromURI(algorithmURI);
size = KeyUtils.getKeyLength(algorithmURI);
@@ -524,7 +575,7 @@ public class EncryptedKeyProcessor imple
// Find the encrypted data element referenced by dataRefURI
//
Element encryptedDataElement =
- ReferenceListProcessor.findEncryptedDataElement(doc, docInfo, dataRefURI);
+ EncryptionUtils.findEncryptedDataElement(doc, docInfo, dataRefURI);
if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
List<WSSecurityEngineResult> signedResults =
docInfo.getResultsByTag(WSConstants.SIGN);
@@ -567,7 +618,7 @@ public class EncryptedKeyProcessor imple
algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
}
- return ReferenceListProcessor.decryptEncryptedData(
+ return EncryptionUtils.decryptEncryptedData(
doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
);
}
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/ReferenceListProcessor.java Fri May 22 14:34:20 2015
@@ -19,31 +19,18 @@
package org.apache.wss4j.dom.processor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import org.apache.wss4j.common.ext.Attachment;
-import org.apache.wss4j.common.ext.AttachmentRequestCallback;
-import org.apache.wss4j.common.ext.AttachmentResultCallback;
-import org.apache.wss4j.common.util.AttachmentUtils;
-import org.apache.xml.security.algorithms.JCEMapper;
-import org.w3c.dom.Attr;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+
import org.apache.wss4j.common.bsp.BSPRule;
import org.apache.wss4j.common.crypto.AlgorithmSuite;
import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
@@ -56,14 +43,12 @@ import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.WSSecurityEngineResult;
import org.apache.wss4j.dom.bsp.BSPEnforcer;
import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.CallbackLookup;
-import org.apache.wss4j.dom.message.DOMCallbackLookup;
import org.apache.wss4j.dom.message.token.SecurityTokenReference;
import org.apache.wss4j.dom.str.STRParser;
import org.apache.wss4j.dom.str.SecurityTokenRefSTRParser;
+import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.util.WSSecurityUtil;
-import org.apache.xml.security.encryption.XMLCipher;
-import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.apache.wss4j.dom.util.X509Util;
public class ReferenceListProcessor implements Processor {
private static final org.slf4j.Logger LOG =
@@ -141,7 +126,8 @@ public class ReferenceListProcessor impl
//
// Find the encrypted data element referenced by dataRefURI
//
- Element encryptedDataElement = findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
+ Element encryptedDataElement =
+ EncryptionUtils.findEncryptedDataElement(doc, wsDocInfo, dataRefURI);
if (encryptedDataElement != null && data.isRequireSignedEncryptedDataElements()) {
List<WSSecurityEngineResult> signedResults =
@@ -208,7 +194,7 @@ public class ReferenceListProcessor impl
}
return
- decryptEncryptedData(
+ EncryptionUtils.decryptEncryptedData(
doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo, data
);
}
@@ -258,269 +244,5 @@ public class ReferenceListProcessor impl
}
}
- /**
- * Look up the encrypted data. First try Id="someURI". If no such Id then try
- * wsu:Id="someURI".
- *
- * @param doc The document in which to find EncryptedData
- * @param wsDocInfo The WSDocInfo object to use
- * @param dataRefURI The URI of EncryptedData
- * @return The EncryptedData element
- * @throws WSSecurityException if the EncryptedData element referenced by dataRefURI is
- * not found
- */
- public static Element
- findEncryptedDataElement(
- Document doc,
- WSDocInfo wsDocInfo,
- String dataRefURI
- ) throws WSSecurityException {
- CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
- if (callbackLookup == null) {
- callbackLookup = new DOMCallbackLookup(doc);
- }
- Element encryptedDataElement =
- callbackLookup.getElement(dataRefURI, null, true);
- if (encryptedDataElement == null) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef",
- new Object[] {dataRefURI});
- }
- if (encryptedDataElement.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
- && encryptedDataElement.getNamespaceURI().equals(WSConstants.WSSE11_NS)) {
- Node child = encryptedDataElement.getFirstChild();
- while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
- child = child.getNextSibling();
- }
- return (Element)child;
- }
- return encryptedDataElement;
- }
-
-
- /**
- * Decrypt the EncryptedData argument using a SecretKey.
- * @param doc The (document) owner of EncryptedData
- * @param dataRefURI The URI of EncryptedData
- * @param encData The EncryptedData element
- * @param symmetricKey The SecretKey with which to decrypt EncryptedData
- * @param symEncAlgo The symmetric encryption algorithm to use
- * @throws WSSecurityException
- */
- public static WSDataRef
- decryptEncryptedData(
- Document doc,
- String dataRefURI,
- Element encData,
- SecretKey symmetricKey,
- String symEncAlgo,
- RequestData requestData
- ) throws WSSecurityException {
-
- WSDataRef dataRef = new WSDataRef();
- dataRef.setEncryptedElement(encData);
- dataRef.setWsuId(dataRefURI);
- dataRef.setAlgorithm(symEncAlgo);
-
- String typeStr = encData.getAttributeNS(null, "Type");
- if (typeStr != null &&
- (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr) ||
- WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
-
- try {
- Element cipherData = WSSecurityUtil.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
- if (cipherData == null) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
- }
- Element cipherReference = WSSecurityUtil.getDirectChildElement(cipherData, "CipherReference", WSConstants.ENC_NS);
- if (cipherReference == null) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
- }
- String uri = cipherReference.getAttributeNS(null, "URI");
- if (uri == null || uri.length() < 5) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
- }
- if (!uri.startsWith("cid:")) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
- }
- dataRef.setWsuId(uri);
- dataRef.setAttachment(true);
-
- CallbackHandler attachmentCallbackHandler = requestData.getAttachmentCallbackHandler();
- if (attachmentCallbackHandler == null) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
- }
-
- final String attachmentId = uri.substring(4);
-
- AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
- attachmentRequestCallback.setAttachmentId(attachmentId);
-
- attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
- List<Attachment> attachments = attachmentRequestCallback.getAttachments();
- if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.INVALID_SECURITY,
- "empty", new Object[] {"Attachment not found"}
- );
- }
- Attachment attachment = attachments.get(0);
-
- final String encAlgo = X509Util.getEncAlgo(encData);
- final String jceAlgorithm =
- JCEMapper.translateURItoJCEID(encAlgo);
- final Cipher cipher = Cipher.getInstance(jceAlgorithm);
-
- InputStream attachmentInputStream =
- AttachmentUtils.setupAttachmentDecryptionStream(
- encAlgo, cipher, symmetricKey, attachment.getSourceStream());
-
- Attachment resultAttachment = new Attachment();
- resultAttachment.setId(attachment.getId());
- resultAttachment.setMimeType(encData.getAttributeNS(null, "MimeType"));
- resultAttachment.setSourceStream(attachmentInputStream);
- resultAttachment.addHeaders(attachment.getHeaders());
-
- if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr)) {
- AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(
- resultAttachment.getHeaders(), attachmentInputStream);
- }
-
- AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
- attachmentResultCallback.setAttachment(resultAttachment);
- attachmentResultCallback.setAttachmentId(resultAttachment.getId());
- attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
-
- } catch (UnsupportedCallbackException e) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILED_CHECK, e);
- } catch (IOException e) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILED_CHECK, e);
- } catch (NoSuchAlgorithmException e) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILED_CHECK, e);
- } catch (NoSuchPaddingException e) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILED_CHECK, e);
- }
-
- dataRef.setContent(true);
- // Remove this EncryptedData from the security header to avoid processing it again
- encData.getParentNode().removeChild(encData);
-
- return dataRef;
- }
-
- boolean content = X509Util.isContent(encData);
- dataRef.setContent(content);
-
- Node parent = encData.getParentNode();
- Node previousSibling = encData.getPreviousSibling();
- if (content) {
- encData = (Element) encData.getParentNode();
- parent = encData.getParentNode();
- }
-
- XMLCipher xmlCipher = null;
- try {
- xmlCipher = XMLCipher.getInstance(symEncAlgo);
- xmlCipher.setSecureValidation(true);
- xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
- } catch (XMLEncryptionException ex) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex
- );
- }
-
- try {
- xmlCipher.doFinal(doc, encData, content);
- } catch (Exception ex) {
- throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
- }
-
- if (parent.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
- && parent.getNamespaceURI().equals(WSConstants.WSSE11_NS)
- || parent.getLocalName().equals(WSConstants.ENCRYPED_ASSERTION_LN)
- && parent.getNamespaceURI().equals(WSConstants.SAML2_NS)) {
-
- Node decryptedHeader = parent.getFirstChild();
- Node soapHeader = parent.getParentNode();
- soapHeader.replaceChild(decryptedHeader, parent);
-
- dataRef.setProtectedElement((Element)decryptedHeader);
- dataRef.setXpath(getXPath(decryptedHeader));
- } else if (content) {
- dataRef.setProtectedElement(encData);
- dataRef.setXpath(getXPath(encData));
- } else {
- Node decryptedNode;
- if (previousSibling == null) {
- decryptedNode = parent.getFirstChild();
- } else {
- decryptedNode = previousSibling.getNextSibling();
- }
- if (decryptedNode != null && Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
- dataRef.setProtectedElement((Element)decryptedNode);
- }
- dataRef.setXpath(getXPath(decryptedNode));
- }
-
- return dataRef;
- }
-
-
- public String getId() {
- return null;
- }
-
-
- /**
- * @param decryptedNode the decrypted node
- * @return a fully built xpath
- * (eg. "/soapenv:Envelope/soapenv:Body/ns:decryptedElement")
- * if the decryptedNode is an Element or an Attr node and is not detached
- * from the document. <code>null</code> otherwise
- */
- public static String getXPath(Node decryptedNode) {
- if (decryptedNode == null) {
- return null;
- }
-
- String result = "";
- if (Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
- result = decryptedNode.getNodeName();
- result = prependFullPath(result, decryptedNode.getParentNode());
- } else if (Node.ATTRIBUTE_NODE == decryptedNode.getNodeType()) {
- result = "@" + decryptedNode.getNodeName();
- result = prependFullPath(result, ((Attr)decryptedNode).getOwnerElement());
- } else {
- return null;
- }
-
- return result;
- }
-
-
- /**
- * Recursively build an absolute xpath (starting with the root "/")
- *
- * @param xpath the xpath expression built so far
- * @param node the current node whose name is to be prepended
- * @return a fully built xpath
- */
- private static String prependFullPath(String xpath, Node node) {
- if (node == null) {
- // probably a detached node... not really useful
- return null;
- } else if (Node.ELEMENT_NODE == node.getNodeType()) {
- xpath = node.getNodeName() + "/" + xpath;
- return prependFullPath(xpath, node.getParentNode());
- } else if (Node.DOCUMENT_NODE == node.getNodeType()) {
- return "/" + xpath;
- } else {
- return prependFullPath(xpath, node.getParentNode());
- }
- }
-
}
+
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java Fri May 22 14:34:20 2015
@@ -48,6 +48,7 @@ import org.apache.wss4j.dom.WSDocInfo;
import org.apache.wss4j.dom.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
+import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.validate.Credential;
import org.apache.wss4j.dom.validate.Validator;
import org.opensaml.xml.signature.KeyInfo;
@@ -265,7 +266,7 @@ public class SAMLTokenProcessor implemen
}
ref.setTransformAlgorithms(transformAlgorithms);
- ref.setXpath(ReferenceListProcessor.getXPath(token));
+ ref.setXpath(EncryptionUtils.getXPath(token));
protectedRefs.add(ref);
}
}
Modified: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java?rev=1681129&r1=1681128&r2=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SignatureProcessor.java Fri May 22 14:34:20 2015
@@ -82,6 +82,7 @@ import org.apache.wss4j.dom.str.Signatur
import org.apache.wss4j.dom.transform.AttachmentContentSignatureTransform;
import org.apache.wss4j.dom.transform.STRTransform;
import org.apache.wss4j.dom.transform.STRTransformUtil;
+import org.apache.wss4j.dom.util.EncryptionUtils;
import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.dom.util.XmlSchemaDateFormat;
import org.apache.wss4j.dom.validate.Credential;
@@ -573,7 +574,7 @@ public class SignatureProcessor implemen
}
ref.setTransformAlgorithms(transformAlgorithms);
- ref.setXpath(ReferenceListProcessor.getXPath(se));
+ ref.setXpath(EncryptionUtils.getXPath(se));
protectedRefs.add(ref);
}
}
Added: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java?rev=1681129&view=auto
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java (added)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java Fri May 22 14:34:20 2015
@@ -0,0 +1,378 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wss4j.dom.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.ext.AttachmentRequestCallback;
+import org.apache.wss4j.common.ext.AttachmentResultCallback;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.AttachmentUtils;
+import org.apache.wss4j.common.util.XMLUtils;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSDataRef;
+import org.apache.wss4j.dom.WSDocInfo;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.message.CallbackLookup;
+import org.apache.wss4j.dom.message.DOMCallbackLookup;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public final class EncryptionUtils {
+
+ private EncryptionUtils() {
+ // complete
+ }
+
+ /**
+ * Look up the encrypted data. First try Id="someURI". If no such Id then try
+ * wsu:Id="someURI".
+ *
+ * @param doc The document in which to find EncryptedData
+ * @param wsDocInfo The WSDocInfo object to use
+ * @param dataRefURI The URI of EncryptedData
+ * @return The EncryptedData element
+ * @throws WSSecurityException if the EncryptedData element referenced by dataRefURI is
+ * not found
+ */
+ public static Element
+ findEncryptedDataElement(
+ Document doc,
+ WSDocInfo wsDocInfo,
+ String dataRefURI
+ ) throws WSSecurityException {
+ CallbackLookup callbackLookup = wsDocInfo.getCallbackLookup();
+ if (callbackLookup == null) {
+ callbackLookup = new DOMCallbackLookup(doc);
+ }
+ Element encryptedDataElement =
+ callbackLookup.getElement(dataRefURI, null, true);
+ if (encryptedDataElement == null) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.INVALID_SECURITY, "dataRef",
+ new Object[] {dataRefURI});
+ }
+ if (encryptedDataElement.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
+ && encryptedDataElement.getNamespaceURI().equals(WSConstants.WSSE11_NS)) {
+ Node child = encryptedDataElement.getFirstChild();
+ while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
+ child = child.getNextSibling();
+ }
+ return (Element)child;
+ }
+ return encryptedDataElement;
+ }
+
+
+ /**
+ * Decrypt the EncryptedData argument using a SecretKey.
+ * @param doc The (document) owner of EncryptedData
+ * @param dataRefURI The URI of EncryptedData
+ * @param encData The EncryptedData element
+ * @param symmetricKey The SecretKey with which to decrypt EncryptedData
+ * @param symEncAlgo The symmetric encryption algorithm to use
+ * @throws WSSecurityException
+ */
+ public static WSDataRef
+ decryptEncryptedData(
+ Document doc,
+ String dataRefURI,
+ Element encData,
+ SecretKey symmetricKey,
+ String symEncAlgo,
+ RequestData requestData
+ ) throws WSSecurityException {
+
+ WSDataRef dataRef = new WSDataRef();
+ dataRef.setEncryptedElement(encData);
+ dataRef.setWsuId(dataRefURI);
+ dataRef.setAlgorithm(symEncAlgo);
+
+ // See if it is an attachment, and handle that differently
+ String typeStr = encData.getAttributeNS(null, "Type");
+ String xopURI = getXOPURIFromEncryptedData(encData);
+ if (typeStr != null &&
+ (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_CONTENT_ONLY.equals(typeStr) ||
+ WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr))) {
+
+ Element cipherData = XMLUtils.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
+ if (cipherData == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+ }
+ Element cipherReference = XMLUtils.getDirectChildElement(cipherData, "CipherReference", WSConstants.ENC_NS);
+ if (cipherReference == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+ }
+ String uri = cipherReference.getAttributeNS(null, "URI");
+
+ return decryptAttachment(dataRefURI, uri, false, encData, symmetricKey, symEncAlgo, requestData);
+ } else if (xopURI != null) {
+ return decryptAttachment(dataRefURI, xopURI, true, encData, symmetricKey, symEncAlgo, requestData);
+ }
+
+ boolean content = X509Util.isContent(encData);
+ dataRef.setContent(content);
+
+ Node parent = encData.getParentNode();
+ Node previousSibling = encData.getPreviousSibling();
+ if (content) {
+ encData = (Element) encData.getParentNode();
+ parent = encData.getParentNode();
+ }
+
+ XMLCipher xmlCipher = null;
+ try {
+ xmlCipher = XMLCipher.getInstance(symEncAlgo);
+ xmlCipher.setSecureValidation(true);
+ xmlCipher.init(XMLCipher.DECRYPT_MODE, symmetricKey);
+ } catch (XMLEncryptionException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.UNSUPPORTED_ALGORITHM, ex
+ );
+ }
+
+ try {
+ xmlCipher.doFinal(doc, encData, content);
+ } catch (Exception ex) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
+ }
+
+ if (parent.getLocalName().equals(WSConstants.ENCRYPTED_HEADER)
+ && parent.getNamespaceURI().equals(WSConstants.WSSE11_NS)
+ || parent.getLocalName().equals(WSConstants.ENCRYPED_ASSERTION_LN)
+ && parent.getNamespaceURI().equals(WSConstants.SAML2_NS)) {
+
+ Node decryptedHeader = parent.getFirstChild();
+ Node soapHeader = parent.getParentNode();
+ soapHeader.replaceChild(decryptedHeader, parent);
+
+ dataRef.setProtectedElement((Element)decryptedHeader);
+ dataRef.setXpath(getXPath(decryptedHeader));
+ } else if (content) {
+ dataRef.setProtectedElement(encData);
+ dataRef.setXpath(getXPath(encData));
+ } else {
+ Node decryptedNode;
+ if (previousSibling == null) {
+ decryptedNode = parent.getFirstChild();
+ } else {
+ decryptedNode = previousSibling.getNextSibling();
+ }
+ if (decryptedNode != null && Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
+ dataRef.setProtectedElement((Element)decryptedNode);
+ }
+ dataRef.setXpath(getXPath(decryptedNode));
+ }
+
+ return dataRef;
+ }
+
+ private static String getXOPURIFromEncryptedData(Element encData) {
+ Element cipherData = XMLUtils.getDirectChildElement(encData, "CipherData", WSConstants.ENC_NS);
+ if (cipherData != null) {
+ Element cipherValue =
+ XMLUtils.getDirectChildElement(cipherData, "CipherValue", WSConstants.ENC_NS);
+ return getXOPURIFromCipherValue(cipherValue);
+ }
+
+ return null;
+ }
+
+ public static String getXOPURIFromCipherValue(Element cipherValue) {
+ if (cipherValue != null && cipherValue.hasAttributeNS(WSConstants.XMLNS_NS, "xop")
+ && WSConstants.XOP_NS.equals(cipherValue.getAttributeNS(WSConstants.XMLNS_NS, "xop"))) {
+ Element cipherValueChild =
+ XMLUtils.getDirectChildElement(cipherValue, "Include", WSConstants.XOP_NS);
+ if (cipherValueChild != null && cipherValueChild.hasAttributeNS(null, "href")) {
+ return cipherValueChild.getAttributeNS(null, "href");
+ }
+ }
+
+ return null;
+ }
+
+
+ private static WSDataRef
+ decryptAttachment(
+ String dataRefURI,
+ String uri,
+ boolean xop,
+ Element encData,
+ SecretKey symmetricKey,
+ String symEncAlgo,
+ RequestData requestData
+ ) throws WSSecurityException {
+ WSDataRef dataRef = new WSDataRef();
+ dataRef.setWsuId(dataRefURI);
+ dataRef.setAlgorithm(symEncAlgo);
+
+ try {
+ if (uri == null || uri.length() < 5 || !uri.startsWith("cid:")) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+ }
+ dataRef.setWsuId(uri);
+ dataRef.setAttachment(true);
+
+ CallbackHandler attachmentCallbackHandler = requestData.getAttachmentCallbackHandler();
+ if (attachmentCallbackHandler == null) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
+ }
+
+ final String attachmentId = uri.substring(4);
+
+ AttachmentRequestCallback attachmentRequestCallback = new AttachmentRequestCallback();
+ attachmentRequestCallback.setAttachmentId(attachmentId);
+
+ attachmentCallbackHandler.handle(new Callback[]{attachmentRequestCallback});
+ List<Attachment> attachments = attachmentRequestCallback.getAttachments();
+ if (attachments == null || attachments.isEmpty() || !attachmentId.equals(attachments.get(0).getId())) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.INVALID_SECURITY,
+ "empty", new Object[] {"Attachment not found"}
+ );
+ }
+ Attachment attachment = attachments.get(0);
+
+ final String encAlgo = X509Util.getEncAlgo(encData);
+ final String jceAlgorithm =
+ JCEMapper.translateURItoJCEID(encAlgo);
+ final Cipher cipher = Cipher.getInstance(jceAlgorithm);
+
+ InputStream attachmentInputStream =
+ AttachmentUtils.setupAttachmentDecryptionStream(
+ encAlgo, cipher, symmetricKey, attachment.getSourceStream());
+
+ // For the xop:Include case, we need to replace the xop:Include Element with the
+ // decrypted Element
+ if (xop) {
+ DocumentBuilder db =
+ org.apache.xml.security.utils.XMLUtils.createDocumentBuilder(false);
+ Document doc = db.parse(attachmentInputStream);
+ Node importedNode = encData.getOwnerDocument().importNode(doc.getDocumentElement(), true);
+ encData.getParentNode().appendChild(importedNode);
+ org.apache.xml.security.utils.XMLUtils.repoolDocumentBuilder(db);
+ }
+
+ Attachment resultAttachment = new Attachment();
+ resultAttachment.setId(attachment.getId());
+ resultAttachment.setMimeType(encData.getAttributeNS(null, "MimeType"));
+ resultAttachment.setSourceStream(attachmentInputStream);
+ resultAttachment.addHeaders(attachment.getHeaders());
+
+ String typeStr = encData.getAttributeNS(null, "Type");
+ if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr)) {
+ AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(
+ resultAttachment.getHeaders(), attachmentInputStream);
+ }
+
+ AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback();
+ attachmentResultCallback.setAttachment(resultAttachment);
+ attachmentResultCallback.setAttachmentId(resultAttachment.getId());
+ attachmentCallbackHandler.handle(new Callback[]{attachmentResultCallback});
+
+ } catch (UnsupportedCallbackException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (IOException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (NoSuchAlgorithmException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (NoSuchPaddingException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (ParserConfigurationException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ } catch (SAXException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, e);
+ }
+
+ dataRef.setContent(true);
+ // Remove this EncryptedData from the security header to avoid processing it again
+ encData.getParentNode().removeChild(encData);
+
+ return dataRef;
+ }
+
+ /**
+ * @param decryptedNode the decrypted node
+ * @return a fully built xpath
+ * (eg. "/soapenv:Envelope/soapenv:Body/ns:decryptedElement")
+ * if the decryptedNode is an Element or an Attr node and is not detached
+ * from the document. <code>null</code> otherwise
+ */
+ public static String getXPath(Node decryptedNode) {
+ if (decryptedNode == null) {
+ return null;
+ }
+
+ String result = "";
+ if (Node.ELEMENT_NODE == decryptedNode.getNodeType()) {
+ result = decryptedNode.getNodeName();
+ result = prependFullPath(result, decryptedNode.getParentNode());
+ } else if (Node.ATTRIBUTE_NODE == decryptedNode.getNodeType()) {
+ result = "@" + decryptedNode.getNodeName();
+ result = prependFullPath(result, ((Attr)decryptedNode).getOwnerElement());
+ } else {
+ return null;
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Recursively build an absolute xpath (starting with the root "/")
+ *
+ * @param xpath the xpath expression built so far
+ * @param node the current node whose name is to be prepended
+ * @return a fully built xpath
+ */
+ private static String prependFullPath(String xpath, Node node) {
+ if (node == null) {
+ // probably a detached node... not really useful
+ return null;
+ } else if (Node.ELEMENT_NODE == node.getNodeType()) {
+ xpath = node.getNodeName() + "/" + xpath;
+ return prependFullPath(xpath, node.getParentNode());
+ } else if (Node.DOCUMENT_NODE == node.getNodeType()) {
+ return "/" + xpath;
+ } else {
+ return prependFullPath(xpath, node.getParentNode());
+ }
+ }
+
+}
Copied: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java (from r1680507, webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java)
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java?p2=webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java&p1=webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java&r1=1680507&r2=1681129&rev=1681129&view=diff
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/X509Util.java (original)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/X509Util.java Fri May 22 14:34:20 2015
@@ -17,13 +17,12 @@
* under the License.
*/
-package org.apache.wss4j.dom.processor;
+package org.apache.wss4j.dom.util;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.KeyUtils;
-import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
@@ -73,7 +72,7 @@ public final class X509Util {
return symEncAlgo;
}
- protected static SecretKey getSharedKey(
+ public static SecretKey getSharedKey(
Element keyInfoElem,
String algorithm,
CallbackHandler cb
Added: webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java?rev=1681129&view=auto
==============================================================================
--- webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java (added)
+++ webservices/wss4j/branches/2_0_x-fixes/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/XOPAttachmentTest.java Fri May 22 14:34:20 2015
@@ -0,0 +1,190 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.wss4j.dom.message;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.wss4j.common.WSEncryptionPart;
+import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.CryptoFactory;
+import org.apache.wss4j.common.ext.Attachment;
+import org.apache.wss4j.common.util.XMLUtils;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSSConfig;
+import org.apache.wss4j.dom.WSSecurityEngine;
+import org.apache.wss4j.dom.WSSecurityEngineResult;
+import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
+import org.apache.wss4j.dom.common.SOAPUtil;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Test for processing an xop:Include inside a CipherValue Element
+ */
+public class XOPAttachmentTest extends org.junit.Assert {
+
+ private static final String SOAP_BODY =
+ "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\">"
+ + "<value xmlns=\"\">15</value>"
+ + "</add>";
+
+ private static final org.slf4j.Logger LOG =
+ org.slf4j.LoggerFactory.getLogger(XOPAttachmentTest.class);
+
+ private WSSecurityEngine secEngine = new WSSecurityEngine();
+ private Crypto crypto = null;
+
+ public XOPAttachmentTest() throws Exception {
+ WSSConfig.init();
+ crypto = CryptoFactory.getInstance();
+ }
+
+ protected byte[] readInputStream(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ try {
+ int read = 0;
+ byte[] buf = new byte[4096];
+ while ((read = inputStream.read(buf)) != -1) {
+ byteArrayOutputStream.write(buf, 0, read);
+ }
+ return byteArrayOutputStream.toByteArray();
+ } finally {
+ byteArrayOutputStream.close();
+ }
+ }
+
+ // Set up a test to encrypt the SOAP Body + an attachment, which is the same content as
+ // the SOAP Body. Then replace the encrypted SOAP Body with a xop:Include to the attachment,
+ // and modify the request to remove the encryption stuff pointing to the attachment.
+ @org.junit.Test
+ public void testEncryptedSOAPBody() throws Exception {
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecEncrypt encrypt = new WSSecEncrypt();
+ encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+ encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
+ parts.add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
+ parts.add(new WSEncryptionPart("cid:Attachments", "Content"));
+ encrypt.setParts(parts);
+
+ String attachmentId = UUID.randomUUID().toString();
+ final Attachment attachment = new Attachment();
+ attachment.setId(attachmentId);
+ attachment.setSourceStream(new ByteArrayInputStream(SOAP_BODY.getBytes("UTF-8")));
+
+ AttachmentCallbackHandler attachmentCallbackHandler =
+ new AttachmentCallbackHandler(Collections.singletonList(attachment));
+ encrypt.setAttachmentCallbackHandler(attachmentCallbackHandler);
+ List<Attachment> encryptedAttachments = attachmentCallbackHandler.getResponseAttachments();
+
+ Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
+
+ // Find the SOAP Body + replace with a xop:Include to the attachment!
+ Element soapBody = WSSecurityUtil.findBodyElement(encryptedDoc);
+ assertNotNull(soapBody);
+ Element encryptedData =
+ XMLUtils.getDirectChildElement(soapBody, "EncryptedData", WSConstants.ENC_NS);
+ encryptedData.removeAttributeNS(null, "Type");
+ Element cipherData =
+ XMLUtils.getDirectChildElement(encryptedData, "CipherData", WSConstants.ENC_NS);
+ assertNotNull(cipherData);
+ Element cipherValue =
+ XMLUtils.getDirectChildElement(cipherData, "CipherValue", WSConstants.ENC_NS);
+ assertNotNull(cipherValue);
+
+ WSSecurityUtil.setNamespace(cipherValue, WSConstants.XOP_NS, "xop");
+
+ Element cipherValueChild = encryptedDoc.createElementNS(WSConstants.XOP_NS, "Include");
+ cipherValueChild.setAttributeNS(null, "href", "cid:" + encryptedAttachments.get(0).getId());
+ cipherValue.replaceChild(cipherValueChild, cipherValue.getFirstChild());
+
+ // Remove EncryptedData structure from the security header (which encrypted the attachment
+ // in the first place)
+ Element securityHeader =
+ WSSecurityUtil.findWsseSecurityHeaderBlock(encryptedDoc, encryptedDoc.getDocumentElement(), false);
+ Element encryptedAttachmentData =
+ XMLUtils.getDirectChildElement(securityHeader, "EncryptedData", WSConstants.ENC_NS);
+ assertNotNull(encryptedAttachmentData);
+ String encryptedDataId = encryptedAttachmentData.getAttributeNS(null, "Id");
+ securityHeader.removeChild(encryptedAttachmentData);
+
+ // Now get EncryptedKey + remove the reference to the EncryptedData above
+ Element encryptedKey =
+ XMLUtils.getDirectChildElement(securityHeader, "EncryptedKey", WSConstants.ENC_NS);
+ assertNotNull(encryptedKey);
+ Element referenceList =
+ XMLUtils.getDirectChildElement(encryptedKey, "ReferenceList", WSConstants.ENC_NS);
+ assertNotNull(referenceList);
+ Node child = referenceList.getFirstChild();
+ while (child != null) {
+ if (child instanceof Element && "DataReference".equals(child.getLocalName())
+ && WSConstants.ENC_NS.equals(child.getNamespaceURI())) {
+ String uri = ((Element)child).getAttributeNS(null, "URI");
+ if (uri.equals("#" + encryptedDataId)) {
+ referenceList.removeChild(child);
+ break;
+ }
+ }
+ child = child.getNextSibling();
+ }
+
+ if (LOG.isDebugEnabled()) {
+ String outputString = XMLUtils.PrettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ //System.out.println(outputString);
+ }
+
+ attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments);
+ verify(encryptedDoc, attachmentCallbackHandler);
+
+ String processedDoc = XMLUtils.PrettyDocumentToString(encryptedDoc);
+ assertTrue(processedDoc.contains(SOAP_BODY));
+ }
+
+ /**
+ * Verifies the soap envelope.
+ * This method verifies all the signature generated.
+ *
+ * @throws java.lang.Exception Thrown when there is a problem in verification
+ */
+ private List<WSSecurityEngineResult> verify(Document doc, CallbackHandler attachmentCallbackHandler) throws Exception {
+ RequestData requestData = new RequestData();
+ requestData.setAttachmentCallbackHandler(attachmentCallbackHandler);
+ requestData.setSigVerCrypto(crypto);
+ requestData.setDecCrypto(crypto);
+ requestData.setCallbackHandler(new KeystoreCallbackHandler());
+ return secEngine.processSecurityHeader(doc, null, requestData);
+ }
+}