Skip to content
This repository was archived by the owner on May 26, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -661,11 +661,6 @@ private void setSignatureValueElement(byte[] bytes) {
}

String base64codedValue = XMLUtils.encodeToString(bytes);

if (base64codedValue.length() > 76 && !XMLUtils.ignoreLineBreaks()) {
base64codedValue = "\n" + base64codedValue + "\n";
}

Text t = createText(base64codedValue);
signatureValueElement.appendChild(t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.xml.security.stax.ext.stax.XMLSecEventFactory;
import org.apache.xml.security.stax.ext.stax.XMLSecNamespace;
import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
Expand Down Expand Up @@ -72,6 +73,7 @@ public void setAction(XMLSecurityConstants.Action action) {

@Override
public void init(OutputProcessorChain outputProcessorChain) throws XMLSecurityException {
XMLUtils.setThreadLocalBase64Parameters(securityProperties.getBase64LineLength(), securityProperties.getBase64LineSeparator());
outputProcessorChain.addProcessor(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@
*/
package org.apache.xml.security.stax.ext;

import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;

import java.security.Key;
import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.util.*;

import javax.xml.namespace.QName;

import org.apache.xml.security.stax.securityToken.SecurityTokenConstants;
import org.apache.xml.security.utils.XMLUtils;


/**
* Main configuration class to supply keys etc.
Expand Down Expand Up @@ -80,6 +81,8 @@ public class XMLSecurityProperties {
private QName signaturePositionQName;
private boolean signaturePositionStart = false;
private AlgorithmParameterSpec algorithmParameterSpec;
private int base64LineLength = XMLUtils.DEFAULT_BASE64_LINE_LENGTH;
private byte[] base64LineSeparator = XMLUtils.DEFAULT_BASE64_LINE_SEPARATOR;

public XMLSecurityProperties() {
}
Expand Down Expand Up @@ -120,6 +123,8 @@ protected XMLSecurityProperties(XMLSecurityProperties xmlSecurityProperties) {
this.signaturePositionQName = xmlSecurityProperties.signaturePositionQName;
this.signaturePositionStart = xmlSecurityProperties.signaturePositionStart;
this.algorithmParameterSpec = xmlSecurityProperties.algorithmParameterSpec;
this.base64LineSeparator = xmlSecurityProperties.base64LineSeparator;
this.base64LineLength = xmlSecurityProperties.base64LineLength;
}

public boolean isSignaturePositionStart() {
Expand Down Expand Up @@ -539,4 +544,44 @@ public AlgorithmParameterSpec getAlgorithmParameterSpec() {
public void setAlgorithmParameterSpec(AlgorithmParameterSpec algorithmParameterSpec) {
this.algorithmParameterSpec = algorithmParameterSpec;
}

/**
* @return the Base64 line separator, or {@code null} for no line separator.
*/
public byte[] getBase64LineSeparator() {
return base64LineSeparator;
}

/**
* Sets the Base64 line separator to the given US-ASCII bytes.
* The default is CRLF.
* For no line separator, use the combination of {@code base64LineLength = 4} and
* {@code base64LineSeparator = null}.
*
* @param base64LineSeparator a Base64 line separator, or {@code null} for no line separator.
* @see #setBase64LineLength(int)
*/
public void setBase64LineSeparator(byte[] base64LineSeparator) {
this.base64LineSeparator = base64LineSeparator;
}

/**
* @return the Base64 line length, possibly ≤ {@code 0} for no line separator.
*/
public int getBase64LineLength() {
return base64LineLength;
}

/**
* Sets the Base64 line length, which must be a multiple of 4.
* The default is 76.
* For no line separator, use the combination of {@code base64LineLength = 4} and
* {@code base64LineSeparator = null}.
*
* @param base64LineLength a Base64 line length, or {@code 0} for no line separator.
* @see #setBase64LineSeparator(byte[])
*/
public void setBase64LineLength(int base64LineLength) {
this.base64LineLength = base64LineLength;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,7 @@ public void init(OutputProcessorChain outputProcessorChain) throws XMLSecurityEx
symmetricCipher.init(Cipher.ENCRYPT_MODE, encryptionPartDef.getSymmetricKey(), parameterSpec);

characterEventGeneratorOutputStream = new CharacterEventGeneratorOutputStream();
Base64OutputStream base64EncoderStream = null;
if (XMLUtils.isIgnoreLineBreaks()) {
base64EncoderStream = new Base64OutputStream(characterEventGeneratorOutputStream, true, 0, null);
} else {
base64EncoderStream = new Base64OutputStream(characterEventGeneratorOutputStream, true);
}
Base64OutputStream base64EncoderStream = XMLUtils.createBase64OutputStream(characterEventGeneratorOutputStream, true);
base64EncoderStream.write(iv);

OutputStream outputStream = new CipherOutputStream(base64EncoderStream, symmetricCipher);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,6 @@ public void addBase64Element(byte[] bytes, String localname) {
el.appendChild(text);

appendSelf(el);
if (!XMLUtils.ignoreLineBreaks()) {
appendSelf(createText("\n"));
}
}
}

Expand All @@ -320,9 +317,7 @@ public void addTextElement(String text, String localname) {
*/
public void addBase64Text(byte[] bytes) {
if (bytes != null) {
Text t = XMLUtils.ignoreLineBreaks()
? createText(XMLUtils.encodeToString(bytes))
: createText("\n" + XMLUtils.encodeToString(bytes) + "\n");
Text t = createText(XMLUtils.encodeToString(bytes));
appendSelf(t);
}
}
Expand Down
51 changes: 47 additions & 4 deletions src/main/java/org/apache/xml/security/utils/XMLUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import java.util.List;
import java.util.Set;

import org.apache.commons.codec.binary.Base64OutputStream;
import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
import org.apache.xml.security.parser.XMLParser;
import org.apache.xml.security.parser.XMLParserException;
import org.apache.xml.security.parser.XMLParserImpl;
import org.apache.xml.security.stax.impl.util.KeyValue;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
Expand Down Expand Up @@ -77,6 +79,12 @@ public final class XMLUtils {
private static volatile String xencPrefix = "xenc";
private static volatile String xenc11Prefix = "xenc11";

public static final int DEFAULT_BASE64_LINE_LENGTH = 76;
public static final byte[] DEFAULT_BASE64_LINE_SEPARATOR = {13, 10};
private static final KeyValue<Integer, byte[]> DEFAULT_BASE64_PARAMETERS = new KeyValue<>(DEFAULT_BASE64_LINE_LENGTH, DEFAULT_BASE64_LINE_SEPARATOR);
private static final KeyValue<Integer, byte[]> IGNORE_LINE_BREAKS_BASE64_PARAMETERS = new KeyValue<>(0, null);
private static final ThreadLocal<KeyValue<Integer, byte[]>> BASE64_PARAMETERS = ThreadLocal.withInitial(() -> DEFAULT_BASE64_PARAMETERS);

/**
* Constructor XMLUtils
*
Expand Down Expand Up @@ -525,10 +533,20 @@ public static void addReturnBeforeChild(Element e, Node child) {
}

public static String encodeToString(byte[] bytes) {
if (ignoreLineBreaks) {
KeyValue<Integer, byte[]> base64Parameters = getEffectiveBase64Parameters();
int lineLength = base64Parameters.getKey();
byte[] lineSeparator = base64Parameters.getValue();
if (lineSeparator == null) {
return Base64.getEncoder().encodeToString(bytes);
}
return Base64.getMimeEncoder().encodeToString(bytes);
return Base64.getMimeEncoder(lineLength, lineSeparator).encodeToString(bytes);
}

private static KeyValue<Integer, byte[]> getEffectiveBase64Parameters() {
if (ignoreLineBreaks) {
return IGNORE_LINE_BREAKS_BASE64_PARAMETERS;
}
return BASE64_PARAMETERS.get();
}

public static byte[] decode(String encodedString) {
Expand All @@ -539,10 +557,24 @@ public static byte[] decode(byte[] encodedBytes) {
return Base64.getMimeDecoder().decode(encodedBytes);
}

@Deprecated
public static boolean isIgnoreLineBreaks() {
return ignoreLineBreaks;
}

/**
* Creates a new Base64 output stream around a given output stream, using the thread-local Base64 parameters
* which were configured on this thread using {@link #setThreadLocalBase64Parameters(int, byte[])}.
*
* @param out The delegate output stream, which must not be {@code null}.
* @param doEncode {@code true} to encode, {@code false} to decode Base64.
* @return A new Base64 output stream, never {@code null}.
*/
public static Base64OutputStream createBase64OutputStream(OutputStream out, boolean doEncode) {
KeyValue<Integer, byte[]> base64Parameters = getEffectiveBase64Parameters();
return new Base64OutputStream(out, true, base64Parameters.getKey(), base64Parameters.getValue());
}

/**
* Method convertNodelistToSet
*
Expand Down Expand Up @@ -854,6 +886,7 @@ public static boolean isDescendantOrSelf(Node ctx, Node descendantOrSelf) {
}
}

@Deprecated
public static boolean ignoreLineBreaks() {
return ignoreLineBreaks;
}
Expand Down Expand Up @@ -1050,6 +1083,16 @@ public static byte[] getBytes(BigInteger big, int bitlen) {
return resizedBytes;
}



/**
* Sets the thread-local Base64 parameters that will be used by this thread in further calls to
* {@link #encodeToString(byte[])} and {@link #createBase64OutputStream(OutputStream, boolean)}.
* Any thread-local parameters set here will be overruled (have no effect) when the system property
* {@code "org.apache.xml.security.ignoreLineBreaks"} is set.
*
* @param lineLength a line length, 76 by default. Use 0 for no line separator.
* @param lineSeparator a line separator, CRLF {@code {13, 10}} by default. Use {@code null} for no line separator.
*/
public static void setThreadLocalBase64Parameters(int lineLength, byte[] lineSeparator) {
BASE64_PARAMETERS.set(new KeyValue<>(lineLength, lineSeparator));
}
}
Loading