You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2019/05/09 16:48:36 UTC

[qpid-jms-amqp-0-x] 02/03: QPID-8282: [JMS AMQP 0-x] Remove use of javax.xml.bind.DatatypeConverter

This is an automated email from the ASF dual-hosted git repository.

orudyy pushed a commit to branch 6.3.x
in repository https://gitbox.apache.org/repos/asf/qpid-jms-amqp-0-x.git

commit 6f1d83e1a5b2c66bce338519208b96b5ec7eb800
Author: Alex Rudyy <or...@apache.org>
AuthorDate: Thu May 9 17:45:43 2019 +0100

    QPID-8282: [JMS AMQP 0-x] Remove use of javax.xml.bind.DatatypeConverter
---
 .../security/scram/AbstractScramSaslClient.java    |   6 +-
 .../src/main/java/org/apache/qpid/util/Base64.java | 202 +++++++++++++++++++++
 .../java/org/apache/qpid/util/DataUrlUtils.java    |  32 ----
 .../main/java/org/apache/qpid/util/Strings.java    |   4 +-
 .../network/security/ssl/SSLUtilTest.java          |  31 ++--
 .../test/java/org/apache/qpid/util/Base64Test.java | 118 ++++++++++++
 6 files changed, 340 insertions(+), 53 deletions(-)

diff --git a/client/src/main/java/org/apache/qpid/client/security/scram/AbstractScramSaslClient.java b/client/src/main/java/org/apache/qpid/client/security/scram/AbstractScramSaslClient.java
index 6c23fd0..b32115d 100644
--- a/client/src/main/java/org/apache/qpid/client/security/scram/AbstractScramSaslClient.java
+++ b/client/src/main/java/org/apache/qpid/client/security/scram/AbstractScramSaslClient.java
@@ -37,8 +37,8 @@ import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.sasl.SaslClient;
 import javax.security.sasl.SaslException;
-import javax.xml.bind.DatatypeConverter;
 
+import org.apache.qpid.util.Base64;
 import org.apache.qpid.util.Strings;
 
 public abstract class AbstractScramSaslClient implements SaslClient
@@ -194,7 +194,7 @@ public abstract class AbstractScramSaslClient implements SaslClient
 
 
             String clientFinalMessageWithoutProof =
-                    "c=" + DatatypeConverter.printBase64Binary(GS2_HEADER.getBytes(ASCII))
+                    "c=" + Base64.encode(GS2_HEADER.getBytes(ASCII))
                     + ",r=" + _serverNonce;
 
             String authMessage = _clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof;
@@ -213,7 +213,7 @@ public abstract class AbstractScramSaslClient implements SaslClient
             _serverSignature = computeHmac(serverKey, authMessage);
 
             String finalMessageWithProof = clientFinalMessageWithoutProof
-                                           + ",p=" + DatatypeConverter.printBase64Binary(clientProof);
+                                           + ",p=" + Base64.encode(clientProof);
             return finalMessageWithProof.getBytes();
         }
         catch (UnsupportedEncodingException e)
