Uploaded image for project: 'Santuario'
  1. Santuario
  2. SANTUARIO-262

Invalid use of String.getBytes()

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • Java 1.4.4
    • Java 1.4.5, Java 1.5
    • Java
    • Security Level: Public (Public issues, viewable by everyone)
    • None

    Description

      Various places call String.getBytes() without any encoding. This allows the JRE to use the "plattform" encoding, which can be any (even ISO-8859-1/UTF-8 totally incompatible) encoding - there are such JVMs out there.

      This XML header implicates, that the following bytes stream is in UTF-8, therefore the header must be UTF-8 too:
      diff --git a/src/org/apache/xml/security/utils/XMLUtils.java b/src/org/apache/xml/security/utils/XMLUtils.java
      — a/src/org/apache/xml/security/utils/XMLUtils.java
      +++ b/src/org/apache/xml/security/utils/XMLUtils.java
      @@ -153,7 +153,7 @@ public class XMLUtils {

      try {
      if (addPreamble)

      { - os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes()); + os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes("UTF-8")); }

      os.write(

      RFC 2617 does not specify an encoding for the hashed password, but in practice they are in an ASCII compatible encoding (http://stackoverflow.com/questions/702629/utf-8-characters-mangled-in-http-basic-auth-username):
      diff --git a/src/org/apache/xml/security/utils/resolver/implementations/ResolverDirectHTTP.java b/src/org/apache/xml/security/utils/resolver/implementations/ResolverDirectHTTP.java
      — a/src/org/apache/xml/security/utils/resolver/implementations/ResolverDirectHTTP.java
      +++ b/src/org/apache/xml/security/utils/resolver/implementations/ResolverDirectHTTP.java
      @@ -161,7 +161,7 @@ public class ResolverDirectHTTP extends ResourceResolverSpi {

      if ((proxyUser != null) && (proxyPass != null)) {
      String password = proxyUser + ":" + proxyPass;

      • String encodedPassword = Base64.encode(password.getBytes());
        + String encodedPassword = Base64.encode(password.getBytes("ISO-8859-1"));

      // or was it Proxy-Authenticate ?
      urlConnection.setRequestProperty("Proxy-Authorization",
      @@ -190,7 +190,7 @@ public class ResolverDirectHTTP extends ResourceResolverSpi {

      String password = user + ":" + pass;
      String encodedPassword =

      • Base64.encode(password.getBytes());
        + Base64.encode(password.getBytes("ISO-8859-1"));

      // set authentication property in the http header
      urlConnection.setRequestProperty("Authorization",

      KANonce/OAEPparms are set/returned by the API as byte[] - internally they are converted to/from a string without specifing an encoding.
      Therefore the result is platform dependant. I suggest specifying UTF-8, as UTF-8 is probably used on most plattforms:
      diff --git a/src/org/apache/xml/security/encryption/XMLCipher.java b/src/org/apache/xml/security/encryption/XMLCipher.java
      — a/src/org/apache/xml/security/encryption/XMLCipher.java
      +++ b/src/org/apache/xml/security/encryption/XMLCipher.java
      @@ -976,7 +976,7 @@ public class XMLCipher

      { encryptedBytes = c.doFinal(serializedOctets.getBytes("UTF-8")); logger.debug("Expected cipher.outputSize = " + Integer.toString(c.getOutputSize( - serializedOctets.getBytes().length))); + serializedOctets.getBytes("UTF-8").length))); }

      logger.debug("Actual cipher.outputSize = " +
      Integer.toString(encryptedBytes.length));
      @@ -2042,7 +2042,11 @@ public class XMLCipher {
      EncryptionConstants.EncryptionSpecNS,
      EncryptionConstants._TAG_KA_NONCE).item(0);
      if (null != kaNonceElement) {

      • result.setKANonce(kaNonceElement.getNodeValue().getBytes());
        + try { + result.setKANonce(kaNonceElement.getNodeValue().getBytes("UTF-8")); + }

        catch(UnsupportedEncodingException e)

        { + throw new XMLEncryptionException("UTF-8 not supported", e); + }

        }
        // TODO: ///////////////////////////////////////////////////////////
        // Figure out how to make this pesky line work..
        @@ -2411,8 +2415,12 @@ public class XMLCipher {
        EncryptionConstants.EncryptionSpecNS,
        EncryptionConstants._TAG_OAEPPARAMS).item(0);
        if (null != oaepParamsElement) {

      • result.setOAEPparams(
      • oaepParamsElement.getNodeValue().getBytes());
        + try { + result.setOAEPparams( + oaepParamsElement.getNodeValue().getBytes("UTF-8")); + }

        catch(UnsupportedEncodingException e)

        { + throw new RuntimeException("UTF-8 not supported", e); + }

        }

      // TODO: Make this mess work
      @@ -2743,11 +2751,15 @@ public class XMLCipher {
      result.setAttributeNS(
      null, EncryptionConstants._ATT_ALGORITHM, algorithmURI);
      if (null != kaNonce) {

      • result.appendChild(
      • XMLUtils.createElementInEncryptionSpace(
      • _contextDocument,
      • EncryptionConstants._TAG_KA_NONCE)).appendChild(
      • _contextDocument.createTextNode(new String(kaNonce)));
        + try { + result.appendChild( + XMLUtils.createElementInEncryptionSpace( + _contextDocument, + EncryptionConstants._TAG_KA_NONCE)).appendChild( + _contextDocument.createTextNode(new String(kaNonce, "UTF-8"))); + }

        catch(UnsupportedEncodingException e)

        { + throw new RuntimeException("UTF-8 not supported", e); + }
        }
        if (!agreementMethodInformation.isEmpty()) {
        Iterator itr = agreementMethodInformation.iterator();
        @@ -3428,11 +3440,15 @@ public class XMLCipher { String.valueOf(keySize)))); }
        if (null != oaepParams) {
        - result.appendChild(
        - XMLUtils.createElementInEncryptionSpace(_contextDocument,
        - EncryptionConstants._TAG_OAEPPARAMS).appendChild(
        - _contextDocument.createTextNode(
        - new String(oaepParams))));
        + try { + result.appendChild( + XMLUtils.createElementInEncryptionSpace(_contextDocument, + EncryptionConstants._TAG_OAEPPARAMS).appendChild( + _contextDocument.createTextNode( + new String(oaepParams, "UTF-8")))); + } catch(UnsupportedEncodingException e) {+ throw new RuntimeException("UTF-8 not supported", e);+ }

        }
        Iterator itr = encryptionMethodInformation.iterator();
        while (itr.hasNext()) {

      The default encoding for an XML file is UTF-8 - make behaviour consistant for all plattforms:
      diff --git a/src/org/apache/xml/security/signature/XMLSignatureInput.java b/src/org/apache/xml/security/signature/XMLSignatureInput.java
      — a/src/org/apache/xml/security/signature/XMLSignatureInput.java
      +++ b/src/org/apache/xml/security/signature/XMLSignatureInput.java
      @@ -147,7 +147,11 @@ public class XMLSignatureInput implements Cloneable {

      • @param inputStr the input String which including XML document or node
        */
        public XMLSignatureInput(String inputStr) {
      • this(inputStr.getBytes());
        + try { + this.bytes = inputStr.getBytes("UTF-8"); + }

        catch(UnsupportedEncodingException e)

        { + throw new RuntimeException("UTF-8 not supported", e); + }

        }

      /**
      @@ -614,9 +618,9 @@ public class XMLSignatureInput implements Cloneable {
      // if a not-wellformed nodeset exists, put a container around it...
      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      • baos.write("<container>".getBytes());
        + baos.write("<container>".getBytes("UTF-8"));
        baos.write(this.getBytes());
      • baos.write("</container>".getBytes());
        + baos.write("</container>".getBytes("UTF-8"));

      byte result[] = baos.toByteArray();
      Document document = db.parse(new ByteArrayInputStream(result));

      Attachments

        1. encode-upload.patch
          7 kB
          Martin Koegler

        Activity

          People

            coheigea Colm O hEigeartaigh
            e9925248 Martin Koegler
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: