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 2016/02/02 11:47:41 UTC
svn commit: r1728073 - in /webservices/wss4j/trunk:
ws-security-common/src/main/java/org/apache/wss4j/common/util/
ws-security-dom/src/main/java/org/apache/wss4j/dom/message/
ws-security-dom/src/test/java/org/apache/wss4j/dom/message/
ws-security-stax/...
Author: coheigea
Date: Tue Feb 2 10:47:41 2016
New Revision: 1728073
URL: http://svn.apache.org/viewvc?rev=1728073&view=rev
Log:
[WSS-566] - AES_128_GCM does not work for attachments
Modified:
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/AttachmentUtils.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java
webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java
Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/AttachmentUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/AttachmentUtils.java?rev=1728073&r1=1728072&r2=1728073&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/AttachmentUtils.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/util/AttachmentUtils.java Tue Feb 2 10:47:41 2016
@@ -20,12 +20,12 @@ package org.apache.wss4j.common.util;
import org.apache.wss4j.common.ext.Attachment;
import org.apache.wss4j.common.ext.WSSecurityException;
-import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipherUtil;
import org.apache.xml.security.stax.impl.util.MultiInputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
-import javax.crypto.spec.IvParameterSpec;
import javax.mail.internet.MimeUtility;
import java.io.*;
@@ -34,6 +34,7 @@ import java.nio.charset.StandardCharsets
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.*;
public final class AttachmentUtils {
@@ -479,23 +480,19 @@ public final class AttachmentUtils {
private boolean firstRead = true;
private void initCipher() throws IOException {
- // For now, we only work with Block ciphers, so this will work.
- // This should probably be put into the JCE mapper.
- int ivLen = cipher.getBlockSize();
- if (XMLCipher.AES_128_GCM.equals(encAlgo) || XMLCipher.AES_192_GCM.equals(encAlgo)
- || XMLCipher.AES_256_GCM.equals(encAlgo)) {
- ivLen = 12;
- }
-
+ int ivLen = JCEMapper.getIVLengthFromURI(encAlgo) / 8;
byte[] ivBytes = new byte[ivLen];
+
int read = super.in.read(ivBytes, 0, ivLen);
while (read != ivLen) {
read += super.in.read(ivBytes, read, ivLen - read);
}
- IvParameterSpec iv = new IvParameterSpec(ivBytes);
+
+ AlgorithmParameterSpec paramSpec =
+ XMLCipherUtil.constructBlockCipherParameters(encAlgo, ivBytes, AttachmentUtils.class);
try {
- cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ cipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IOException(e);
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java?rev=1728073&r1=1728072&r2=1728073&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java Tue Feb 2 10:47:41 2016
@@ -20,6 +20,7 @@
package org.apache.wss4j.dom.message;
import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -30,7 +31,6 @@ import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
@@ -59,8 +59,10 @@ import org.apache.xml.security.encryptio
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.TransformSerializer;
import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLCipherUtil;
import org.apache.xml.security.encryption.XMLEncryptionException;
import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.stax.ext.XMLSecurityConstants;
import org.apache.xml.security.utils.Base64;
import org.apache.xml.security.utils.EncryptionConstants;
import org.w3c.dom.Attr;
@@ -631,17 +633,13 @@ public class WSSecEncrypt extends WSSecE
String jceAlgorithm = JCEMapper.translateURItoJCEID(encryptionAlgorithm);
try {
Cipher cipher = Cipher.getInstance(jceAlgorithm);
+
+ int ivLen = JCEMapper.getIVLengthFromURI(encryptionAlgorithm) / 8;
+ byte[] iv = XMLSecurityConstants.generateBytes(ivLen);
+ AlgorithmParameterSpec paramSpec =
+ XMLCipherUtil.constructBlockCipherParameters(encryptionAlgorithm, iv, WSSecEncrypt.class);
+ cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
- // The Spec mandates a 96-bit IV for GCM algorithms
- if (XMLCipher.AES_128_GCM.equals(encryptionAlgorithm)
- || XMLCipher.AES_192_GCM.equals(encryptionAlgorithm)
- || XMLCipher.AES_256_GCM.equals(encryptionAlgorithm)) {
- byte[] iv = WSSecurityUtil.generateNonce(12);
- IvParameterSpec paramSpec = new IvParameterSpec(iv);
- cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
- } else {
- cipher.init(Cipher.ENCRYPT_MODE, secretKey);
- }
return cipher;
} catch (Exception e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java?rev=1728073&r1=1728072&r2=1728073&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java Tue Feb 2 10:47:41 2016
@@ -411,6 +411,66 @@ public class AttachmentTest extends Asse
}
@Test
+ public void testXMLAttachmentContentEncryptionGCM() 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);
+ encrypt.setSymmetricEncAlgorithm(WSConstants.AES_128_GCM);
+
+ WSSecHeader secHeader = new WSSecHeader(doc);
+ secHeader.insertSecurityHeader();
+
+ encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content"));
+ encrypt.getParts().add(new WSEncryptionPart("cid:Attachments", "Content"));
+
+ String attachmentId = UUID.randomUUID().toString();
+ final Attachment attachment = new Attachment();
+ attachment.setMimeType("text/xml");
+ attachment.addHeaders(getHeaders(attachmentId));
+ attachment.setId(attachmentId);
+ attachment.setSourceStream(new ByteArrayInputStream(SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8)));
+
+ AttachmentCallbackHandler attachmentCallbackHandler =
+ new AttachmentCallbackHandler(Collections.singletonList(attachment));
+ encrypt.setAttachmentCallbackHandler(attachmentCallbackHandler);
+ List<Attachment> encryptedAttachments = attachmentCallbackHandler.getResponseAttachments();
+
+ Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
+
+ if (LOG.isDebugEnabled()) {
+ String outputString = XMLUtils.prettyDocumentToString(encryptedDoc);
+ LOG.debug(outputString);
+ }
+
+ NodeList references = doc.getElementsByTagNameNS(WSConstants.ENC_NS, "DataReference");
+ Assert.assertEquals(2, references.getLength());
+ NodeList cipherReferences = doc.getElementsByTagNameNS(WSConstants.ENC_NS, "CipherReference");
+ Assert.assertEquals(1, cipherReferences.getLength());
+ NodeList encDatas = doc.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData");
+ Assert.assertEquals(2, encDatas.getLength());
+
+ NodeList securityHeaderElement = doc.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
+ Assert.assertEquals(1, securityHeaderElement.getLength());
+ NodeList childs = securityHeaderElement.item(0).getChildNodes();
+ Assert.assertEquals(2, childs.getLength());
+ Assert.assertEquals(childs.item(0).getLocalName(), "EncryptedKey");
+ Assert.assertEquals(childs.item(1).getLocalName(), "EncryptedData");
+
+ attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments);
+ verify(encryptedDoc, attachmentCallbackHandler);
+
+ Assert.assertFalse(attachmentCallbackHandler.getResponseAttachments().isEmpty());
+ Attachment responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(0);
+ byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream());
+ Assert.assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8)));
+ Assert.assertEquals("text/xml", responseAttachment.getMimeType());
+
+ Map<String, String> attHeaders = responseAttachment.getHeaders();
+ Assert.assertEquals(6, attHeaders.size());
+ }
+
+ @Test
public void testInvalidXMLAttachmentContentEncryption() throws Exception {
Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
WSSecEncrypt encrypt = new WSSecEncrypt();
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java?rev=1728073&r1=1728072&r2=1728073&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/EncryptOutputProcessor.java Tue Feb 2 10:47:41 2016
@@ -21,6 +21,7 @@ package org.apache.wss4j.stax.impl.proce
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -28,7 +29,6 @@ import java.util.List;
import java.util.Map;
import javax.crypto.Cipher;
-import javax.crypto.spec.IvParameterSpec;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
@@ -45,6 +45,8 @@ import org.apache.wss4j.stax.ext.WSSCons
import org.apache.wss4j.stax.ext.WSSSecurityProperties;
import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
import org.apache.wss4j.stax.utils.WSSUtils;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipherUtil;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.config.JCEAlgorithmMapper;
import org.apache.xml.security.stax.config.TransformerAlgorithmMapper;
@@ -263,15 +265,13 @@ public class EncryptOutputProcessor exte
Cipher cipher = null;
try {
cipher = Cipher.getInstance(jceAlgorithm);
+
+ int ivLen = JCEMapper.getIVLengthFromURI(encryptionSymAlgorithm) / 8;
+ byte[] iv = XMLSecurityConstants.generateBytes(ivLen);
+ AlgorithmParameterSpec paramSpec =
+ XMLCipherUtil.constructBlockCipherParameters(encryptionSymAlgorithm, iv, this.getClass());
+ cipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey(), paramSpec);
- // The Spec mandates a 96-bit IV for GCM algorithms
- if ("AES/GCM/NoPadding".equals(cipher.getAlgorithm())) {
- byte[] temp = XMLSecurityConstants.generateBytes(12);
- IvParameterSpec ivParameterSpec = new IvParameterSpec(temp);
- cipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey(), ivParameterSpec);
- } else {
- cipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey());
- }
} catch (Exception e) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_ENCRYPTION, e);
}
Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java?rev=1728073&r1=1728072&r2=1728073&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java Tue Feb 2 10:47:41 2016
@@ -479,6 +479,78 @@ public class AttachmentTest extends Abst
Map<String, String> attHeaders = responseAttachment.getHeaders();
Assert.assertEquals(6, attHeaders.size());
}
+
+ @Test
+ public void testXMLAttachmentContentEncryptionGCM() throws Exception {
+
+ final String attachmentId = UUID.randomUUID().toString();
+ final Attachment attachment = new Attachment();
+ attachment.setMimeType("text/xml");
+ attachment.addHeaders(getHeaders(attachmentId));
+ attachment.setId(attachmentId);
+ attachment.setSourceStream(new ByteArrayInputStream(SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8)));
+ AttachmentCallbackHandler attachmentCallbackHandler =
+ new AttachmentCallbackHandler(Collections.singletonList(attachment));
+ List<Attachment> encryptedAttachments = attachmentCallbackHandler.getResponseAttachments();
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ {
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
+ actions.add(WSSConstants.ENCRYPT);
+ securityProperties.setActions(actions);
+ securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
+ securityProperties.setEncryptionUser("receiver");
+ securityProperties.addEncryptionPart(new SecurePart(new QName("http://schemas.xmlsoap.org/soap/envelope/", "Body"), SecurePart.Modifier.Content));
+ securityProperties.addEncryptionPart(new SecurePart("cid:Attachments", SecurePart.Modifier.Content));
+ securityProperties.setAttachmentCallbackHandler(attachmentCallbackHandler);
+ securityProperties.setEncryptionSymAlgorithm(WSSConstants.NS_XENC11_AES128_GCM);
+
+ OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
+ XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, StandardCharsets.UTF_8.name(), new ArrayList<SecurityEvent>());
+ XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
+ XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+ xmlStreamWriter.close();
+
+ Document securedDoc = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+
+ NodeList references = securedDoc.getElementsByTagNameNS(WSConstants.ENC_NS, "DataReference");
+ Assert.assertEquals(2, references.getLength());
+ NodeList cipherReferences = securedDoc.getElementsByTagNameNS(WSConstants.ENC_NS, "CipherReference");
+ Assert.assertEquals(1, cipherReferences.getLength());
+ NodeList encDatas = securedDoc.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData");
+ Assert.assertEquals(2, encDatas.getLength());
+
+ NodeList securityHeaderElement = securedDoc.getElementsByTagNameNS(WSConstants.WSSE_NS, "Security");
+ Assert.assertEquals(1, securityHeaderElement.getLength());
+ NodeList childs = securityHeaderElement.item(0).getChildNodes();
+ Assert.assertEquals(2, childs.getLength());
+ Assert.assertEquals(childs.item(0).getLocalName(), "EncryptedKey");
+ Assert.assertEquals(childs.item(1).getLocalName(), "EncryptedData");
+ }
+
+ attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments);
+ {
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.loadDecryptionKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ securityProperties.setAttachmentCallbackHandler(attachmentCallbackHandler);
+
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+ XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
+ StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
+ }
+
+ Assert.assertFalse(attachmentCallbackHandler.getResponseAttachments().isEmpty());
+ Attachment responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(0);
+
+ byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream());
+ Assert.assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8)));
+ Assert.assertEquals("text/xml", responseAttachment.getMimeType());
+
+ Map<String, String> attHeaders = responseAttachment.getHeaders();
+ Assert.assertEquals(6, attHeaders.size());
+ }
@Test
public void testInvalidXMLAttachmentContentEncryption() throws Exception {
@@ -1250,4 +1322,5 @@ public class AttachmentTest extends Abst
}
}
}
+
}