diff --git a/client/src/main/java/org/apache/qpid/util/Base64.java b/client/src/main/java/org/apache/qpid/util/Base64.java
new file mode 100644
index 0000000..7b14533
--- /dev/null
+++ b/client/src/main/java/org/apache/qpid/util/Base64.java
@@ -0,0 +1,202 @@
+/*
+ *
+ * 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.qpid.util;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+
+public class Base64
+{
+    private static final char PAD = '=';
+    private static final char[] BASE64_ENCODE =
+            {
+                    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+                    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+                    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+                    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+            };
+    private static final int MASK_8BITS = 0xff;
+    private static final int MASK_6BITS = 0x3f;
+    private static final int[] BASE64_DECODE =
+            {
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
+                    55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2,
+                    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+                    20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+                    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+                    48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+                    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+            };
+
+    public static String encode(byte[] data)
+    {
+        final StringBuilder encoded = new StringBuilder(4 * ((data.length + 2) / 3));
+        final int triples = data.length / 3 * 3;
+        int i = 0;
+        for (; i < triples; i += 3)
+        {
+            final int bits =
+                    (data[i] & MASK_8BITS) << 16 | (data[i + 1] & MASK_8BITS) << 8 | (data[i + 2] & MASK_8BITS);
+            encoded.append(BASE64_ENCODE[(bits >>> 18) & MASK_6BITS]);
+            encoded.append(BASE64_ENCODE[(bits >>> 12) & MASK_6BITS]);
+            encoded.append(BASE64_ENCODE[(bits >>> 6) & MASK_6BITS]);
+            encoded.append(BASE64_ENCODE[bits & MASK_6BITS]);
+        }
+
+        if (i < data.length)
+        {
+            final int remaining1 = data[i] & MASK_8BITS;
+            encoded.append(BASE64_ENCODE[remaining1 >> 2]);
+            if (i == data.length - 1)
+            {
+                encoded.append(BASE64_ENCODE[(remaining1 << 4) & MASK_6BITS]);
+                encoded.append(PAD);
+                encoded.append(PAD);
+            }
+            else
+            {
+                final int remaining2 = data[i + 1] & 0xff;
+                encoded.append(BASE64_ENCODE[(remaining1 << 4) & MASK_6BITS | (remaining2 >> 4)]);
+                encoded.append(BASE64_ENCODE[(remaining2 << 2) & MASK_6BITS]);
+                encoded.append(PAD);
+            }
+        }
+
+        return encoded.toString();
+    }
+
+    public static byte[] decode(String data)
+    {
+        final byte[] bytes = data.getBytes(StandardCharsets.ISO_8859_1);
+        final int decodeSize =
+                3 * ((bytes.length + 3) / 4) - ((bytes.length & 0x3) != 0 ? 4 - (bytes.length & 0x3) : 0);
+        final ByteArrayOutputStream buffer = new ByteArrayOutputStream(decodeSize);
+
+        for (int i = 0; i < bytes.length; i += 4)
+        {
+            int b = 0;
+            int byteCounter = 0;
+            if (check(bytes, i, byteCounter))
+            {
+                b = get(bytes, i, byteCounter)  << 18;
+                byteCounter++;
+                if (check(bytes, i, byteCounter))
+                {
+                    b = b | (get(bytes, i, byteCounter) << 12);
+                    byteCounter++;
+                    if (check(bytes, i, byteCounter))
+                    {
+                        b = b | (get(bytes, i, byteCounter) << 6);
+                        byteCounter++;
+                        if (check(bytes, i, byteCounter))
+                        {
+                            b = b | get(bytes, i, byteCounter);
+                            byteCounter++;
+                        }
+                    }
+                }
+            }
+
+            if (byteCounter == 4)
+            {
+                buffer.write((byte) (b >> 16) & MASK_8BITS);
+                buffer.write((byte) (b >> 8) & MASK_8BITS);
+                buffer.write((byte) (b) & MASK_8BITS);
+            }
+            else if (byteCounter == 3)
+            {
+                buffer.write((byte) (b >> 16) & MASK_8BITS);
+                buffer.write((byte) (b >> 8 ) & MASK_8BITS);
+            }
+            else if (byteCounter == 2)
+            {
+                buffer.write((byte) (b >> 16) & MASK_8BITS);
+            }
+            else
+            {
+                throw new IllegalArgumentException("Malformed data");
+            }
+        }
+        return buffer.toByteArray();
+    }
+
+    private static int get(byte[] bytes, int index, int shift)
+    {
+        final int i = index + shift;
+        if (i>= 0 && i < bytes.length)
+        {
+            int b = bytes[i] & MASK_8BITS;
+            if (b == PAD)
+            {
+                throw new IllegalArgumentException(String.format("Unexpected padding detected at position %d", i));
+            }
+            int d = BASE64_DECODE[b];
+            if (d < 0)
+            {
+                throw new IllegalArgumentException(String.format("Unexpected character '%x' at position %d", b, i));
+            }
+            return d & MASK_8BITS;
+        }
+        throw new IllegalArgumentException("Unexpected index");
+    }
+
+    private static boolean check(byte[] bytes, int index, int shift)
+    {
+        final int i = index + shift;
+        if (i < bytes.length)
+        {
+            final int b = bytes[i] & MASK_8BITS;
+            if (b == PAD)
+            {
+                if (shift == 0)
+                {
+                    throw new IllegalArgumentException(String.format("Unexpected padding detected at position %d", i));
+                }
+                else if (shift == 2
+                         && ((i == bytes.length - 2 && bytes[i + 1] != PAD)
+                             || (i == bytes.length - 1 && bytes[i - 1] != PAD)))
+                {
+                    throw new IllegalArgumentException("Missing padding");
+                }
+                else if (shift != 2 && i < bytes.length - 1)
+                {
+                    throw new IllegalArgumentException(String.format("Unexpected padding detected at position %d", i));
+                }
+                return false;
+            }
+            else if (BASE64_DECODE[b] < 0)
+            {
+                throw new IllegalArgumentException(String.format("Unexpected character '%x' at position %d", b, i));
+            }
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/client/src/main/java/org/apache/qpid/util/DataUrlUtils.java b/client/src/main/java/org/apache/qpid/util/DataUrlUtils.java
deleted file mode 100644
index 16c5012..0000000
--- a/client/src/main/java/org/apache/qpid/util/DataUrlUtils.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.qpid.util;
-
-import javax.xml.bind.DatatypeConverter;
-
-public class DataUrlUtils
-{
-    public static String getDataUrlForBytes(final byte[] bytes)
-    {
-        StringBuilder inlineURL = new StringBuilder("data:;base64,");
-        inlineURL.append(DatatypeConverter.printBase64Binary(bytes));
-        return inlineURL.toString();
-    }
-}
diff --git a/client/src/main/java/org/apache/qpid/util/Strings.java b/client/src/main/java/org/apache/qpid/util/Strings.java
index b94ac11..b491d0d 100644
--- a/client/src/main/java/org/apache/qpid/util/Strings.java
+++ b/client/src/main/java/org/apache/qpid/util/Strings.java
@@ -33,8 +33,6 @@ import java.util.Stack;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.xml.bind.DatatypeConverter;
-
 
 /**
  * Strings
@@ -135,7 +133,7 @@ public final class Strings
             throw new IllegalArgumentException("Cannot convert string '"+ base64String+ "'to a byte[] - it does not appear to be base64 data");
         }
 
-        return DatatypeConverter.parseBase64Binary(base64String);
+        return Base64.decode(base64String);
     }
 
     public static interface Resolver
diff --git a/client/src/test/java/org/apache/qpid/transport/network/security/ssl/SSLUtilTest.java b/client/src/test/java/org/apache/qpid/transport/network/security/ssl/SSLUtilTest.java
index e547c20..1db8725 100644
--- a/client/src/test/java/org/apache/qpid/transport/network/security/ssl/SSLUtilTest.java
+++ b/client/src/test/java/org/apache/qpid/transport/network/security/ssl/SSLUtilTest.java
@@ -32,10 +32,11 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLEngineResult;
 import javax.net.ssl.TrustManagerFactory;
-import javax.xml.bind.DatatypeConverter;
+
 
 import org.apache.qpid.test.utils.QpidTestCase;
 import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.util.Base64;
 
 public class SSLUtilTest extends QpidTestCase
 {
@@ -320,7 +321,7 @@ public class SSLUtilTest extends QpidTestCase
         return clientEngine;
     }
 
-    private static byte[] TRUSTSTORE = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAANAAAAAgAPa2V5c3RvcmUyLWFsaWFzAAABVutBZIkABVguNTA5AAAGHzCCBhsw"
+    private static byte[] TRUSTSTORE = Base64.decode("/u3+7QAAAAIAAAANAAAAAgAPa2V5c3RvcmUyLWFsaWFzAAABVutBZIkABVguNTA5AAAGHzCCBhsw"
                                                                            +"ggQDoAMCAQICCQCrOvhXap7bYTANBgkqhkiG9w0BAQUFADBcMQswCQYDVQQGEwJVUzEQMA4GA1UE"
                                                                            +"CBMHcHJpdmF0ZTERMA8GA1UEBxMIcHJvdmluY2UxDTALBgNVBAoTBGNpdHkxGTAXBgNVBAMTEGFt"
                                                                            +"cXAuZXhhbXBsZS5jb20wHhcNMTYwOTAyMTQxNTE1WhcNMjYwNzEyMTQxNTE1WjBcMQswCQYDVQQG"
@@ -689,7 +690,7 @@ public class SSLUtilTest extends QpidTestCase
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp.example.com
 
-    private static byte[] KEYSTORE_1 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQOSYAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_1 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQOSYAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJbpiFtanggVFjHUoiw5SBLNdnZpIbHao5oqJ6X7ra2IYE5pAYc8lA00P8GAt8ZfVFU/r1"
                                                                            +"iSj26gWQzbnOqgICfLEe1UNPzMmutxCKHUkZIqlXgvc/Ga7eNhZFxLYoJcjSHcH3rXjfiLihR7fi"
                                                                            +"ig7OavC88c3qnZld9SHcVSGquUQf65UlMDcLz5ro4JCWojxP0HqmaysTfVW0qGNSeGZcLM4F8siO"
@@ -766,7 +767,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=amqp.example.com
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp1.example.com
-    private static byte[] KEYSTORE_2 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQOxJAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_2 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQOxJAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJb7B1Wn+7tr/UMY9U5S1jldHUBVs55D+bq9mEnI+15JSYH0HOgTeG2GHUMFg5s+P9sMX6"
                                                                            +"OQL5awZrIrj/IBm3H1JGYvQ90tGNZpbIyPxx912QRfM9qwx4x9q8/EX4C4HqUYzHPrwhtdauGuM7"
                                                                            +"0v2QMKG6ZKTb9f8VSXhhrntVA0V3hmHpFozpIm1vFjFHQvKwOk0H/ig0ZBCPEBGT447lSn8DyM42"
@@ -844,7 +845,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=amqp.example.com
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp1.example.com, DNS:amqp2.example.com
-    private static byte[] KEYSTORE_3 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQPpoAAAJiDCCCYQwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_3 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQPpoAAAJiDCCCYQwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJcMesQe4dg1MYgHKVJCEUzCTpgJu3iTGwbnLOOhraGFn02YXh0Axbwws2hD0SH8XYF4h3"
                                                                            +"pVI+YbXCWHiQzzn0/5mbSEAQcNBqPR+UTQULdDpI5jGWlf3oPRdqRLP/zAXzgb5N2bmbtdLQ02NK"
                                                                            +"pvhRHNnLWmTBUokkBRUkh8kiUH3Xu8qIaJbK7ge0yglerFOK6kzic1PZwfvdzsoBxgb0CTHfzOK2"
@@ -923,7 +924,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=amqp.example.com
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp1.example.com, DNS:*.example.com
-    private static byte[] KEYSTORE_4 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQP7OAAAJiDCCCYQwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_4 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQP7OAAAJiDCCCYQwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJcM11nToM9HiebwkA/+F9HTYV7bjlRO04+J09z8yiaerv82Iik4bIZjsl2V8IPIjUACxM"
                                                                            +"7ToGh+WiELoTTDtcjTrfAxk8CM1buiugzN8do8/VwTHpIyDmKQoEY+54Ma2S1r52mqpl5B4sJT3U"
                                                                            +"25g1ahx23Ytwti9TNKf5NGDLuKrVzbidoYNc2p8yFQe7gaktKVSmIyaZOjRrwm9quoopKNdB/73k"
@@ -1002,7 +1003,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=*.example.com
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp1.example.net, DNS:*.org
-    private static byte[] KEYSTORE_5 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQQX7AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_5 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQQX7AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJbhJZvU/boEm92Z+W8kebBumXt/3K9qwGBIntSvmLduW4HIVcQ6+W3Q5Kbd7JiQbAut7b"
                                                                            +"jicmydwnibrk7DimQAfCGsqud2ywj6eZwkXXa5ZNbuQKUQxP0me82awrQHYBkSaHJv2kwSdTQU7O"
                                                                            +"la3CoRhtps1pInt00GjVbBEtBERcUrCVG7GtLbxKaOnDEaixK/ewS+7FnG83SfjEKCc5yso/aKaG"
@@ -1080,7 +1081,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=amqp.example.com
     //            X509v3 Subject Alternative Name:
     //                DNS:*
-    private static byte[] KEYSTORE_6 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQQ/fAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_6 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQQ/fAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJb3fs2zcPchqg7CgqHGxwNehB9UogWD1nbgdXd5RtWrIg8Gifp05miLKUjPxQp1/L0D36"
                                                                            +"XVyqVO7hINZZE3wb9p7PR+bzo7DWMuPZ7+2YzcX2fSLRLcT2h88L3wHjblYH19Bk19/H44JI6j2H"
                                                                            +"NwVXbAJRAR/6gQJWDewRmkDmSwbiLZ+0pYGz6P5lucXWFt8T2h+pAqz0Ui400RxrpM49AadvCK6v"
@@ -1157,7 +1158,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=*
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp.example.org, DNS:amqp1.example.org, DNS:amqp2.example.org
-    private static byte[] KEYSTORE_7 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQRyQAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_7 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQRyQAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJb+vOaA9ERF3UR5QStjyDSVyHQneIIdOijZfbIxzvUHqZLXOZ6g03xiRs0mJ/RPgPPXo2"
                                                                            +"EzR8U19YIljUdVw37yro4LpsH1buo+tzPC5p6PhLS28jaMCsLWKpnabAQfWptCgjSoOvKJ26XdxB"
                                                                            +"NVJVPrBBscwP+ytgcwJ1wsAkkvOGazygincn7MJiBUNkd7HpJ2VjueeqgttwMKFKFifFdE390Has"
@@ -1234,7 +1235,7 @@ public class SSLUtilTest extends QpidTestCase
     //        Subject: C=US, ST=private, L=province, O=city, CN=*
     //            X509v3 Subject Alternative Name:
     //                DNS:amqp.example.org, DNS:example.org
-    private static byte[] KEYSTORE_8 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQTD+AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_8 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQTD+AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJbjpQpyUW3ZmF8P1gwRce6uQCTe3hN+4Mft8FrnZRnv4kx0YW1cMRfyig89HYONM8KsS0"
                                                                            +"BMoqT3xa5iCQ/oHBymb82OC4YWSAomHFNT2JoDWelNQfnMqjGt3UETBP7g06+ulDjEA5+DAsdcxy"
                                                                            +"Jtt3Tpfjpe0s0I5jY3blGPV8yQDCNkahhqET6Jvg3PJYsHBE3ssPkTNKI5rMjzbt36pai/HlmjdU"
@@ -1308,7 +1309,7 @@ public class SSLUtilTest extends QpidTestCase
                                                                           );
 
     //        Subject: C=US, ST=private, L=province, O=city, CN=amqp.example.org
-    private static byte[] KEYSTORE_9 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQTqYAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_9 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQTqYAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                            +"AQUABIIJbnd59Bys8FgK8FREpm5Vsbq0uIbSE3nZFBNRVaYostRXeNA1fJok01wXBqrf05NfelKj"
                                                                            +"+ttyFHwE8AKzLfF6vDusoEH4r3HUaQWoWMiOfCzljxjtrr/eQQFx92dX5+Z17BH4+92HZUzVPbSg"
                                                                            +"31eoaZ24lTO7X8XXq0a43mnC/m3Vs9K590oCfXSDRsx8Ucr0VbUjR8jyLMxE6f4/cxBIhg2PTzCi"
@@ -1383,7 +1384,7 @@ public class SSLUtilTest extends QpidTestCase
                                                                           );
 
     //        Subject: C=US, ST=private, L=province, O=city, CN=*.example.org
-    private static byte[] KEYSTORE_10 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQT/DAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_10 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQT/DAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
                                                                             +"AQUABIIJb5zVRh9eulhVb9JI6dbHdLyWN/AwqIfERSIFCr/n0jn7MvWHPiMYQtYtzv+z7bkNVTv+"
                                                                             +"Uec6wagRxHGu4bjcVuIs6zX2lUrO0L5rN3Jwcbu6bpMIxw7sAPw4/k7Kgvf1ddSOIn4WGiHrJf8G"
                                                                             +"WvMy3rs9dnxSe8Z+TvUBn3yfFemMRpwnfGn6TuJsdBfzU/bm9dX8RBjMmwQgyHqVgzuvJtAkaQb8"
@@ -1457,7 +1458,7 @@ public class SSLUtilTest extends QpidTestCase
                                                                            );
 
     //        Subject: C=US, ST=private, L=province, O=city, CN=*.org
-    private static byte[] KEYSTORE_11 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQUx1AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_11 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQUx1AAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                             +"AQUABIIJbuNPa7B2d1Mjkq6EBTzELi9V6XgirTYklPyKB3sQ5DUjlK+KoAsUI4oqAGOYPJDzHteq"
                                                                             +"ocv5Dj2+741/Pi5Y6DDvls+6fHrmlJk3QOuVJT4yaI5vo9FJ3FUCUyDohvYrRfpA6gfTfO+QU6DI"
                                                                             +"9G+D4+6gZtz2k4tdoFymtLQRzBS7+L3pFzl5uP7FA1UVWRZlHwsFyLmEmQhZlZcecYtCdTr018iV"
@@ -1531,7 +1532,7 @@ public class SSLUtilTest extends QpidTestCase
                                                                            );
 
     //        Subject: C=US, ST=private, L=province, O=city, CN=*.*.org
-    private static byte[] KEYSTORE_12 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQVfLAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_12 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQVfLAAAJhjCCCYIwDgYKKwYBBAEqAhEB"
                                                                             +"AQUABIIJbrIYGAiHi9UXY3+A7AqtiNSK6KUzH4bilTLdy875582mryHmiv7372P049JZ2NtA0FXk"
                                                                             +"z/Idna6VGQmQfC7V/RWYpcCiiDcNFwpwCrnplPZw/6ItTDFaZQruZjIrgT3joyWGHvDvnzrTOGwt"
                                                                             +"l/yAc3DPnOThuqRogsUHUHpCAxii7/a3fsy4bPvZowSn2s0xJKAt0wBtSEAywahpzbax2pHWFwff"
@@ -1605,7 +1606,7 @@ public class SSLUtilTest extends QpidTestCase
                                                                            );
 
     //        Subject: C=US, ST=private, L=province, O=city, CN=*
-    private static byte[] KEYSTORE_13 = DatatypeConverter.parseBase64Binary("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQWJoAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
+    private static byte[] KEYSTORE_13 = Base64.decode("/u3+7QAAAAIAAAABAAAAAQAKc2VsZnNpZ25lZAAAAVbrQWJoAAAJhzCCCYMwDgYKKwYBBAEqAhEB"
                                                                             +"AQUABIIJb2KqIXFhF34E/cZLKwQIiZncYFYOrfP3HUNTvAXWuX1F2prq4VIiq8zrsLpFB07UrfdL"
                                                                             +"7+xfuC9WJJ09455608neFGtH7K6V5ntULLicLOEkz/jH0WgHBsZjUFXhAl+DivFI880OT7z2FC2E"
                                                                             +"odYUp35Un/cSbfyxjYBQtu64X+u5g+05UW5GhxHCUrHik/5sJYimER/ZrM3SV1ctnllqtJeZx6sn"
diff --git a/client/src/test/java/org/apache/qpid/util/Base64Test.java b/client/src/test/java/org/apache/qpid/util/Base64Test.java
new file mode 100644
index 0000000..57fda0f
--- /dev/null
+++ b/client/src/test/java/org/apache/qpid/util/Base64Test.java
@@ -0,0 +1,118 @@
+/*
+ *
+ * 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.qpid.util;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class Base64Test extends QpidTestCase
+{
+
+    public void testEncode()
+    {
+        assertEquals("", Base64.encode("".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zg==", Base64.encode("f".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm8=", Base64.encode("fo".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm9v", Base64.encode("foo".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm9vYg==", Base64.encode("foob".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm9vYmE=", Base64.encode("fooba".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm9vYmFy", Base64.encode("foobar".getBytes(StandardCharsets.ISO_8859_1)));
+        assertEquals("Zm9vYmFyMQ==", Base64.encode("foobar1".getBytes(StandardCharsets.ISO_8859_1)));
+    }
+
+    public void testDecode()
+    {
+        assertEquals("", new String(Base64.decode(""), StandardCharsets.ISO_8859_1));
+        assertEquals("f",new String(Base64.decode("Zg=="),StandardCharsets.ISO_8859_1));
+        assertEquals("fo", new String(Base64.decode("Zm8="), StandardCharsets.ISO_8859_1));
+        assertEquals("foo", new String(Base64.decode("Zm9v"), StandardCharsets.ISO_8859_1));
+        assertEquals("foob", new String(Base64.decode("Zm9vYg=="), StandardCharsets.ISO_8859_1));
+        assertEquals("fooba", new String(Base64.decode("Zm9vYmE="), StandardCharsets.ISO_8859_1));
+        assertEquals("foobar", new String(Base64.decode("Zm9vYmFy"), StandardCharsets.ISO_8859_1));
+        assertEquals("foobar1", new String(Base64.decode("Zm9vYmFyMQ=="), StandardCharsets.ISO_8859_1));
+    }
+
+    public void testDecodeMissingPadding()
+    {
+        try
+        {
+                 Base64.decode("Zm9vYmFyMQ=");
+                 fail("Exception expected");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+
+    public void testMalformed()
+    {
+        try
+        {
+            Base64.decode("Z=m9vYmFyMQ=");
+            fail("Exception expected");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+
+    public void testUnexpectedPadding()
+    {
+        try
+        {
+            Base64.decode("=");
+            fail("Exception expected");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+
+    public void testUnexpectedCharacter()
+    {
+        try
+        {
+            Base64.decode("Zm9vYmFyMQ:=");
+            fail("Exception expected");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+
+    public void testMissing()
+    {
+        try
+        {
+            Base64.decode("Z");
+            fail("Exception expected");
+        }
+        catch (IllegalArgumentException e)
+        {
+            // pass
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org