From fa1392f37e72ce66968a04e68da9f4912498bce6 Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Tue, 13 Dec 2011 14:10:03 -0600
Subject: [PATCH] Added unit tests for pki-util.

New unit tests have been added to test string converters indirectly.
This is to allow replacing the converters with charset encoder and
decoder without changing the test cases.

The TestRunner has been moved into a separate package such that it
can be reused by other packages.

Ticket #3
---
 pki/.classpath                                     |    2 +
 pki/base/CMakeLists.txt                            |    1 +
 pki/base/common/test/CMakeLists.txt                |    9 +-
 pki/base/{util => test}/CMakeLists.txt             |    2 +-
 pki/base/test/src/CMakeLists.txt                   |   20 ++
 .../src}/com/netscape/test/TestListener.java       |    0
 .../src}/com/netscape/test/TestRunner.java         |    0
 pki/base/util/CMakeLists.txt                       |    1 +
 pki/base/util/test/CMakeLists.txt                  |   60 ++++++
 .../com/netscape/security/util/BMPStringTest.java  |  178 +++++++++++++++++
 .../com/netscape/security/util/IA5StringTest.java  |  179 +++++++++++++++++
 .../test/com/netscape/security/util/JSSUtil.java   |   43 ++++
 .../security/util/PrintableStringTest.java         |  201 ++++++++++++++++++++
 .../com/netscape/security/util/StringTestUtil.java |   76 ++++++++
 .../netscape/security/util/TeletexStringTest.java  |  179 +++++++++++++++++
 .../com/netscape/security/util/UTF8StringTest.java |  166 ++++++++++++++++
 .../security/util/UniversalStringTest.java         |  166 ++++++++++++++++
 .../netscape/security/x509/ConverterTestUtil.java  |   22 ++
 .../security/x509/DirStrConverterTest.java         |  107 +++++++++++
 .../security/x509/GenericValueConverterTest.java   |  110 +++++++++++
 .../security/x509/IA5StringConverterTest.java      |   78 ++++++++
 .../security/x509/PrintableConverterTest.java      |   83 ++++++++
 pki/scripts/compose_pki_core_packages              |    2 +-
 23 files changed, 1679 insertions(+), 6 deletions(-)
 copy pki/base/{util => test}/CMakeLists.txt (54%)
 create mode 100644 pki/base/test/src/CMakeLists.txt
 rename pki/base/{common/test => test/src}/com/netscape/test/TestListener.java (100%)
 rename pki/base/{common/test => test/src}/com/netscape/test/TestRunner.java (100%)
 create mode 100644 pki/base/util/test/CMakeLists.txt
 create mode 100644 pki/base/util/test/com/netscape/security/util/BMPStringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/IA5StringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/JSSUtil.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/PrintableStringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/StringTestUtil.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/TeletexStringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/UTF8StringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/util/UniversalStringTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/x509/ConverterTestUtil.java
 create mode 100644 pki/base/util/test/com/netscape/security/x509/DirStrConverterTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java
 create mode 100644 pki/base/util/test/com/netscape/security/x509/PrintableConverterTest.java

diff --git a/pki/.classpath b/pki/.classpath
index 742a56d2c2318f9b0ba2ba8dee56af58879effe6..2b33d633b9d1bac1291d123c26de4ff2a61d5309 100644
--- a/pki/.classpath
+++ b/pki/.classpath
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry excluding="**/CMakeLists.txt" kind="src" path="base/ca/src"/>
+	<classpathentry kind="src" path="base/test/src"/>
+	<classpathentry kind="src" path="base/util/test"/>
 	<classpathentry kind="src" path="base/common/test"/>
 	<classpathentry kind="src" path="base/common/src"/>
 	<classpathentry excluding="**/CMakeLists.txt" kind="src" path="base/java-tools/src"/>
diff --git a/pki/base/CMakeLists.txt b/pki/base/CMakeLists.txt
index 019564eaf94daedbf1eb9f2a061b9005233748f5..6230f5688d228ac8358bf81924089cb1f850403a 100644
--- a/pki/base/CMakeLists.txt
+++ b/pki/base/CMakeLists.txt
@@ -2,6 +2,7 @@ project(base)
 
 # The order is important!
 #   add_subdirectory(osutil)
