This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch coheigea/encrypted-headers in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git
commit cef14ab9302a561de3c62977c9417748152317e9 Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Mon Sep 14 07:51:59 2026 +0100 Make sure for Attachment-Complete the mime type is read from the encrypted header --- .../org/apache/wss4j/dom/util/EncryptionUtils.java | 15 ++- .../apache/wss4j/dom/message/AttachmentTest.java | 113 ++++++++++++++++- .../processor/input/DecryptInputProcessor.java | 14 ++- .../org/apache/wss4j/stax/test/AttachmentTest.java | 139 ++++++++++++++++++++- 4 files changed, 267 insertions(+), 14 deletions(-) diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java index 9240f725f..231615187 100644 --- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java +++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/util/EncryptionUtils.java @@ -53,7 +53,9 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.security.NoSuchAlgorithmException; +import java.util.HashMap; import java.util.List; +import java.util.Map; public final class EncryptionUtils { @@ -352,8 +354,17 @@ public final class EncryptionUtils { String typeStr = encData.getAttributeNS(null, "Type"); if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(typeStr)) { - AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders( - resultAttachment.getHeaders(), attachmentInputStream); + // Attachment-Complete: the profile-listed MIME headers (and hence the + // delivered MIME type) must come from the encrypted header block, not + // from the unauthenticated @MimeType attribute or cleartext part headers. + Map<String, String> protectedHeaders = new HashMap<>(); + AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(protectedHeaders, attachmentInputStream); + String contentType = protectedHeaders.get(AttachmentUtils.MIME_HEADER_CONTENT_TYPE); + if (contentType == null) { + throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK); + } + resultAttachment.setMimeType(contentType); + resultAttachment.addHeaders(protectedHeaders); } AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback(); diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java index 9eab6c6fd..f68cf79fd 100644 --- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java +++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/AttachmentTest.java @@ -725,7 +725,7 @@ public class AttachmentTest { byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> attHeaders = responseAttachment.getHeaders(); assertEquals(6, attHeaders.size()); @@ -785,6 +785,109 @@ public class AttachmentTest { assertEquals("text/xml", responseAttachment.getMimeType()); } + // Regression test for CWE-345: a wire attacker cannot forge the delivered MIME type of an + // Attachment-Complete encrypted attachment by tampering with the unauthenticated + // xenc:EncryptedData/@MimeType attribute - the MIME type must be sourced from the + // encrypted (protected) Content-Type header instead. + @Test + public void testXMLAttachmentCompleteEncryptionTamperedMimeTypeAttributeIgnored() throws Exception { + Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG); + WSSecHeader secHeader = new WSSecHeader(doc); + secHeader.insertSecurityHeader(); + + WSSecEncrypt encrypt = new WSSecEncrypt(secHeader); + encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security"); + encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); + + encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content")); + encrypt.getParts().add(new WSEncryptionPart("cid:Attachments", "Element")); + + 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(); + + KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128); + SecretKey symmetricKey = keyGen.generateKey(); + Document encryptedDoc = encrypt.build(crypto, symmetricKey); + + // Simulate a wire attacker rewriting the unauthenticated @MimeType attribute + NodeList encDatas = encryptedDoc.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData"); + Element attachmentEncData = null; + for (int i = 0; i < encDatas.getLength(); i++) { + Element encData = (Element) encDatas.item(i); + if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(encData.getAttributeNS(null, "Type"))) { + attachmentEncData = encData; + break; + } + } + assertFalse(attachmentEncData == null); + attachmentEncData.setAttributeNS(null, "MimeType", "application/malicious"); + + if (LOG.isDebugEnabled()) { + String outputString = XMLUtils.prettyDocumentToString(encryptedDoc); + LOG.debug(outputString); + } + + attachmentCallbackHandler = new AttachmentCallbackHandler(encryptedAttachments); + verify(encryptedDoc, attachmentCallbackHandler); + + assertFalse(attachmentCallbackHandler.getResponseAttachments().isEmpty()); + Attachment responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(0); + + byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); + assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); + } + + // Regression test for CWE-345: if the protected header block (inside the ciphertext) does + // not contain a Content-Type header, decryption of an Attachment-Complete attachment must + // fail closed rather than falling back to the unauthenticated @MimeType attribute. + @Test + public void testXMLAttachmentCompleteEncryptionMissingProtectedContentType() throws Exception { + Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG); + WSSecHeader secHeader = new WSSecHeader(doc); + secHeader.insertSecurityHeader(); + + WSSecEncrypt encrypt = new WSSecEncrypt(secHeader); + encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security"); + encrypt.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); + + encrypt.getParts().add(new WSEncryptionPart("Body", "http://schemas.xmlsoap.org/soap/envelope/", "Content")); + encrypt.getParts().add(new WSEncryptionPart("cid:Attachments", "Element")); + + String attachmentId = UUID.randomUUID().toString(); + final Attachment attachment = new Attachment(); + attachment.setMimeType("text/xml"); + Map<String, String> headers = getHeaders(attachmentId); + headers.remove(AttachmentUtils.MIME_HEADER_CONTENT_TYPE); + attachment.addHeaders(headers); + 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(); + + KeyGenerator keyGen = KeyUtils.getKeyGenerator(WSConstants.AES_128); + SecretKey symmetricKey = keyGen.generateKey(); + Document encryptedDoc = encrypt.build(crypto, symmetricKey); + + final AttachmentCallbackHandler finalAttachmentCallbackHandler = + new AttachmentCallbackHandler(encryptedAttachments); + WSSecurityException exception = org.junit.jupiter.api.Assertions.assertThrows( + WSSecurityException.class, () -> verify(encryptedDoc, finalAttachmentCallbackHandler)); + assertEquals(WSSecurityException.ErrorCode.FAILED_CHECK, exception.getErrorCode()); + } + @Test public void testMultipleAttachmentCompleteEncryption() throws Exception { Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG); @@ -835,14 +938,14 @@ public class AttachmentTest { byte[] attachment1Bytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachment1Bytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> att1Headers = responseAttachment.getHeaders(); assertEquals(6, att1Headers.size()); responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(1); byte[] attachment2Bytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachment2Bytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/plain", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> att2Headers = responseAttachment.getHeaders(); assertEquals(6, att2Headers.size()); @@ -909,7 +1012,7 @@ public class AttachmentTest { byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> attHeaders = responseAttachment.getHeaders(); assertEquals(6, attHeaders.size()); @@ -1077,7 +1180,7 @@ public class AttachmentTest { byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> attHeaders = responseAttachment.getHeaders(); assertEquals(6, attHeaders.size()); diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java index 709d8ca5a..9b8b540ac 100644 --- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java +++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/input/DecryptInputProcessor.java @@ -24,6 +24,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.Key; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -364,12 +365,21 @@ public class DecryptInputProcessor extends AbstractDecryptInputProcessor { resultAttachment.addHeaders(attachment.getHeaders()); if (WSSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(encryptedDataType.getType())) { + // Attachment-Complete: the profile-listed MIME headers (and hence the + // delivered MIME type) must come from the encrypted header block, not + // from the unauthenticated MimeType attribute or cleartext part headers. + Map<String, String> protectedHeaders = new HashMap<>(); try { - AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders( - resultAttachment.getHeaders(), attachmentInputStream); + AttachmentUtils.readAndReplaceEncryptedAttachmentHeaders(protectedHeaders, attachmentInputStream); } catch (IOException e) { throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY, e); } + String contentType = protectedHeaders.get(AttachmentUtils.MIME_HEADER_CONTENT_TYPE); + if (contentType == null) { + throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY); + } + resultAttachment.setMimeType(contentType); + resultAttachment.addHeaders(protectedHeaders); } AttachmentResultCallback attachmentResultCallback = new AttachmentResultCallback(); diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java index 62d21dd8c..59cd7a7e8 100644 --- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java +++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/AttachmentTest.java @@ -784,7 +784,7 @@ public class AttachmentTest extends AbstractTestBase { Attachment responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(0); byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> attHeaders = responseAttachment.getHeaders(); assertEquals(6, attHeaders.size()); @@ -870,6 +870,135 @@ public class AttachmentTest extends AbstractTestBase { } } + // Regression test for CWE-345: a wire attacker cannot forge the delivered MIME type of an + // Attachment-Complete encrypted attachment by tampering with the unauthenticated + // xenc:EncryptedData/@MimeType attribute - the MIME type must be sourced from the + // encrypted (protected) Content-Type header instead. + @Test + public void testXMLAttachmentCompleteEncryptionTamperedMimeTypeAttributeIgnored() 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<>(); + actions.add(WSSConstants.ENCRYPTION); + 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.Element)); + securityProperties.setAttachmentCallbackHandler(attachmentCallbackHandler); + + 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(); + } + + // Simulate a wire attacker rewriting the unauthenticated @MimeType attribute + Document securedDoc = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())); + NodeList encDatas = securedDoc.getElementsByTagNameNS(WSConstants.ENC_NS, "EncryptedData"); + Element attachmentEncData = null; + for (int i = 0; i < encDatas.getLength(); i++) { + Element encData = (Element) encDatas.item(i); + if (WSConstants.SWA_ATTACHMENT_ENCRYPTED_DATA_TYPE_COMPLETE.equals(encData.getAttributeNS(null, "Type"))) { + attachmentEncData = encData; + break; + } + } + assertFalse(attachmentEncData == null); + attachmentEncData.setAttributeNS(null, "MimeType", "application/malicious"); + + ByteArrayOutputStream tamperedBaos = new ByteArrayOutputStream(); + javax.xml.transform.TransformerFactory.newInstance().newTransformer() + .transform(new DOMSource(securedDoc), new StreamResult(tamperedBaos)); + + 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(tamperedBaos.toByteArray()))); + StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader); + } + + assertFalse(attachmentCallbackHandler.getResponseAttachments().isEmpty()); + Attachment responseAttachment = attachmentCallbackHandler.getResponseAttachments().get(0); + byte[] attachmentBytes = readInputStream(responseAttachment.getSourceStream()); + assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); + } + + // Regression test for CWE-345: if the protected header block (inside the ciphertext) does + // not contain a Content-Type header, decryption of an Attachment-Complete attachment must + // fail closed rather than falling back to the unauthenticated MimeType attribute. + @Test + public void testXMLAttachmentCompleteEncryptionMissingProtectedContentType() throws Exception { + + final String attachmentId = UUID.randomUUID().toString(); + final Attachment attachment = new Attachment(); + attachment.setMimeType("text/xml"); + Map<String, String> headers = getHeaders(attachmentId); + headers.remove(AttachmentUtils.MIME_HEADER_CONTENT_TYPE); + attachment.addHeaders(headers); + 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<>(); + actions.add(WSSConstants.ENCRYPTION); + 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.Element)); + securityProperties.setAttachmentCallbackHandler(attachmentCallbackHandler); + + 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(); + } + + 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()))); + try { + StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader); + fail("Expected a WSSecurityException due to the missing protected Content-Type header"); + } catch (XMLStreamException e) { + assertTrue(e.getCause() instanceof WSSecurityException); + assertEquals(WSSecurityException.ErrorCode.INVALID_SECURITY, ((WSSecurityException) e.getCause()).getErrorCode()); + } + } + @Test public void testMultipleAttachmentCompleteEncryption() throws Exception { @@ -928,7 +1057,7 @@ public class AttachmentTest extends AbstractTestBase { byte[] attachment1Bytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachment1Bytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> att1Headers = responseAttachment.getHeaders(); assertEquals(6, att1Headers.size()); @@ -936,7 +1065,7 @@ public class AttachmentTest extends AbstractTestBase { byte[] attachment2Bytes = readInputStream(responseAttachment.getSourceStream()); assertTrue(Arrays.equals(attachment2Bytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/plain", responseAttachment.getMimeType()); + assertEquals("text/xml; charset=UTF-8", responseAttachment.getMimeType()); Map<String, String> att2Headers = responseAttachment.getHeaders(); assertEquals(6, att2Headers.size()); } @@ -1036,7 +1165,7 @@ public class AttachmentTest extends AbstractTestBase { byte[] attachmentBytes = readInputStream(attachment[0].getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", attachment[0].getMimeType()); + assertEquals("text/xml; charset=UTF-8", attachment[0].getMimeType()); Map<String, String> attHeaders = attachment[0].getHeaders(); assertEquals(6, attHeaders.size()); @@ -1230,7 +1359,7 @@ public class AttachmentTest extends AbstractTestBase { byte[] attachmentBytes = readInputStream(attachment[0].getSourceStream()); assertTrue(Arrays.equals(attachmentBytes, SOAPUtil.SAMPLE_SOAP_MSG.getBytes(StandardCharsets.UTF_8))); - assertEquals("text/xml", attachment[0].getMimeType()); + assertEquals("text/xml; charset=UTF-8", attachment[0].getMimeType()); Map<String, String> attHeaders = attachment[0].getHeaders(); assertEquals(6, attHeaders.size());