+add_subdirectory(test)
 if (APPLICATION_FLAVOR_PKI_CORE)
     add_subdirectory(setup)
     add_subdirectory(symkey)
diff --git a/pki/base/common/test/CMakeLists.txt b/pki/base/common/test/CMakeLists.txt
index 8618bd023dda12b1e4653f37ddf5ef4c9661c40d..7ded236f065799fe7abc1b038976b98344441558 100644
--- a/pki/base/common/test/CMakeLists.txt
+++ b/pki/base/common/test/CMakeLists.txt
@@ -51,15 +51,14 @@ set(pki-common-test_SRCS
     com/netscape/cmscore/request/RequestTest.java
     com/netscape/cmscore/test/CMSBaseTestCase.java
     com/netscape/cmscore/test/TestHelper.java
-    com/netscape/test/TestListener.java
-    com/netscape/test/TestRunner.java
 )
 
 set(CMAKE_JAVA_INCLUDE_PATH
     ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
     ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSBUNDLE_JAR}
     ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR} ${XALAN_JAR} ${XERCES_JAR}
-    ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR} ${JUNIT_JAR}
+    ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR}
+    ${PKI_TEST_JAR} ${JUNIT_JAR}
 )
 
 set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
@@ -72,6 +71,7 @@ add_jar(pki-common-test ${pki-common-test_SRCS})
 add_dependencies(pki-common-test
     osutil pki-nsutil pki-cmsutil
     pki-certsrv pki-cms pki-cmscore pki-cmsbundle
+    pki-test
 )
 
 # create test target
@@ -83,7 +83,8 @@ add_junit_test(test-pki-common
         ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
         ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSBUNDLE_JAR}
         ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR}
-        ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR} ${JUNIT_JAR}
+        ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR}
+        ${PKI_TEST_JAR} ${JUNIT_JAR}
     TESTS
         com.netscape.certsrv.authentication.AuthTokenTest
         com.netscape.certsrv.request.AgentApprovalsTest
diff --git a/pki/base/util/CMakeLists.txt b/pki/base/test/CMakeLists.txt
similarity index 54%
copy from pki/base/util/CMakeLists.txt
copy to pki/base/test/CMakeLists.txt
index 593e0637c1fe441c6f56b1468c834f295705c4bf..9a4acceefea18130a011b750b17d7aabdabf88d5 100644
--- a/pki/base/util/CMakeLists.txt
+++ b/pki/base/test/CMakeLists.txt
@@ -1,3 +1,3 @@
-project(util Java)
+project(test Java)
 
 add_subdirectory(src)
diff --git a/pki/base/test/src/CMakeLists.txt b/pki/base/test/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3631baa73e528afb279c01d015170b0388baa001
--- /dev/null
+++ b/pki/base/test/src/CMakeLists.txt
@@ -0,0 +1,20 @@
+project(pki-test_java Java)
+
+# TODO: create CMake function to find all Java files
+set(pki-test_java_SRCS
+    com/netscape/test/TestListener.java
+    com/netscape/test/TestRunner.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+    ${XALAN_JAR} ${XERCES_JAR} ${JUNIT_JAR}
+)
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build test jar file
+# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
+add_jar(pki-test ${pki-test_java_SRCS})
+set(PKI_TEST_JAR ${pki-test_JAR_FILE} CACHE INTERNAL "pki-test jar file")
\ No newline at end of file
diff --git a/pki/base/common/test/com/netscape/test/TestListener.java b/pki/base/test/src/com/netscape/test/TestListener.java
similarity index 100%
rename from pki/base/common/test/com/netscape/test/TestListener.java
rename to pki/base/test/src/com/netscape/test/TestListener.java
diff --git a/pki/base/common/test/com/netscape/test/TestRunner.java b/pki/base/test/src/com/netscape/test/TestRunner.java
similarity index 100%
rename from pki/base/common/test/com/netscape/test/TestRunner.java
rename to pki/base/test/src/com/netscape/test/TestRunner.java
diff --git a/pki/base/util/CMakeLists.txt b/pki/base/util/CMakeLists.txt
index 593e0637c1fe441c6f56b1468c834f295705c4bf..b8600ba4cbd1351f21aa64b6afd8dee88de9c009 100644
--- a/pki/base/util/CMakeLists.txt
+++ b/pki/base/util/CMakeLists.txt
@@ -1,3 +1,4 @@
 project(util Java)
 
 add_subdirectory(src)
+add_subdirectory(test)
diff --git a/pki/base/util/test/CMakeLists.txt b/pki/base/util/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..119b4dd38af725447d1015a0e744da5143a61fb4
--- /dev/null
+++ b/pki/base/util/test/CMakeLists.txt
@@ -0,0 +1,60 @@
+project(pki-util-test Java)
+
+# TODO: create CMake function to find all Java files
+set(pki-util-test_SRCS
+    com/netscape/security/util/BMPStringTest.java
+    com/netscape/security/util/IA5StringTest.java
+    com/netscape/security/util/JSSUtil.java
+    com/netscape/security/util/PrintableStringTest.java
+    com/netscape/security/util/StringTestUtil.java
+    com/netscape/security/util/TeletexStringTest.java
+    com/netscape/security/util/UniversalStringTest.java
+    com/netscape/security/util/UTF8StringTest.java
+    com/netscape/security/x509/ConverterTestUtil.java
+    com/netscape/security/x509/DirStrConverterTest.java
+    com/netscape/security/x509/GenericValueConverterTest.java
+    com/netscape/security/x509/IA5StringConverterTest.java
+    com/netscape/security/x509/PrintableConverterTest.java
+)
+
+set(CMAKE_JAVA_INCLUDE_PATH
+    ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+    ${JSS_JAR} ${LDAPJDK_JAR} ${OSUTIL_JAR} ${XALAN_JAR} ${XERCES_JAR}
+    ${PKI_TEST_JAR} ${JUNIT_JAR}
+)
+
+set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
+
+# build test jar file
+# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
+set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
+add_jar(pki-util-test ${pki-util-test_SRCS})
+add_dependencies(pki-util-test osutil pki-test)
+
+# create test target
+# do not include xalan and xerces in class path
+# TODO: create CMake function to find all JUnit test classes
+add_junit_test(test-pki-util
+    CLASSPATH
+        ${pki-util-test_JAR_FILE}
+        ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+        ${JSS_JAR} ${LDAPJDK_JAR} ${OSUTIL_JAR}
+        ${PKI_TEST_JAR} ${JUNIT_JAR}
+    TESTS
+        com.netscape.security.util.BMPStringTest
+        com.netscape.security.util.IA5StringTest
+        com.netscape.security.util.PrintableStringTest
+        com.netscape.security.util.TeletexStringTest
+        com.netscape.security.util.UniversalStringTest
+        com.netscape.security.util.UTF8StringTest
+        com.netscape.security.x509.DirStrConverterTest
+        com.netscape.security.x509.GenericValueConverterTest
+        com.netscape.security.x509.IA5StringConverterTest
+        com.netscape.security.x509.PrintableConverterTest
+    REPORTS_DIR
+        reports
+)
+
+# include test into the main test
+add_dependencies(test test-pki-util)
diff --git a/pki/base/util/test/com/netscape/security/util/BMPStringTest.java b/pki/base/util/test/com/netscape/security/util/BMPStringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1dcb659163c15e9b6ebb14e116774051211cf22
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/BMPStringTest.java
@@ -0,0 +1,178 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerValue;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+public class BMPStringTest {
+
+    public byte tag = DerValue.tag_BMPString;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        actual = StringTestUtil.normalizeUnicode(actual);
+        System.out.println(" - norm.   : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        actual = StringTestUtil.normalizeUnicode(actual);
+        System.out.println(" - norm.   : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        actual = StringTestUtil.normalizeUnicode(actual);
+        System.out.println(" - norm.   : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        actual = StringTestUtil.normalizeUnicode(actual);
+        System.out.println(" - norm.   : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/IA5StringTest.java b/pki/base/util/test/com/netscape/security/util/IA5StringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f101e549741e3a3f40df2d5dce1ca1225cad48ba
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/IA5StringTest.java
@@ -0,0 +1,179 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class IA5StringTest {
+
+    public byte tag = DerValue.tag_IA5String;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            byte[] actual = StringTestUtil.encode(tag, string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            String output = StringTestUtil.decode(tag, data);
+            System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/JSSUtil.java b/pki/base/util/test/com/netscape/security/util/JSSUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..abaab4272f35b31b4b24287b0f16525304b8d01c
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/JSSUtil.java
@@ -0,0 +1,43 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerValue;
+
+import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.ASN1Value;
+import org.mozilla.jss.asn1.BMPString;
+import org.mozilla.jss.asn1.IA5String;
+import org.mozilla.jss.asn1.PrintableString;
+import org.mozilla.jss.asn1.TeletexString;
+import org.mozilla.jss.asn1.UTF8String;
+import org.mozilla.jss.asn1.UniversalString;
+
+public class JSSUtil {
+
+    public static byte[] encode(byte tag, String string) throws Exception {
+        ASN1Value value;
+
+        switch (tag) {
+            case DerValue.tag_BMPString:
+                value = new BMPString(string);
+                break;
+            case DerValue.tag_IA5String:
+                value = new IA5String(string);
+                break;
+            case DerValue.tag_PrintableString:
+                value = new PrintableString(string);
+                break;
+            case DerValue.tag_T61String:
+                value = new TeletexString(string);
+                break;
+            case DerValue.tag_UniversalString:
+                value = new UniversalString(string);
+                break;
+            case DerValue.tag_UTF8String:
+                value = new UTF8String(string);
+                break;
+            default:
+                throw new Exception("Unsupported tag: "+tag);
+        }
+        return ASN1Util.encode(value);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/PrintableStringTest.java b/pki/base/util/test/com/netscape/security/util/PrintableStringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d0bc2cbf334110d54300fda4b4fad87a94e5020
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/PrintableStringTest.java
@@ -0,0 +1,201 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class PrintableStringTest {
+
+    public byte tag = DerValue.tag_PrintableString;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            byte[] actual = StringTestUtil.encode(tag, string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            String output = StringTestUtil.decode(tag, data);
+            System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            byte[] actual = StringTestUtil.encode(tag, string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            String output = StringTestUtil.decode(tag, data);
+            System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            byte[] actual = StringTestUtil.encode(tag, StringTestUtil.MULTIBYTE_CHARS);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            String output = StringTestUtil.decode(tag, data);
+            System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/StringTestUtil.java b/pki/base/util/test/com/netscape/security/util/StringTestUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..211ba518316c49fa7ab952944dee967ed03704a1
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/StringTestUtil.java
@@ -0,0 +1,76 @@
+package com.netscape.security.util;
+
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+
+public class StringTestUtil {
+
+    public final static String PRINTABLE_CHARS =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \'()+,-./:=?";
+
+    public final static String NON_PRINTABLE_CHARS = "\"\\";
+
+    public final static String CONTROL_CHARS = "\b\t\n\f\r";
+
+    public final static String MULTIBYTE_CHARS = "我爱你"; // I love you
+
+    public static String toString(byte[] array) {
+
+        StringBuffer sb = new StringBuffer();
+        for (int i=0; i<array.length; i++) {
+            if (i > 0) sb.append(" ");
+            sb.append(Integer.toHexString(0xff & array[i] | 0x100).substring(1).toUpperCase());
+        }
+
+        return sb.toString();
+    }
+
+    public static byte[] normalizeUnicode(byte[] data) throws Exception {
+
+        DerValue value = new DerValue(data);
+        byte[] tmp = value.data.toByteArray();
+
+        if (tmp[0] == -2 && tmp[1] == -1) { // remove optional big-endian byte-order mark
+
+            byte tag = value.tag;
+            int length = value.length() - 2;
+
+            DerOutputStream os = new DerOutputStream();
+            os.putTag((byte)0, false, tag);
+            os.putLength(length);
+            os.write(tmp, 2, length);
+
+            return os.toByteArray();
+        }
+
+        return data;
+    }
+
+    public static byte[] encode(byte tag, String string) throws Exception {
+        DerOutputStream os = new DerOutputStream();
+        os.putStringType(tag, string);
+        return os.toByteArray();
+    }
+
+    public static String decode(byte tag, byte[] bytes) throws Exception {
+        DerInputStream is = new DerInputStream(bytes);
+
+        switch (tag) {
+        case DerValue.tag_BMPString:
+            return is.getBMPString();
+        case DerValue.tag_IA5String:
+            return is.getIA5String();
+        case DerValue.tag_PrintableString:
+            return is.getPrintableString();
+        case DerValue.tag_T61String:
+            return is.getT61String();
+        case DerValue.tag_UniversalString:
+            return is.getUniversalString();
+        case DerValue.tag_UTF8String:
+            return is.getDerValue().getUTF8String();
+        default:
+            throw new Exception("Unsupported tag: "+tag);
+        }
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/TeletexStringTest.java b/pki/base/util/test/com/netscape/security/util/TeletexStringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7217cae40c64691ef5437ede22af97bb69e8cf1a
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/TeletexStringTest.java
@@ -0,0 +1,179 @@
+package com.netscape.security.util;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class TeletexStringTest {
+
+    public byte tag = DerValue.tag_T61String;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            byte[] actual = StringTestUtil.encode(tag, string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(DerValue.tag_UTF8String, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: IOException");
+
+        try {
+            String output = StringTestUtil.decode(tag, data);
+            System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IOException);
+        }
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/UTF8StringTest.java b/pki/base/util/test/com/netscape/security/util/UTF8StringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3256a8e33b8805271e7093af90e6e66bd9add77d
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/UTF8StringTest.java
@@ -0,0 +1,166 @@
+package com.netscape.security.util;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class UTF8StringTest {
+
+    public byte tag = DerValue.tag_UTF8String;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, "");
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, "");
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/util/UniversalStringTest.java b/pki/base/util/test/com/netscape/security/util/UniversalStringTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aceae03b3067254a3132abfff25c07f10e58ac73
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/util/UniversalStringTest.java
@@ -0,0 +1,166 @@
+package com.netscape.security.util;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import sun.security.util.DerValue;
+
+public class UniversalStringTest {
+
+    public byte tag = DerValue.tag_UniversalString;
+
+    @Test
+    public void testEncodingEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingEmptyString() throws Exception {
+
+        String input = "";
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingNonPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.NON_PRINTABLE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingNonPrintableCharacters() throws Exception {
+
+        String input = StringTestUtil.NON_PRINTABLE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+input+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+output+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Encoding: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingControlCharacters() throws Exception {
+
+        String input = StringTestUtil.CONTROL_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+
+    @Test
+    public void testEncodingMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Encoding: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(tag, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = StringTestUtil.encode(tag, string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testDecodingMultibyteCharacters() throws Exception {
+
+        String input = StringTestUtil.MULTIBYTE_CHARS;
+        byte[] data = JSSUtil.encode(tag, input);
+
+        System.out.println("Decoding: ["+StringTestUtil.toString(data)+"]");
+
+        System.out.println(" - expected: ["+StringTestUtil.toString(input.getBytes())+"]");
+
+        String output = StringTestUtil.decode(tag, data);
+        System.out.println(" - actual  : ["+StringTestUtil.toString(output.getBytes())+"]");
+
+        Assert.assertEquals(input, output);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/x509/ConverterTestUtil.java b/pki/base/util/test/com/netscape/security/x509/ConverterTestUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..748c1b284bc30321710a936a6de8be645fca91cc
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/x509/ConverterTestUtil.java
@@ -0,0 +1,22 @@
+package com.netscape.security.x509;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AVAValueConverter;
+
+public class ConverterTestUtil {
+
+    public static byte[] convert(AVAValueConverter converter, String string, byte[] tags) throws Exception {
+
+        DerOutputStream os = new DerOutputStream();
+
+        DerValue value = converter.getValue(string, tags);
+        value.encode(os);
+
+        return os.toByteArray();
+    }
+
+    public static byte[] convert(AVAValueConverter converter, String string) throws Exception {
+        return convert(converter, string, null);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/x509/DirStrConverterTest.java b/pki/base/util/test/com/netscape/security/x509/DirStrConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec8ddc51b15171269135518fb3e4a7dfce54fdb5
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/x509/DirStrConverterTest.java
@@ -0,0 +1,107 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.DirStrConverter;
+
+public class DirStrConverterTest {
+
+    @Test
+    public void testEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Converting: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharactersWithTags() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] {
+            DerValue.tag_IA5String, DerValue.tag_UTF8String
+        });
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testMultibyteCharactersWithTags() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_UTF8String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new DirStrConverter(), string, new byte[] {
+            DerValue.tag_IA5String, DerValue.tag_UTF8String
+        });
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java b/pki/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bee2b241fff84d619df5bb0bf10dd622a0479a69
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/x509/GenericValueConverterTest.java
@@ -0,0 +1,110 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.GenericValueConverter;
+
+public class GenericValueConverterTest {
+
+    @Test
+    public void testEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Converting: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_BMPString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        actual = StringTestUtil.normalizeUnicode(actual);
+        System.out.println(" - norm.   : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharactersWithTags() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_T61String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] {
+            DerValue.tag_T61String, DerValue.tag_UniversalString
+        });
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testMultibyteCharactersWithTags() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_UniversalString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new GenericValueConverter(), string, new byte[] {
+            DerValue.tag_T61String, DerValue.tag_UniversalString
+        });
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java b/pki/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..682e7384fba0b01ca6bd57f56782ae6a9055f029
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/x509/IA5StringConverterTest.java
@@ -0,0 +1,78 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.IA5StringConverter;
+
+public class IA5StringConverterTest {
+
+    @Test
+    public void testEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Converting: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_IA5String, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        System.out.println(" - expected: IllegalArgumentException");
+
+        try {
+            byte[] actual = ConverterTestUtil.convert(new IA5StringConverter(), string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IllegalArgumentException);
+        }
+    }
+}
diff --git a/pki/base/util/test/com/netscape/security/x509/PrintableConverterTest.java b/pki/base/util/test/com/netscape/security/x509/PrintableConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..acaa5c1b8981dd7cdfaaaed11c4551a4f985cef6
--- /dev/null
+++ b/pki/base/util/test/com/netscape/security/x509/PrintableConverterTest.java
@@ -0,0 +1,83 @@
+package com.netscape.security.x509;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+import com.netscape.security.util.JSSUtil;
+import com.netscape.security.util.StringTestUtil;
+
+import netscape.security.util.DerValue;
+import netscape.security.x509.PrintableConverter;
+
+public class PrintableConverterTest {
+
+    @Test
+    public void testEmptyString() throws Exception {
+
+        String string = "";
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testPrintableCharacters() throws Exception {
+
+        String string = StringTestUtil.PRINTABLE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        byte[] expected = JSSUtil.encode(DerValue.tag_PrintableString, string);
+        System.out.println(" - expected: "+StringTestUtil.toString(expected));
+
+        byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+        System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+        Assert.assertArrayEquals(expected, actual);
+    }
+
+    @Test
+    public void testControlCharacters() throws Exception {
+
+        String string = StringTestUtil.CONTROL_CHARS;
+        System.out.println("Converting: ["+StringTestUtil.toString(string.getBytes())+"]");
+
+        System.out.println(" - expected: IllegalArgumentException");
+
+        try {
+            byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IllegalArgumentException);
+        }
+    }
+
+    @Test
+    public void testMultibyteCharacters() throws Exception {
+
+        String string = StringTestUtil.MULTIBYTE_CHARS;
+        System.out.println("Converting: ["+string+"]");
+
+        System.out.println(" - expected: IllegalArgumentException");
+
+        try {
+            byte[] actual = ConverterTestUtil.convert(new PrintableConverter(), string);
+            System.out.println(" - actual  : "+StringTestUtil.toString(actual));
+
+            Assert.fail();
+
+        } catch (Exception e) {
+            System.out.println(" - actual  : "+e.getClass().getSimpleName());
+            Assert.assertTrue(e instanceof IllegalArgumentException);
+        }
+    }
+}
diff --git a/pki/scripts/compose_pki_core_packages b/pki/scripts/compose_pki_core_packages
index 46cfaa67312276a9bf30508f107a519725e2b2b1..5486c711512522428038b6c52514dc9700fc4939 100755
--- a/pki/scripts/compose_pki_core_packages
+++ b/pki/scripts/compose_pki_core_packages
@@ -39,7 +39,7 @@ PKI_CORE_VERSION="9.0.16"
 ##
 
 PKI_SPECS_FILE="${PKI_DIR}/specs/${PKI_CORE}.spec"
-PKI_COMPONENT_LIST="setup symkey native-tools util java-tools common selinux ca silent"
+PKI_COMPONENT_LIST="test setup symkey native-tools util java-tools common selinux ca silent"
 
 
 ##
-- 
1.7.6.4

