From e7484c264d46d31aeff1a6398e016a4836e383ad Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Mon, 12 Dec 2011 22:55:14 -0600
Subject: [PATCH] Replaced byte-to-char & char-to-byte converters.

The byte-to-char and char-to-byte converters have been replaced
with a set of charsets, each having its own decoders and encoders.

Ticket #3
---
 pki/base/util/src/CMakeLists.txt                   |   39 +++--
 .../netscape/security/util/ASN1CharStrConvMap.java |  181 ++++++-------------
 .../security/util/ASN1CharsetProvider.java         |   30 +++
 .../security/util/ByteToCharIA5String.java         |   69 -------
 .../security/util/ByteToCharPrintable.java         |   88 ---------
 .../netscape/security/util/ByteToCharUnicode.java  |  187 --------------------
 .../security/util/ByteToCharUniversalString.java   |   99 -----------
 .../security/util/CharToByteIA5String.java         |   88 ---------
 .../security/util/CharToBytePrintable.java         |  122 -------------
 .../security/util/CharToByteUniversalString.java   |   85 ---------
 .../netscape/security/util/DerOutputStream.java    |   49 ++----
 .../util/src/netscape/security/util/DerValue.java  |   71 ++++----
 .../src/netscape/security/util/IA5Charset.java     |   24 +++
 .../netscape/security/util/IA5CharsetDecoder.java  |   62 +++++++
 .../netscape/security/util/IA5CharsetEncoder.java  |   68 +++++++
 .../netscape/security/util/PrintableCharset.java   |   24 +++
 .../security/util/PrintableCharsetDecoder.java     |   68 +++++++
 .../security/util/PrintableCharsetEncoder.java     |   92 ++++++++++
 .../netscape/security/util/UniversalCharset.java   |   24 +++
 .../security/util/UniversalCharsetDecoder.java     |   97 ++++++++++
 .../security/util/UniversalCharsetEncoder.java     |   66 +++++++
 pki/base/util/src/netscape/security/x509/AVA.java  |   42 +++---
 .../netscape/security/x509/DirStrConverter.java    |   75 +++-----
 .../security/x509/GenericValueConverter.java       |   78 +++-----
 .../netscape/security/x509/IA5StringConverter.java |   44 ++---
 .../security/x509/LdapV3DNStrConverter.java        |   68 +++----
 .../netscape/security/x509/PrintableConverter.java |   46 ++---
 27 files changed, 836 insertions(+), 1150 deletions(-)
 create mode 100644 pki/base/util/src/netscape/security/util/ASN1CharsetProvider.java
 delete mode 100644 pki/base/util/src/netscape/security/util/ByteToCharIA5String.java
 delete mode 100644 pki/base/util/src/netscape/security/util/ByteToCharPrintable.java
 delete mode 100644 pki/base/util/src/netscape/security/util/ByteToCharUnicode.java
 delete mode 100644 pki/base/util/src/netscape/security/util/ByteToCharUniversalString.java
 delete mode 100644 pki/base/util/src/netscape/security/util/CharToByteIA5String.java
 delete mode 100644 pki/base/util/src/netscape/security/util/CharToBytePrintable.java
 delete mode 100644 pki/base/util/src/netscape/security/util/CharToByteUniversalString.java
 create mode 100644 pki/base/util/src/netscape/security/util/IA5Charset.java
 create mode 100644 pki/base/util/src/netscape/security/util/IA5CharsetDecoder.java
 create mode 100644 pki/base/util/src/netscape/security/util/IA5CharsetEncoder.java
 create mode 100644 pki/base/util/src/netscape/security/util/PrintableCharset.java
 create mode 100644 pki/base/util/src/netscape/security/util/PrintableCharsetDecoder.java
 create mode 100644 pki/base/util/src/netscape/security/util/PrintableCharsetEncoder.java
 create mode 100644 pki/base/util/src/netscape/security/util/UniversalCharset.java
 create mode 100644 pki/base/util/src/netscape/security/util/UniversalCharsetDecoder.java
 create mode 100644 pki/base/util/src/netscape/security/util/UniversalCharsetEncoder.java

diff --git a/pki/base/util/src/CMakeLists.txt b/pki/base/util/src/CMakeLists.txt
index dffa341b09a49802ae4702159e0ead41d328c369..919b593e7f30decad0261c3269fe05680767a8f2 100644
--- a/pki/base/util/src/CMakeLists.txt
+++ b/pki/base/util/src/CMakeLists.txt
@@ -157,30 +157,33 @@ set(pki-nsutil_java_SRCS
     netscape/security/x509/PolicyConstraint.java
     netscape/security/x509/RevokedCertImpl.java
     netscape/security/x509/OtherName.java
+    netscape/security/util/ASN1CharsetProvider.java
+    netscape/security/util/ASN1CharStrConvMap.java
     netscape/security/util/BigInt.java
+    netscape/security/util/BitArray.java
+    netscape/security/util/ByteArrayLexOrder.java
+    netscape/security/util/ByteArrayTagOrder.java
+    netscape/security/util/CertPrettyPrint.java
+    netscape/security/util/CrlPrettyPrint.java
+    netscape/security/util/DerEncoder.java
+    netscape/security/util/DerInputBuffer.java
+    netscape/security/util/DerInputStream.java
     netscape/security/util/DerOutputStream.java
-    netscape/security/util/ASN1CharStrConvMap.java
-    netscape/security/util/ByteToCharUnicode.java
     netscape/security/util/DerValue.java
-    netscape/security/util/CharToByteIA5String.java
-    netscape/security/util/DerInputBuffer.java
-    netscape/security/util/CharToBytePrintable.java
-    netscape/security/util/ObjectIdentifier.java
-    netscape/security/util/DerEncoder.java
     netscape/security/util/ExtPrettyPrint.java
-    netscape/security/util/ByteArrayLexOrder.java
-    netscape/security/util/BitArray.java
-    netscape/security/util/CrlPrettyPrint.java
-    netscape/security/util/CertPrettyPrint.java
-    netscape/security/util/ByteArrayTagOrder.java
-    netscape/security/util/PrettyPrintResources.java
+    netscape/security/util/IA5Charset.java
+    netscape/security/util/IA5CharsetDecoder.java
+    netscape/security/util/IA5CharsetEncoder.java
+    netscape/security/util/ObjectIdentifier.java
     netscape/security/util/PrettyPrintFormat.java
-    netscape/security/util/CharToByteUniversalString.java
-    netscape/security/util/ByteToCharIA5String.java
+    netscape/security/util/PrettyPrintResources.java
+    netscape/security/util/PrintableCharset.java
+    netscape/security/util/PrintableCharsetDecoder.java
+    netscape/security/util/PrintableCharsetEncoder.java
     netscape/security/util/PubKeyPrettyPrint.java
-    netscape/security/util/ByteToCharPrintable.java
-    netscape/security/util/DerInputStream.java
-    netscape/security/util/ByteToCharUniversalString.java
+    netscape/security/util/UniversalCharset.java
+    netscape/security/util/UniversalCharsetDecoder.java
+    netscape/security/util/UniversalCharsetEncoder.java
     netscape/security/provider/DSA.java
     netscape/security/provider/DSAPrivateKey.java
     netscape/security/provider/DSAParameters.java
diff --git a/pki/base/util/src/netscape/security/util/ASN1CharStrConvMap.java b/pki/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
index 5df6baef83fc13aeeedd1a44cc9e97e543fc0c38..5fbca4750d480bd6fe930bb77fd92d3f11127608 100644
--- a/pki/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
+++ b/pki/base/util/src/netscape/security/util/ASN1CharStrConvMap.java
@@ -17,16 +17,13 @@
 // --- END COPYRIGHT BLOCK ---
 package netscape.security.util;
 
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-import sun.io.ByteToCharConverter;
-import sun.io.ByteToCharUTF8;
-import sun.io.CharToByteConverter;
-import sun.io.CharToByteUTF8;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.util.*;
 
 /**
- * Maps a ASN.1 character string type to a CharToByte and ByteToChar converter.
+ * Maps a ASN.1 character string type to a charset encoder and decoder.
  * The converter is used to convert a DerValue of a ASN.1 character string type
  * from bytes to unicode characters and vice versa.
  *
@@ -50,101 +47,62 @@ public class ASN1CharStrConvMap
     }
 
     /**
-     * Get a Character to Byte converter for the specified DER tag.
+     * Get an encoder for the specified DER tag.
      *
      * @param tag 	A DER tag of a ASN.1 character string type,
      *			for example DerValue.tag_PrintableString.
      *
-     * @return 		A CharToByteConverter for the DER tag.
-     *
-     * @exception InstantiationException
-     *		if error occurs when instantiating the CharToByteConverter.
-     * @exception IllegalAccessException
-     *		if error occurs when loading the CharToByteConverter class.
+     * @return 		An encoder for the DER tag.
      */
-    public CharToByteConverter getCBC(byte tag)
-	throws IllegalAccessException, InstantiationException
-    {
-	Byte tagObj = Byte.valueOf(tag);
-	CharToByteConverter cbc = null;
-	Class cbcClass;
-	cbcClass = (Class)tag2CBC.get(tagObj);
-	if (cbcClass == null)
-	    return null;
-	cbc = (CharToByteConverter)cbcClass.newInstance();
-	cbc.setSubstitutionMode(false);
-	return cbc;
+    public CharsetEncoder getEncoder(byte tag) {
+        Charset charset = charsets.get(tag);
+        if (charset == null) return null;
+        return charset.newEncoder();
     }
 
     /**
-     * Get a Byte to Character converter for the given DER tag.
+     * Get a decoder for the given DER tag.
      *
      * @param tag 	A DER tag of a ASN.1 character string type,
      *			for example DerValue.tag_PrintableString.
      *
-     * @return 		A ByteToCharConverter for the DER tag.
-     *
-     * @exception InstantiationException
-     *		if error occurs when instantiationg the ByteToCharConverter.
-     * @exception IllegalAccessException
-     *		if error occurs when loading the ByteToCharConverter class.
+     * @return 		A decoder for the DER tag.
      */
-    public ByteToCharConverter getBCC(byte tag)
-	throws IllegalAccessException, InstantiationException
-    {
-	Byte tagObj = Byte.valueOf(tag);
-	ByteToCharConverter bcc = null;
-	Class bccClass = (Class)tag2BCC.get(tagObj);
-	if (bccClass == null)
-	    return null;
-	bcc = (ByteToCharConverter)bccClass.newInstance();
-	bcc.setSubstitutionMode(false);
-	return bcc;
+    public CharsetDecoder getDecoder(byte tag) {
+        Charset charset = charsets.get(tag);
+        if (charset == null) return null;
+        return charset.newDecoder();
     }
 
     /**
-     * Add a tag-CharToByteConverter-ByteToCharConverter entry in the map.
+     * Add a tag-charset entry in the map.
      *
      * @param tag	A DER tag of a ASN.1 character string type,
      *			ex. DerValue.tag_IA5String
-     * @param cbc	A CharToByteConverter for the tag.
-     * @param bcc	A ByteToCharConverter for the tag.
+     * @param charset	A charset for the tag.
      */
-    public void addEntry(byte tag, Class cbc, Class bcc)
-    {
-	Class current_cbc;
-	Class current_bcc;
-	Byte tagByte = Byte.valueOf(tag);
 
-	current_cbc = (Class)tag2CBC.get(tagByte);
-	current_bcc = (Class)tag2BCC.get(tagByte);
-	if (current_cbc != null || current_bcc != null)
-	{
-	    if (current_cbc != cbc || current_bcc != bcc)
-	    {
-		throw new IllegalArgumentException(
-		    "a DER tag to converter entry already exists.");
-	    }
-	    else {
-		return;
-	    }
-	}
-	if (!CharToByteConverter.class.isAssignableFrom(cbc) ||
-	    !ByteToCharConverter.class.isAssignableFrom(bcc)) {
-	    throw new IllegalArgumentException(
-		"arguments not a CharToByteConverter or ByteToCharConverter");
-	}
-	tag2CBC.put(tagByte, cbc);
-	tag2BCC.put(tagByte, bcc);
+    public void addEntry(byte tag, Charset charset) {
+
+        Charset currentCharset = charsets.get(tag);
+
+        if (currentCharset != null) {
+            if (currentCharset != charset) {
+                throw new IllegalArgumentException(
+                    "a DER tag to converter entry already exists.");
+            } else {
+                return;
+            }
+        }
+
+        charsets.put(tag, charset);
     }
-
     /**
      * Get and enumeration of all tags in the map.
      * @return 	An Enumeration of DER tags in the map as Bytes.
      */
-    public Enumeration getTags()
-    {
-	return tag2CBC.keys();
+    public Iterator<Byte> getTags() {
+	    return charsets.keySet().iterator();
     }
 
     // static public methods.
@@ -172,8 +130,7 @@ public class ASN1CharStrConvMap
 
     // private methods and variables.
 
-    private Hashtable tag2CBC = new Hashtable();
-    private Hashtable tag2BCC = new Hashtable();
+    private Map<Byte, Charset> charsets = new HashMap<Byte, Charset>();
 
     private static ASN1CharStrConvMap defaultMap;
 
@@ -181,50 +138,28 @@ public class ASN1CharStrConvMap
      * Create the default converter map on initialization
      */
     static {
-	defaultMap = new ASN1CharStrConvMap();
-	defaultMap.addEntry(DerValue.tag_PrintableString,
-	    	CharToBytePrintable.class, ByteToCharPrintable.class);
-	defaultMap.addEntry(DerValue.tag_VisibleString,
-	    	CharToBytePrintable.class, ByteToCharPrintable.class);
-	defaultMap.addEntry(DerValue.tag_IA5String,
-	    	CharToByteIA5String.class, ByteToCharIA5String.class);
-	defaultMap.addEntry(DerValue.tag_BMPString,
-	        // Changed by bskim
-	    	//sun.io.CharToByteUnicode.class,
-	    	//netscape.security.util.ByteToCharUnicode.class);
-	    	sun.io.CharToByteUnicodeBig.class,
-	    	sun.io.ByteToCharUnicodeBig.class);
-	    	// Change end
-	defaultMap.addEntry(DerValue.tag_UniversalString,
-	    	CharToByteUniversalString.class,
-	    	ByteToCharUniversalString.class);
-    	// XXX this is an oversimplified implementation of T.61 strings, it
-    	// doesn't handle all cases
-	defaultMap.addEntry(DerValue.tag_T61String,
-	    	latin1CBC.class, latin1BCC.class);
-	// UTF8String added to ASN.1 in 1998
-	defaultMap.addEntry(DerValue.tag_UTF8String,
-	    	CharToByteUTF8.class,
-	    	ByteToCharUTF8.class);
-	defaultMap.addEntry(DerValue.tag_GeneralString,
-	    	CharToByteUTF8.class,
-	    	ByteToCharUTF8.class);
+        ASN1CharsetProvider provider = new ASN1CharsetProvider();
+
+        defaultMap = new ASN1CharStrConvMap();
+        defaultMap.addEntry(DerValue.tag_PrintableString,
+            provider.charsetForName("ASN.1-Printable"));
+        defaultMap.addEntry(DerValue.tag_VisibleString,
+            provider.charsetForName("ASN.1-Printable"));
+        defaultMap.addEntry(DerValue.tag_IA5String,
+            provider.charsetForName("ASN.1-IA5"));
+        defaultMap.addEntry(DerValue.tag_BMPString,
+            Charset.forName("UTF-16BE"));
+        defaultMap.addEntry(DerValue.tag_UniversalString,
+            provider.charsetForName("ASN.1-Universal"));
+        // XXX this is an oversimplified implementation of T.61 strings, it
+        // doesn't handle all cases
+        defaultMap.addEntry(DerValue.tag_T61String,
+            Charset.forName("ISO-8859-1"));
+        // UTF8String added to ASN.1 in 1998
+        defaultMap.addEntry(DerValue.tag_UTF8String,
+            Charset.forName("UTF-8"));
+        defaultMap.addEntry(DerValue.tag_GeneralString,
+            Charset.forName("UTF-8"));
     };
 
 };
-
-class latin1CBC extends sun.io.CharToByteISO8859_1 {
-	public latin1CBC() {
-		super();
-		subMode = false;
-	}
-}
-
-class latin1BCC extends sun.io.ByteToCharISO8859_1 {
-	public latin1BCC() {
-		super();
-		subMode = false;
-	}
-}
-
-
diff --git a/pki/base/util/src/netscape/security/util/ASN1CharsetProvider.java b/pki/base/util/src/netscape/security/util/ASN1CharsetProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..1de1c3c48e3e7a00257b2cd3f92561e169df68e0
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/ASN1CharsetProvider.java
@@ -0,0 +1,30 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.spi.CharsetProvider;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class ASN1CharsetProvider extends CharsetProvider {
+
+    protected Map<String, Charset> charsets = new HashMap<String, Charset>();
+
+    public ASN1CharsetProvider() {
+        addCharset(new PrintableCharset());
+        addCharset(new IA5Charset());
+        addCharset(new UniversalCharset());
+    }
+
+    public Iterator<Charset> charsets() {
+        return charsets.values().iterator();
+    }
+
+    public Charset charsetForName(String charsetName) {
+        return charsets.get(charsetName);
+    }
+
+    public void addCharset(Charset cs) {
+        charsets.put(cs.name(), cs);
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/ByteToCharIA5String.java b/pki/base/util/src/netscape/security/util/ByteToCharIA5String.java
deleted file mode 100644
index 69fab22a74e0a13916a454b7b5961f9e1e2c0fcb..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/ByteToCharIA5String.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.ByteToCharConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts bytes in ASN.1 IA5String character set to unicode 
- * characters. 
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class ByteToCharIA5String extends ByteToCharConverter 
-{
-    public String getCharacterEncoding() {
-	return "ASN.1 IA5String";
-    }
-
-    public int convert(byte[] input, int inStart, int inEnd,
-		       char[] output, int outStart, int outEnd)
-	throws ConversionBufferFullException,
-		UnknownCharacterException
-    {
-	int j = outStart;
-	for (int i = inStart; i < inEnd; i++, j++) {
-	    if (j >= outEnd) {
-		byteOff = i;
-		charOff = j;
-		throw new ConversionBufferFullException();
-	    }
-	    if (!subMode && (input[i] & 0x80) != 0) {
-		byteOff = i;
-		charOff = j;
-		badInputLength = 1;
-		throw new UnknownCharacterException();
-	    }
-	    output[j] = (char) (input[i] & 0x7f);
-	}
-	byteOff = inEnd;
-	charOff = j;
-	return j - outStart;
-    }
-
-    public int flush(char[] output, int outStart, int outEnd) {
-	return 0;
-    }
-
-    public void reset() { }
-
-}
diff --git a/pki/base/util/src/netscape/security/util/ByteToCharPrintable.java b/pki/base/util/src/netscape/security/util/ByteToCharPrintable.java
deleted file mode 100644
index 0607ad2e8ffd2ce22fe345f0221bee5a7fa9780a..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/ByteToCharPrintable.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.ByteToCharConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.MalformedInputException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts bytes in ASN.1 Printable String character set to unicode 
- * characters. 
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class ByteToCharPrintable extends ByteToCharConverter
-{
-
-    public String getCharacterEncoding()
-    {
-	return "ASN.1 Printable";
-    }
-
-    public int convert(byte[] input, int inStart, int inEnd,
-		       char[] output, int outStart, int outEnd)
-            throws MalformedInputException,
-                   UnknownCharacterException,
-                   ConversionBufferFullException
-    {
-	int j = outStart;
-	boolean hasNonPrintableChar = false;
-
-	for (int i = inStart; i < inEnd; i++, j++) {
-	    if (j >= outEnd) {
-		byteOff = i;
-		charOff = j;
-		throw new ConversionBufferFullException();
-	    }
-	    if (!subMode &&
-			!CharToBytePrintable.isPrintableChar((char) (input[i] & 0x7f))) {
-			/* "bug" fix for 359010
-			  byteOff = i;
-			  charOff = j;
-			  badInputLength = 1;
-			  throw new UnknownCharacterException();
-			  */
-			j--;
-			hasNonPrintableChar = true;
-	    } else
-			output[j] = (char) (input[i] & 0x7f);
-	}
-
-	if (hasNonPrintableChar == true) {
-		//
-	}
-
-	byteOff = inEnd;
-	charOff = j;
-	return j - outStart;
-    }
-
-    public int flush( char[] output, int outStart, int outEnd )
-        throws MalformedInputException, ConversionBufferFullException
-    {
-	return 0;
-    }
-
-    public void reset() { }
-
-
-}
diff --git a/pki/base/util/src/netscape/security/util/ByteToCharUnicode.java b/pki/base/util/src/netscape/security/util/ByteToCharUnicode.java
deleted file mode 100644
index 312b8a22b759581df47f003dc40ab998aa3974b6..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/ByteToCharUnicode.java
+++ /dev/null
@@ -1,187 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-import sun.io.ByteToCharUnicodeBig;
-import sun.io.ByteToCharUnicodeLittle;
-import sun.io.ConversionBufferFullException;
-import sun.io.MalformedInputException;
-
-/**
- * Convert byte arrays containing Unicode characters into arrays of actual
- * Unicode characters, sensing the byte order automatically.  To force a
- * particular byte order, use either the "UnicodeBig" or the "UnicodeLittle"
- * encoding.
- *
- * If the first character is a byte order mark, it will be interpreted and
- * discarded. Otherwise, the byte order is assumed to be BigEndian.
- * Either way, the byte order is decided by the first character. Later
- * byte order marks will be passed through as characters (if they indicate
- * the same byte order) or will cause an error (if they indicate the other
- * byte order).
- *
- * @see ByteToCharUnicodeLittle
- * @see ByteToCharUnicodeBig
- *
- * @version 	1.3, 96/11/23
- * @author	Mark Reinhold
- */
-
-public class ByteToCharUnicode extends sun.io.ByteToCharConverter {
-
-    static final char BYTE_ORDER_MARK = (char) 0xfeff;
-    static final char REVERSED_MARK = (char) 0xfffe;
-
-    static final int AUTO = 0;
-    static final int BIG = 1;
-    static final int LITTLE = 2;
-
-    int byteOrder;
-
-    public ByteToCharUnicode() {
-	byteOrder = AUTO;
-    }
-
-    public String getCharacterEncoding() {
-	switch (byteOrder) {
-	case BIG:     return "UnicodeBig";
-	case LITTLE:  return "UnicodeLittle";
-	default:      return "Unicode";
-	}
-    }
-
-    boolean started = false;
-    int leftOverByte;
-    boolean leftOver = false;
-
-    public int convert(byte[] in, int inOff, int inEnd,
-		       char[] out, int outOff, int outEnd)
-	throws ConversionBufferFullException, MalformedInputException
-    {
-	byteOff = inOff;
-	charOff = outOff;
-
-	if (inOff >= inEnd)
-	    return 0;
-
-	int b1, b2;
-	int bc = 0;
-	int inI = inOff, outI = outOff;
-
-	if (leftOver) {
-	    b1 = leftOverByte & 0xff;
-	    leftOver = false;
-	}
-	else
-	    b1 = in[inI++] & 0xff;
-	bc = 1;
-
-	if (!started) {		/* Read possible initial byte-order mark */
-	    if (inI < inEnd) {
-		b2 = in[inI++] & 0xff;
-		bc = 2;
-
-		char c = (char) ((b1 << 8) | b2);
-		int bo = AUTO;
-
-		if (c == BYTE_ORDER_MARK)
-		    bo = BIG;
-		else if (c == REVERSED_MARK)
-		    bo = LITTLE;
-
-		if (byteOrder == AUTO) {
-		    if (bo == AUTO) {
-                        bo = BIG; // BigEndian by default
-		    }
-		    byteOrder = bo;
-		    if (inI < inEnd) {
-			b1 = in[inI++] & 0xff;
-			bc = 1;
-		    }
-		}
-		else if (bo == AUTO) {
-		    inI--;
-		    bc = 1;
-		}
-		else if (byteOrder == bo) {
-		    if (inI < inEnd) {
-			b1 = in[inI++] & 0xff;
-			bc = 1;
-		    }
-		}
-		else {
-		    badInputLength = bc;
-		    throw new
-			MalformedInputException("Incorrect byte-order mark");
-		}
-
-		started = true;
-	    }
-	}
-
-	/* Loop invariant: (b1 contains the next input byte) && (bc == 1) */
-	while (inI < inEnd) {
-	    b2 = in[inI++] & 0xff;
-	    bc = 2;
-
-	    char c;
-	    if (byteOrder == BIG)
-		c = (char) ((b1 << 8) | b2);
-	    else
-		c = (char) ((b2 << 8) | b1);
-
-	    if (c == REVERSED_MARK)
-		throw new
-		    MalformedInputException("Reversed byte-order mark");
-
-	    if (outI >= outEnd)
-		throw new ConversionBufferFullException();
-	    out[outI++] = c;
-	    byteOff = inI;
-	    charOff = outI;
-
-	    if (inI < inEnd) {
-		b1 = in[inI++] & 0xff;
-		bc = 1;
-	    }
-	}
-
-	if (bc == 1) {
-	    leftOverByte = b1;
-	    leftOver = true;
-	}
-
-	return outI - outOff;
-    }
-
-    public void reset() {
-	leftOver = false;
-	byteOff = charOff = 0;
-    }
-
-    public int flush(char buf[], int off, int len)
-	throws MalformedInputException
-    {
-	if (leftOver) {
-	    reset();
-	    throw new MalformedInputException();
-	}
-	byteOff = charOff = 0;
-	return 0;
-    }
-
-}
diff --git a/pki/base/util/src/netscape/security/util/ByteToCharUniversalString.java b/pki/base/util/src/netscape/security/util/ByteToCharUniversalString.java
deleted file mode 100644
index 77165b7fe09d1722c4f3beede207a02fb1fe9a44..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/ByteToCharUniversalString.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.ByteToCharConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts bytes in ASN.1 UniversalString character set to unicode
- * characters.
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class ByteToCharUniversalString extends ByteToCharConverter
-{
-    public String getCharacterEncoding() {
-	return "ASN.1 UniversalString";
-    }
-
-    public int convert(byte[] input, int inStart, int inEnd,
-		       char[] output, int outStart, int outEnd)
-	throws ConversionBufferFullException,
-		UnknownCharacterException
-    {
-	int j = outStart;
-
-
-	int i = inStart;
-	while(i < inEnd) {
-	    // XXX we do not know what to do with truly UCS-4 characters here
-	    // we also assumed network byte order
-
-        if ( i+3 >= inEnd || 
-				(!((input[i] == 0 && input[i+1] == 0) ||
-				(input[i+2] == 0 && input[i+3] == 0)))) {
-    		byteOff = i;
-	    	charOff = j;
-		    throw new UnknownCharacterException();
-	    }
-		if (input[i+2] == 0 && input[i+3] == 0) {
-			// Try to be a bit forgiving. If the byte order is
-			// reversed, we still try handle it.
-
-			// Sample Date Set (1):
-			// 0000000   f   0  \0  \0 213   0  \0  \0   S   0  \0  \0
-			// 0000014
-
-			// Sample Date Set (2):
-			// 0000000   w  \0  \0  \0   w  \0  \0  \0   w  \0  \0  \0   .  \0  \0  \0
-			// 0000020   (  \0  \0  \0   t  \0  \0  \0   o  \0  \0  \0   b  \0  \0  \0
-			// 0000040   e  \0  \0  \0   |  \0  \0  \0   n  \0  \0  \0   o  \0  \0  \0
-			// 0000060   t  \0  \0  \0   t  \0  \0  \0   o  \0  \0  \0   b  \0  \0  \0
-			// 0000100   e  \0  \0  \0   )  \0  \0  \0   .  \0  \0  \0   c  \0  \0  \0
-			// 0000120   o  \0  \0  \0   m  \0  \0  \0
-			// 0000130
-		    output[j] = (char)(((input[i+1] << 8)& 0xff00) + (input[i] & 0x00ff));
-		} else { 
-			// This should be the right order.
-			//
-			// 0000000 0000 00c4 0000 0064 0000 006d 0000 0069
-			// 0000020 0000 006e 0000 0020 0000 0051 0000 0041
-			// 0000040
-
-			// (input[i] == 0 && input[i+1] == 0)
-		    output[j] = (char)(((input[i+2] << 8)& 0xff00) + (input[i+3] & 0x00ff));
-		}
-	    j++;
-	    i += 4;
-	}
-	byteOff = inEnd;
-	charOff = j;
-	return j - outStart;
-    }
-
-    public int flush(char[] output, int outStart, int outEnd) {
-	return 0;
-    }
-
-    public void reset() { }
-
-}
diff --git a/pki/base/util/src/netscape/security/util/CharToByteIA5String.java b/pki/base/util/src/netscape/security/util/CharToByteIA5String.java
deleted file mode 100644
index f7c0d1e2d085bad4a3f8c139675247649bebfdf9..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/CharToByteIA5String.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.CharToByteConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts a string of ASN.1 IA5String characters to IA5String bytes.
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class CharToByteIA5String extends CharToByteConverter 
-{
-    /* 
-     * Returns the character set id for the conversion.
-     * @return the character set id.
-     */
-    public String getCharacterEncoding () {
-	return "ASN.1 IA5String";
-    }
-
-    /* 
-     * Converts an array of Unicode characters into an array of IA5String
-     * bytes and returns the total number of characters converted.
-     * If conversion cannot be done, UnknownCharacterException is
-     * thrown. The character and byte offset will be set to the point
-     * of the unknown character. 
-     * @param input character array to convert.
-     * @param inStart offset from which to start the conversion.
-     * @param inEnd where to end the conversion.
-     * @param output byte array to store converted bytes.
-     * @param outStart starting offset in the output byte array.
-     * @param outEnd ending offset in the output byte array.
-     * @return the number of characters converted.
-     */
-    public int convert(char[] input, int inStart, int inEnd,
-		       byte[] output, int outStart, int outEnd)
-	throws ConversionBufferFullException,
-		UnknownCharacterException
-    {
-	int j = outStart;
-	for (int i = inStart; i < inEnd; i++, j++) {
-	    if (j >= outEnd) {
-		charOff = i;
-		byteOff = j;
-		throw new ConversionBufferFullException();
-	    }
-	    if (!subMode && (input[i] & 0xFF80) != 0) {
-		charOff = i;
-		byteOff = j;
-		badInputLength = 1;
-		throw new UnknownCharacterException();
-	    }
-		
-	    output[j] = (byte) (input[i] & 0x7f);
-	}
-	return j - outStart;
-    }
-
-    public int flush(byte[] output, int outStart, int outEnd) {
-	return 0;
-    }
-
-    public void reset() { }
-
-    public int getMaxBytesPerChar() {
-	return 1;
-    }
-}
diff --git a/pki/base/util/src/netscape/security/util/CharToBytePrintable.java b/pki/base/util/src/netscape/security/util/CharToBytePrintable.java
deleted file mode 100644
index 970f7782fc14a3365051871e3b675df4cdbc03f0..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/CharToBytePrintable.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.CharToByteConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.MalformedInputException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts a string of ASN.1 PrintableString characters to PrintableString 
- * bytes.
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class CharToBytePrintable extends CharToByteConverter
-{
-    /*
-     * returns the character set id for the conversion.
-     * @return the character set id.
-     */
-    public String getCharacterEncoding()
-    {
-	return "ASN.1 Printable";
-    }
-
-    public static boolean isPrintableChar( char c ) 
-    {
-	if ((c < 'A' || c > 'Z') &&
-	    (c < 'a' || c > 'z') && 
-	    (c < '0' || c > '9') && 
-	    (c != ' ') && 
-	    (c != '\'') && 
-	    (c != '(') && 
-	    (c != ')') && 
-	    (c != '+') && 
-	    (c != ',') && 
-	    (c != '-') && 
-	    (c != '.') && 
-	    (c != '/') && 
-	    (c != ':') && 
-	    (c != '=') && 
-	    (c != '?')) 
-	{
-	    return false;
-	} else {
-	    return true;
-	}
-    }
-
-    /* 
-     * Converts an array of Unicode characters into an array of Printable
-     * String bytes and returns the total number of characters converted.
-     * If conversion cannot be done, UnknownCharacterException is
-     * thrown. The character and byte offset will be set to the point
-     * of the unknown character. 
-     * @param input character array to convert.
-     * @param inStart offset from which to start the conversion.
-     * @param inEnd where to end the conversion.
-     * @param output byte array to store converted bytes.
-     * @param outStart starting offset in the output byte array.
-     * @param outEnd ending offset in the output byte array.
-     * @return the number of characters converted.
-     */
-    public int convert(char[] input, int inStart, int inEnd, 
-			byte[] output, int outStart, int outEnd)
-	throws MalformedInputException, UnknownCharacterException,
-		ConversionBufferFullException
-    {
- 	int j = outStart;
-	int i;
-	for (i = inStart; i < inEnd ; i++, j++) 
-	{
-	    if (j >= outEnd) {
-		charOff = i;
-		byteOff = j;
-		throw new ConversionBufferFullException();
-	    }
-	    if (!subMode && !isPrintableChar(input[i])) {
-		charOff = i;
-		byteOff = j;
-		badInputLength = 1;
-		throw new UnknownCharacterException();
-	    }
-	    output[j] = (byte) (input[i] & 0x7f);
-	}
-	charOff = i;
-	byteOff = j;
-	return j - outStart;
-    }
-
-    public int flush(byte[] output, int outStart, int outEnd)
-	throws MalformedInputException, ConversionBufferFullException
-    {
-	return 0;
-    }
-
-    public void reset() { }
-
-    public int getMaxBytesPerChar()
-    {
-	return 1;
-    }
-
-}
diff --git a/pki/base/util/src/netscape/security/util/CharToByteUniversalString.java b/pki/base/util/src/netscape/security/util/CharToByteUniversalString.java
deleted file mode 100644
index 0d566d539afcfbdfab6c574af695c03cd3fcbc66..0000000000000000000000000000000000000000
--- a/pki/base/util/src/netscape/security/util/CharToByteUniversalString.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// (C) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-package netscape.security.util;
-
-import sun.io.CharToByteConverter;
-import sun.io.ConversionBufferFullException;
-import sun.io.UnknownCharacterException;
-
-/**
- * Converts a string of ASN.1 IA5String characters to IA5String bytes.
- *
- * @author Lily Hsiao
- * @author Slava Galperin
- */
-
-public class CharToByteUniversalString extends CharToByteConverter
-{
-    /*
-     * Returns the character set id for the conversion.
-     * @return the character set id.
-     */
-    public String getCharacterEncoding () {
-	return "ASN.1 UniversalString";
-    }
-
-    /*
-     * Converts an array of Unicode characters into an array of UniversalString
-     * bytes and returns the total number of characters converted.
-     * If conversion cannot be done, UnknownCharacterException is
-     * thrown. The character and byte offset will be set to the point
-     * of the unknown character.
-     * @param input character array to convert.
-     * @param inStart offset from which to start the conversion.
-     * @param inEnd where to end the conversion.
-     * @param output byte array to store converted bytes.
-     * @param outStart starting offset in the output byte array.
-     * @param outEnd ending offset in the output byte array.
-     * @return the number of characters converted.
-     */
-    public int convert(char[] input, int inStart, int inEnd,
-		       byte[] output, int outStart, int outEnd)
-	throws ConversionBufferFullException,
-		UnknownCharacterException
-    {
-	int j = outStart;
-	for (int i = inStart; i < inEnd; i++) {
-	    if (j+3 >= outEnd) {
-		charOff = i;
-		byteOff = j;
-		throw new ConversionBufferFullException();
-	    }
-        output[j++] = 0;
-        output[j++] = 0;
-	    output[j++] = (byte) ((input[i] >> 8) & 0xff);
-	    output[j++] = (byte) (input[i] & 0xff);
-	}
-
-	return j - outStart;
-    }
-
-    public int flush(byte[] output, int outStart, int outEnd) {
-	return 0;
-    }
-
-    public void reset() { }
-
-    public int getMaxBytesPerChar() {
-	return 4;
-    }
-}
diff --git a/pki/base/util/src/netscape/security/util/DerOutputStream.java b/pki/base/util/src/netscape/security/util/DerOutputStream.java
index be42322fab6fc37bad3ce38baad0533dcef0a5c3..3348ce8748718f2e62b5d99b2b8a363f122c7211 100644
--- a/pki/base/util/src/netscape/security/util/DerOutputStream.java
+++ b/pki/base/util/src/netscape/security/util/DerOutputStream.java
@@ -20,6 +20,10 @@ package netscape.security.util;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -28,8 +32,6 @@ import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.TimeZone;
 
-import sun.io.CharToByteConverter;
-
 /**
  * Output stream marshaling DER-encoded data.  This is eventually provided
  * in the form of a byte array; there is no advance limit on the size of
@@ -541,36 +543,21 @@ extends ByteArrayOutputStream implements DerEncoder {
 	putStringType(DerValue.tag_UTF8String, s);
     }
 
-    public void putStringType(byte tag, String s) throws IOException
-    {
-	int next_byte_index;
-	CharToByteConverter cbc;
-	byte buf[];
-	try {
-	    cbc = ASN1CharStrConvMap.getDefault().getCBC(tag);
-	    if (cbc == null)
-		throw new IOException("No character to byte converter for tag");
-	    buf= new byte[cbc.getMaxBytesPerChar()*s.length()];
-	    // Don't use convertAll() here b/c it does not throw
-	    // UnknownCharacterException.
-	    next_byte_index = cbc.convert(s.toCharArray(), 0, s.length(), buf, 0, buf.length);
-	}
-	catch (java.io.CharConversionException e) {
-	    throw new IOException("Not a valid string type "+ tag);
-	}
-	catch (IllegalAccessException e) {
-	    throw new IOException("Cannot load CharToByteConverter class "+
-				  "for DER tag "+tag);
-	}
-	catch (InstantiationException e) {
-	    throw new IOException("Cannot instantiate CharToByteConverter "+
-				  "class for DER tag "+tag);
-	}
+    public void putStringType(byte tag, String s) throws IOException {
+        try {
+            CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tag);
+            if (encoder == null) throw new IOException("No encoder for tag");
 
-	//next_byte_index = cbc.nextByteIndex();
-	write(tag);
-	putLength(next_byte_index);
-	write(buf, 0, next_byte_index);
+            CharBuffer charBuffer = CharBuffer.wrap(s.toCharArray());
+            ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+            write(tag);
+            putLength(byteBuffer.limit());
+            write(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+        } catch (CharacterCodingException e) {
+            throw new IOException("Not a valid string type "+tag, e);
+        }
     }
 
     private void put2DateBytes(byte[] buffer, int value, int offset)
diff --git a/pki/base/util/src/netscape/security/util/DerValue.java b/pki/base/util/src/netscape/security/util/DerValue.java
index 58ef8eccc46a2e3fa05dcf625cb6386e958efca0..14ec33e85412c129fc45c179ada8ee238c32d555 100644
--- a/pki/base/util/src/netscape/security/util/DerValue.java
+++ b/pki/base/util/src/netscape/security/util/DerValue.java
@@ -21,10 +21,14 @@ import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.util.Arrays;
 
 import netscape.security.x509.AVAValueConverter;
 import netscape.security.x509.GenericValueConverter;
-import sun.io.ByteToCharConverter;
 
 /**
  * Represents a single DER-encoded value.  DER encoding rules are a subset
@@ -198,11 +202,23 @@ public class DerValue {
      * @param data the DER-encoded data
      */
     public DerValue(byte tag, byte[] data) {
-	this.tag = tag;
-	buffer = new DerInputBuffer((byte[])data.clone());
-	length = data.length;
-	this.data = new DerInputStream (buffer);
-	this.data.mark (Integer.MAX_VALUE);
+        this.tag = tag;
+        buffer = new DerInputBuffer(data.clone());
+        length = data.length;
+        this.data = new DerInputStream(buffer);
+        this.data.mark(Integer.MAX_VALUE);
+    }
+
+    /**
+     * Creates a DerValue from a tag and some DER-encoded data.
+     *
+     * @param tag the DER type tag
+     * @param data the DER-encoded data
+     * @param offset offset of the data
+     * @param length length of the data
+     */
+    public DerValue(byte tag, byte[] data, int offset, int length) {
+        this(tag, Arrays.copyOfRange(data, offset, offset+length));
     }
 
     /*
@@ -509,37 +525,24 @@ public class DerValue {
 
     /*
      * @eturns a string if the DerValue is a ASN.1 character string type and
-     * if there is a ByteToChar converter for the type. Returns null otherwise.
+     * if there is a decoder for the type. Returns null otherwise.
      */
-    public String getASN1CharString()
-	throws IOException
-    {
-	ByteToCharConverter bcc;
-	int ret;
-	byte buf[];
-	char cbuf[];
+    public String getASN1CharString() throws IOException {
+        try {
+            CharsetDecoder decoder = ASN1CharStrConvMap.getDefault().getDecoder(tag);
+            if (decoder == null) return null;
 
-	try {
-	    bcc = ASN1CharStrConvMap.getDefault().getBCC(tag);
-	    if (bcc == null)
-		return null;
+            ByteBuffer byteBuffer = ByteBuffer.allocate(length);
 
-	    buf = new byte[length];
-	    cbuf = new char[bcc.getMaxCharsPerByte()*length];
-	    data.reset();
-	    data.getBytes(buf);
-	    ret = bcc.convert(buf, 0, buf.length, cbuf, 0, cbuf.length);
-	}
-	catch (java.io.CharConversionException e) {
-	    throw new IOException("Misformed DER value");
-	}
-	catch (IllegalAccessException e) {
-	    throw new IOException("Illegal Access loading ByteToCharConverter");
-	}
-	catch (InstantiationException e) {
-	    throw new IOException("Cannot instantiate ByteToCharConverter");
-	}
-	return new String(cbuf, 0, ret);
+            data.reset();
+            data.getBytes(byteBuffer.array());
+
+            CharBuffer charBuffer = decoder.decode(byteBuffer);
+            return charBuffer.toString();
+
+        } catch (CharacterCodingException e) {
+            throw new IOException("Misformed DER value", e);
+        }
     }
 
     /**
diff --git a/pki/base/util/src/netscape/security/util/IA5Charset.java b/pki/base/util/src/netscape/security/util/IA5Charset.java
new file mode 100644
index 0000000000000000000000000000000000000000..db6da2331748ea372a31a38ae806302d7cb63976
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/IA5Charset.java
@@ -0,0 +1,24 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class IA5Charset extends Charset {
+
+    public IA5Charset() {
+        super("ASN.1-IA5", null);
+    }
+
+    public boolean contains(Charset cs) {
+        return false;
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new IA5CharsetDecoder(this);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new IA5CharsetEncoder(this);
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/IA5CharsetDecoder.java b/pki/base/util/src/netscape/security/util/IA5CharsetDecoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..f23bd8544babfb564d6e3b10ef44be486dcb7a02
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/IA5CharsetDecoder.java
@@ -0,0 +1,62 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 IA5String character set to unicode
+ * characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class IA5CharsetDecoder extends CharsetDecoder {
+
+    public IA5CharsetDecoder(Charset cs) {
+        super(cs, 1, 1);
+    }
+
+    protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+        while (true) {
+
+            if (in.remaining() < 1) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            byte b = in.get();
+
+            if (CodingErrorAction.REPORT == unmappableCharacterAction() && (b & 0x80) != 0) {
+                return CoderResult.unmappableForLength(1);
+            }
+
+            if (out.remaining() < 1) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put((char)(b & 0x7f));
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/IA5CharsetEncoder.java b/pki/base/util/src/netscape/security/util/IA5CharsetEncoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..75c0eed31d59fd0ff8177bf4964cb6b92ec3228e
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/IA5CharsetEncoder.java
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts a string of ASN.1 IA5String characters to IA5String bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class IA5CharsetEncoder extends CharsetEncoder {
+
+    public IA5CharsetEncoder(Charset cs) {
+        super(cs, 1, 1);
+    }
+
+    /*
+     * Converts an array of Unicode characters into an array of IA5String
+     * String bytes and returns the conversion result.
+     * @param in input character buffer to convert.
+     * @param out byte buffer to store output.
+     * @return encoding result.
+     */
+    protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+        while (true) {
+
+            if (in.remaining() < 1) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            char c = in.get();
+
+            if (CodingErrorAction.REPORT == unmappableCharacterAction() && (c & 0xFF80) != 0) {
+                return CoderResult.unmappableForLength(1);
+            }
+
+            if (out.remaining() < 1) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put((byte)(c & 0x7f));
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/PrintableCharset.java b/pki/base/util/src/netscape/security/util/PrintableCharset.java
new file mode 100644
index 0000000000000000000000000000000000000000..676d64cdd426ae18879cbdedf217ed8b3ef94928
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/PrintableCharset.java
@@ -0,0 +1,24 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class PrintableCharset extends Charset {
+
+    public PrintableCharset() {
+        super("ASN.1-Printable", null);
+    }
+
+    public boolean contains(Charset cs) {
+        return false;
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new PrintableCharsetDecoder(this);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new PrintableCharsetEncoder(this);
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/PrintableCharsetDecoder.java b/pki/base/util/src/netscape/security/util/PrintableCharsetDecoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..650fa7736efda15bda7d99eb9abf7943630c12cf
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/PrintableCharsetDecoder.java
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 Printable String character set to unicode
+ * characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class PrintableCharsetDecoder extends CharsetDecoder {
+
+    public PrintableCharsetDecoder(Charset cs) {
+        super(cs, 1, 1);
+    }
+
+    protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+        while (true) {
+
+            if (in.remaining() < 1) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            byte b = in.get();
+            char c = (char)(b & 0x7f);
+
+            if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+                !PrintableCharsetEncoder.isPrintableChar(c)) {
+                /*
+                "bug" fix for 359010
+                return CoderResult.unmappableForLength(1);
+                */
+                continue;
+            }
+
+            if (out.remaining() < 1) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put(c);
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/PrintableCharsetEncoder.java b/pki/base/util/src/netscape/security/util/PrintableCharsetEncoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9463ee45cc3046f51669661ef5ab5c0d5a2e7a1
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/PrintableCharsetEncoder.java
@@ -0,0 +1,92 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts a string of ASN.1 PrintableString characters to PrintableString
+ * bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class PrintableCharsetEncoder extends CharsetEncoder {
+
+    public PrintableCharsetEncoder(Charset cs) {
+        super(cs, 1, 1);
+    }
+
+    public static boolean isPrintableChar(char c) {
+        if ((c < 'A' || c > 'Z') &&
+            (c < 'a' || c > 'z') &&
+            (c < '0' || c > '9') &&
+            (c != ' ') &&
+            (c != '\'') &&
+            (c != '(') &&
+            (c != ')') &&
+            (c != '+') &&
+            (c != ',') &&
+            (c != '-') &&
+            (c != '.') &&
+            (c != '/') &&
+            (c != ':') &&
+            (c != '=') &&
+            (c != '?')) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /*
+     * Converts an array of Unicode characters into an array of Printable
+     * String bytes and returns the conversion result.
+     * @param in input character buffer to convert.
+     * @param out byte buffer to store output.
+     * @return encoding result.
+     */
+    protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+        while (true) {
+
+            if (in.remaining() < 1) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            char c = in.get();
+
+            if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+                !PrintableCharsetEncoder.isPrintableChar(c)) {
+                return CoderResult.unmappableForLength(1);
+            }
+
+            if (out.remaining() < 1) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put((byte)(c & 0x7f));
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/UniversalCharset.java b/pki/base/util/src/netscape/security/util/UniversalCharset.java
new file mode 100644
index 0000000000000000000000000000000000000000..59cc3c6f4ba391abaf34a4e302328e86aa7d8e5d
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/UniversalCharset.java
@@ -0,0 +1,24 @@
+package netscape.security.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+
+public class UniversalCharset extends Charset {
+
+    public UniversalCharset() {
+        super("ASN.1-Universal", null);
+    }
+
+    public boolean contains(Charset cs) {
+        return false;
+    }
+
+    public CharsetDecoder newDecoder() {
+        return new UniversalCharsetDecoder(this);
+    }
+
+    public CharsetEncoder newEncoder() {
+        return new UniversalCharsetEncoder(this);
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/UniversalCharsetDecoder.java b/pki/base/util/src/netscape/security/util/UniversalCharsetDecoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4c672a24e97772840f8ee984bf448f1872a19a3
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/UniversalCharsetDecoder.java
@@ -0,0 +1,97 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Converts bytes in ASN.1 UniversalString character set to unicode
+ * characters.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class UniversalCharsetDecoder extends CharsetDecoder {
+
+    public UniversalCharsetDecoder(Charset cs) {
+        super(cs, 0.25f, 0.25f);
+    }
+
+    protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
+
+        while (true) {
+            // XXX we do not know what to do with truly UCS-4 characters here
+            // we also assumed network byte order
+
+            if (in.remaining() < 4) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            byte b0 = in.get();
+            byte b1 = in.get();
+            byte b2 = in.get();
+            byte b3 = in.get();
+
+            if (CodingErrorAction.REPORT == unmappableCharacterAction() &&
+                !((b0 == 0 && b1 == 0) || (b2 == 0 && b3 == 0))) {
+                return CoderResult.unmappableForLength(4);
+            }
+
+            char c;
+            if (b2 == 0 && b3 == 0) {
+                // Try to be a bit forgiving. If the byte order is
+                // reversed, we still try handle it.
+
+                // Sample Date Set (1):
+                // 0000000   f   0  \0  \0 213   0  \0  \0   S   0  \0  \0
+                // 0000014
+
+                // Sample Date Set (2):
+                // 0000000   w  \0  \0  \0   w  \0  \0  \0   w  \0  \0  \0   .  \0  \0  \0
+                // 0000020   (  \0  \0  \0   t  \0  \0  \0   o  \0  \0  \0   b  \0  \0  \0
+                // 0000040   e  \0  \0  \0   |  \0  \0  \0   n  \0  \0  \0   o  \0  \0  \0
+                // 0000060   t  \0  \0  \0   t  \0  \0  \0   o  \0  \0  \0   b  \0  \0  \0
+                // 0000100   e  \0  \0  \0   )  \0  \0  \0   .  \0  \0  \0   c  \0  \0  \0
+                // 0000120   o  \0  \0  \0   m  \0  \0  \0
+                // 0000130
+                c = (char)(((b1 << 8) & 0xff00) + (b0 & 0x00ff));
+
+            } else { // (b0 == 0 && b1 == 0)
+                // This should be the right order.
+                //
+                // 0000000 0000 00c4 0000 0064 0000 006d 0000 0069
+                // 0000020 0000 006e 0000 0020 0000 0051 0000 0041
+                // 0000040
+
+                c = (char)(((b2 << 8) & 0xff00) + (b3 & 0x00ff));
+            }
+
+            if (out.remaining() < 1) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put(c);
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/util/UniversalCharsetEncoder.java b/pki/base/util/src/netscape/security/util/UniversalCharsetEncoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5775888a1a9a037e0d55ba224a1582a16531cee
--- /dev/null
+++ b/pki/base/util/src/netscape/security/util/UniversalCharsetEncoder.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.util;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * Converts a string of ASN.1 IA5String characters to IA5String bytes.
+ *
+ * @author Lily Hsiao
+ * @author Slava Galperin
+ */
+
+public class UniversalCharsetEncoder extends CharsetEncoder {
+
+    public UniversalCharsetEncoder(Charset cs) {
+        super(cs, 4, 4);
+    }
+
+    /*
+     * Converts an array of Unicode characters into an array of UniversalString
+     * String bytes and returns the conversion result.
+     * @param in input character buffer to convert.
+     * @param out byte buffer to store output.
+     * @return encoding result.
+     */
+    protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
+
+        while (true) {
+
+            if (in.remaining() < 1) return CoderResult.UNDERFLOW;
+
+            in.mark();
+            char c = in.get();
+
+            if (out.remaining() < 4) {
+                in.reset();
+                return CoderResult.OVERFLOW;
+            }
+
+            out.put((byte)0);
+            out.put((byte)0);
+            out.put((byte)((c >> 8) & 0xff));
+            out.put((byte)(c & 0x7f));
+        }
+    }
+}
diff --git a/pki/base/util/src/netscape/security/x509/AVA.java b/pki/base/util/src/netscape/security/x509/AVA.java
index 0614f41caa541964b19a8bad063d726ca6969073..d35426d316ab2f6b7d85d403c87ffb3cee62df96 100644
--- a/pki/base/util/src/netscape/security/x509/AVA.java
+++ b/pki/base/util/src/netscape/security/x509/AVA.java
@@ -20,13 +20,17 @@ package netscape.security.x509;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.UnsupportedCharsetException;
 
 import netscape.security.util.DerEncoder;
 import netscape.security.util.DerInputStream;
 import netscape.security.util.DerOutputStream;
 import netscape.security.util.DerValue;
 import netscape.security.util.ObjectIdentifier;
-import sun.io.ByteToCharConverter;
 
 
 /**
@@ -127,28 +131,24 @@ public final class AVA implements DerEncoder
      * @see LdapDNStrConverter
      * @param in the input stream.
      */
-    public AVA (InputStream in) throws IOException
-    {
-	StringBuffer	temp = new StringBuffer ();
-	AVA 		a;
-	byte[]		buf = new byte[in.available()];
-	char[]		converted_chars;
-	ByteToCharConverter bcc;
+    public AVA(InputStream in) throws IOException {
+        try {
+            // convert from UTF8 bytes to java string then parse it.
+            byte[] buffer = new byte[in.available()];
+            in.read(buffer);
 
-	// convert from UTF8 bytes to java string then parse it.
-	in.read(buf);
-	try {
-	    bcc = ByteToCharConverter.getConverter("UTF8");
-	}
-	catch (java.io.UnsupportedEncodingException e) {
-	    throw new IOException("UTF8 encoding not supported");
-	}
-	converted_chars = bcc.convertAll(buf);
-	temp.append(converted_chars);
+            Charset charset = Charset.forName("UTF-8");
+            CharsetDecoder decoder = charset.newDecoder();
 
-	a = LdapDNStrConverter.getDefault().parseAVA(temp.toString());
-	oid = a.getOid();
-	value = a.getValue();
+            CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer));
+
+            AVA a = LdapDNStrConverter.getDefault().parseAVA(charBuffer.toString());
+            oid = a.getOid();
+            value = a.getValue();
+
+        } catch (UnsupportedCharsetException e) {
+            throw new IOException("UTF8 encoding not supported", e);
+        }
     }
 
     /**
diff --git a/pki/base/util/src/netscape/security/x509/DirStrConverter.java b/pki/base/util/src/netscape/security/x509/DirStrConverter.java
index 261a909d10555b7479d60725fd1de68826967a48..f6ade91aa113dfd1bb603fed8d86b1a3cd743508 100644
--- a/pki/base/util/src/netscape/security/x509/DirStrConverter.java
+++ b/pki/base/util/src/netscape/security/x509/DirStrConverter.java
@@ -18,10 +18,13 @@
 package netscape.security.x509;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
 
 import netscape.security.util.ASN1CharStrConvMap;
 import netscape.security.util.DerValue;
-import sun.io.CharToByteConverter;
 
 /**
  * A DirStrConverter converts a string to a DerValue of ASN.1 Directory String,
@@ -31,10 +34,10 @@ import sun.io.CharToByteConverter;
  * <p>The string to DerValue conversion is done as follows.
  * If the string has only PrintableString characters it is converted
  * to a ASN.1 Printable String using the PrintableString
- * CharToByteConverter from the global default ASN1CharStrConvMap.
+ * encoder from the global default ASN1CharStrConvMap.
  * If it has only characters covered in the PrintableString or T.61
  * character set it is converted to a ASN.1 T.61 string using the T.61
- * CharToByteConverter from the ASN1CharStrCovnMap.
+ * encoder from the ASN1CharStrCovnMap.
  * Otherwise it is converted to a ASN.1 UniversalString (UCS-4 character set)
  * which covers all characters.
  *
@@ -68,7 +71,7 @@ public class DirStrConverter implements AVAValueConverter
      * @return 		a DerValue
      *
      * @exception IOException	 if the string cannot be converted, such as
-     *				 when a UniversalString CharToByteConverter
+     *				 when a UniversalString encoder
      *				 isn't available and the string contains
      *				 characters covered only in the universal
      *				 string (or UCS-4) character set.
@@ -95,51 +98,29 @@ public class DirStrConverter implements AVAValueConverter
     /**
      * Like getValue(String) with specified DER tags as encoding order.
      */
-    public DerValue getValue(String ds, byte[] tags)
-	throws IOException
-    {
-	// try to convert to printable, then t61 the universal -
-	// i.e. from minimal to the most liberal.
+    public DerValue getValue(String valueString, byte[] tags) throws IOException {
+        // try to convert to printable, then t61 the universal -
+        // i.e. from minimal to the most liberal.
 
-	int ret = -1;
-	CharToByteConverter cbc;
-	DerValue value;
-	byte[] bbuf, derBuf;
-	int i;
+        if (tags == null || tags.length == 0) tags = DefEncodingOrder;
 
-	if (tags == null || tags.length == 0) 
-		tags = DefEncodingOrder;
+        for (int i = 0; i < tags.length; i++) {
+            try {
+                CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]);
+                if (encoder == null) continue;
 
-	bbuf = new byte[4*ds.length()];
-	for (i = 0; i < tags.length; i++)
-	{
-	    try {
-		cbc = ASN1CharStrConvMap.getDefault().getCBC(tags[i]);
-		if (cbc == null)
-		    continue;
-		ret = cbc.convert(ds.toCharArray(), 0, ds.length(),
-				  bbuf, 0, bbuf.length);
-		break;
-	    }
-	    catch (java.io.CharConversionException e) {
-		continue;
-	    }
-	    catch (InstantiationException e) {
-		throw new IOException("Cannot instantiate CharToByteConverter");
-	    }
-	    catch (IllegalAccessException e) {
-		throw new IOException(
-			"Illegal Access loading CharToByteConverter");
-	    }
-	}
-	if (ret == -1) {
-	    throw new IOException(
-		"Cannot convert the directory string value to a ASN.1 type");
-	}
+                CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+                ByteBuffer byteBuffer = encoder.encode(charBuffer);
 
-	derBuf = new byte[ret];
-	System.arraycopy(bbuf, 0, derBuf, 0, ret);
-	return new DerValue(tags[i], derBuf);
+                return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+            } catch (CharacterCodingException e) {
+                continue;
+            }
+        }
+
+        throw new IOException(
+            "Cannot convert the directory string value to a ASN.1 type");
     }
 
     /**
@@ -177,7 +158,7 @@ public class DirStrConverter implements AVAValueConverter
      *
      * @param avaValue 	a DerValue
      * @return 		a string if the value can be converted.
-     * @exception IOException  	if a ByteToCharConverter needed for the
+     * @exception IOException  	if a decoder needed for the
      *				conversion is not available.
      */
     public String getAsString(DerValue avaValue)
@@ -190,7 +171,7 @@ public class DirStrConverter implements AVAValueConverter
             avaValue.tag != DerValue.tag_T61String)
 	    throw new IllegalArgumentException(
 		"Invalid Directory String value");
-	// NOTE will return null if a ByteToCharConverter is not available.
+	// NOTE will return null if a decoder is not available.
 	*/
 	return avaValue.getASN1CharString();
     }
diff --git a/pki/base/util/src/netscape/security/x509/GenericValueConverter.java b/pki/base/util/src/netscape/security/x509/GenericValueConverter.java
index 5c906d09f1d74e4f456feff3952d54f09c4cefb4..64377e6eb45c83c045fcd075e1712f7a380018fc 100644
--- a/pki/base/util/src/netscape/security/x509/GenericValueConverter.java
+++ b/pki/base/util/src/netscape/security/x509/GenericValueConverter.java
@@ -18,10 +18,13 @@
 package netscape.security.x509;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
 
 import netscape.security.util.ASN1CharStrConvMap;
 import netscape.security.util.DerValue;
-import sun.io.CharToByteConverter;
 
 /**
  * A GenericValueConverter converts a string that is not associated with 
@@ -30,9 +33,9 @@ import sun.io.CharToByteConverter;
  * Universal String.
  * 
  * <p>The conversion is done as follows. 
- * A CharToByteConverter is obtained for the all the character sets 
+ * An encoder is obtained for the all the character sets
  * from the global default ASN1CharStrConvMap.
- * The CharToByteConverters are then used to convert the string to the 
+ * The encoders are then used to convert the string to the
  * smallest character set first -- printableString. 
  * If the string contains characters outside of that character set, 
  * it is converted to the next character set -- IA5String character set. 
@@ -54,18 +57,18 @@ public class GenericValueConverter implements AVAValueConverter
      * as a PrintableString, IA5String, T.61String, BMPString or  
      * UniversalString. The string is not expected to be encoded in any form.
      * 
-     * <p>If a CharToByteConverter is not available for a character set that
+     * <p>If an encoder is not available for a character set that
      * is needed to convert the string, the string cannot be converted and 
      * an IOException is thrown. For example, if the string contains characters 
      * outside the PrintableString character and only a PrintableString 
-     * CharToByteConverter is available then an IOException is thrown.
+     * encoder is available then an IOException is thrown.
      * 
      * @param s 	A string representing a generic attribute string value.
      *
      * @return 		The DER value of the attribute.
      * 
      * @exception IOException	 if the string cannot be converted, such as 
-     *				 when a CharToByteConverter needed is 
+     *				 when an encoder needed is
      *				 unavailable.
      */
     public DerValue getValue(String s)
@@ -74,50 +77,29 @@ public class GenericValueConverter implements AVAValueConverter
 	return getValue(s, null);
     }
 
-    public DerValue getValue(String s, byte[] tags)
-	throws IOException
-    {
-	// try to convert to printable, then t61 the universal -  
-	// i.e. from minimal coverage to the broadest.
-	int ret = -1;
-	CharToByteConverter cbc;
-	DerValue value;
-	byte[] bbuf, derBuf;
-	int i;
+    public DerValue getValue(String valueString, byte[] tags) throws IOException {
+        // try to convert to printable, then t61 the universal -
+        // i.e. from minimal coverage to the broadest.
 
-	if (tags == null || tags.length == 0)
-		tags = DefEncodingTags;
+        if (tags == null || tags.length == 0) tags = DefEncodingTags;
 
-	bbuf = new byte[4*s.length()];
-	for (i = 0; i < tags.length; i++) 
-	{
-	    try {
-		cbc = ASN1CharStrConvMap.getDefault().getCBC(tags[i]);
-		if (cbc == null)
-		    continue;
-		ret = cbc.convert(s.toCharArray(), 0, s.length(), 
-				  bbuf, 0, bbuf.length);
-		break;
-	    } 
-	    catch (java.io.CharConversionException e) {
-		continue;
-	    } 
-	    catch (InstantiationException e) {
-		throw new IOException("Cannot instantiate CharToByteConverter");
-	    } 
-	    catch (IllegalAccessException e) {
-		throw new IOException(
-			"Illegal Access loading CharToByteConverter");
-	    }
-	}
-	if (ret == -1) {
-	    throw new IllegalArgumentException(
-		"Cannot convert the string value to a ASN.1 type");
-	}
+        for (int i = 0; i < tags.length; i++) {
+            try {
+                CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(tags[i]);
+                if (encoder == null) continue;
 
-	derBuf = new byte[ret];
-	System.arraycopy(bbuf, 0, derBuf, 0, ret);
-	return new DerValue(tags[i], derBuf);
+                CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+                ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+                return new DerValue(tags[i], byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+            } catch (CharacterCodingException e) {
+                continue;
+            }
+        }
+
+        throw new IOException(
+            "Cannot convert the string value to a ASN.1 type");
     }
 
     /** 
@@ -146,7 +128,7 @@ public class GenericValueConverter implements AVAValueConverter
      * 
      * @param avaValue 	A DerValue
      * @return 		A string representing the attribute value.
-     * @exception IOException  	if a ByteToCharConverter needed for the 
+     * @exception IOException  	if a decoder needed for the
      *				conversion is not available or if BER value 
      *				is not one of the ASN1 character string types
      *				here.
diff --git a/pki/base/util/src/netscape/security/x509/IA5StringConverter.java b/pki/base/util/src/netscape/security/x509/IA5StringConverter.java
index f3fa50da06a19cc19755ceda74968236099d517d..fe3e3eb18b698f7fbf0b2049fce6d8d34db33afb 100644
--- a/pki/base/util/src/netscape/security/x509/IA5StringConverter.java
+++ b/pki/base/util/src/netscape/security/x509/IA5StringConverter.java
@@ -18,10 +18,13 @@
 package netscape.security.x509;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
 
 import netscape.security.util.ASN1CharStrConvMap;
 import netscape.security.util.DerValue;
-import sun.io.CharToByteConverter;
 
 /**
  * A AVAValueConverter that converts a IA5String attribute to a DerValue 
@@ -49,7 +52,7 @@ public class IA5StringConverter implements AVAValueConverter
      * 
      * @return			a DerValue. 
      * 
-     * @exception IOException	if a IA5String CharToByteConverter is not 
+     * @exception IOException	if a IA5String encoder is not
      *				available for the conversion.
      */
     public DerValue getValue(String valueString)
@@ -58,29 +61,20 @@ public class IA5StringConverter implements AVAValueConverter
 	return getValue(valueString, null);
     }
 
-    public DerValue getValue(String valueString, byte[] encodingOrder)
-	throws IOException
-    {
-	ASN1CharStrConvMap map;
-	CharToByteConverter cbc;
-	byte[] bbuf = new byte[valueString.length()];
-	map = ASN1CharStrConvMap.getDefault();
-	try {
-	    cbc = map.getCBC(DerValue.tag_IA5String);
-	    if (cbc == null)
-		throw new IOException("No CharToByteConverter for IA5String");
-	    cbc.convert(valueString.toCharArray(), 0, valueString.length(), 
-			bbuf, 0, bbuf.length);
-	}
-	catch (java.io.CharConversionException e) {
-	    throw new IllegalArgumentException(
-		"Invalid IA5String AVA Value string");
-	} catch (InstantiationException e) {
-	    throw new IOException("Cannot instantiate CharToByteConverter");
-	} catch (IllegalAccessException e) {
-	    throw new IOException("Illegal access loading CharToByteConverter");
-	}
-	return new DerValue(DerValue.tag_IA5String, bbuf);
+    public DerValue getValue(String valueString, byte[] tags) throws IOException {
+        try {
+            CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_IA5String);
+            if (encoder == null) throw new IOException("No encoder for IA5String");
+
+            CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+            ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+            return new DerValue(DerValue.tag_IA5String,
+                byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+        } catch (CharacterCodingException e) {
+            throw new IllegalArgumentException("Invalid IA5String AVA Value string");
+        }
     }
 
     /*
diff --git a/pki/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java b/pki/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java
index 8203d9b085e4fa3687eabd7724190a879036bed0..0c845decd03ebaf2a08b07049adbc36473a60636 100644
--- a/pki/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java
+++ b/pki/base/util/src/netscape/security/x509/LdapV3DNStrConverter.java
@@ -23,11 +23,17 @@ import java.io.IOException;
 import java.io.PushbackReader;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Arrays;
 import java.util.Vector;
 
 import netscape.security.util.DerValue;
 import netscape.security.util.ObjectIdentifier;
-import sun.io.ByteToCharConverter;
 
 /**
  * A converter that converts Ldap v3 DN strings as specified in
@@ -835,46 +841,32 @@ public class LdapV3DNStrConverter extends LdapDNStrConverter
      * Parse a sequence of hex pairs, each pair a UTF8 byte to a java string.
      * For example, "4C75C48D" is "Luc", the last c with caron.
      */
-    protected static char[] getStringFromHexpairs(char[] hexPairs)
-	throws UnsupportedEncodingException
-    {
-	ByteToCharConverter utf8_bcc;
-	byte utf8_buf[];
-	char char_buf[];
-	int ret;
-	int i,j;
+    protected static char[] getStringFromHexpairs(char[] hexPairs) throws UnsupportedEncodingException {
+        try {
+            byte[] buffer = new byte[hexPairs.length/2];
 
-	try {
-	    utf8_bcc = ByteToCharConverter.getConverter("UTF8");
-	}
-	catch (UnsupportedEncodingException e) {
-	    throw new UnsupportedEncodingException(
-		"No UTF8 byte to char converter to use for "+
-		"parsing LDAP DN String");
-	}
-	utf8_bcc.setSubstitutionMode(false);
+            for (int i=0; i < buffer.length; i++) {
+                buffer[i] = (byte)
+                    ((Character.digit( hexPairs[i*2], 16 ) << 4) +
+                    Character.digit( hexPairs[i*2+1], 16 ));
+            }
 
-	utf8_buf = new byte[hexPairs.length/2];
-	char_buf = new char[utf8_buf.length*utf8_bcc.getMaxCharsPerByte()];
+            Charset charset = Charset.forName("UTF-8");
+            CharsetDecoder decoder = charset.newDecoder();
 
-	for ( i=0,j=0 ; i < hexPairs.length ; i++,j++ )
-	{
-	    utf8_buf[j] = (byte)
-			  ((Character.digit( hexPairs[i++], 16 ) << 4) +
-		  	    Character.digit( hexPairs[i], 16 ));
-	}
-	try {
-	    ret = utf8_bcc.convert( utf8_buf, 0, utf8_buf.length,
-				    char_buf, 0, char_buf.length );
-	}
-	catch (java.io.CharConversionException e) {
-	    throw new IllegalArgumentException(
-		"Invalid hex pair in LDAP DN String." );
-	}
+            CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(buffer));
 
-	char [] out_buf = new char[ ret ];
-	System.arraycopy( char_buf, 0, out_buf, 0, ret );
-	return out_buf;
+            return Arrays.copyOfRange(charBuffer.array(),
+                    charBuffer.arrayOffset(), charBuffer.arrayOffset() + charBuffer.limit());
+
+        } catch (UnsupportedCharsetException e) {
+            throw new UnsupportedEncodingException(
+                "No UTF8 byte to char converter to use for "+
+                "parsing LDAP DN String");
+
+        } catch (CharacterCodingException e) {
+            throw new IllegalArgumentException(
+                "Invalid hex pair in LDAP DN String.");
+        }
     }
-
 }
diff --git a/pki/base/util/src/netscape/security/x509/PrintableConverter.java b/pki/base/util/src/netscape/security/x509/PrintableConverter.java
index b4c58739def5e783c6b4246b632b10c81b235f46..b3bcd7322d88812af45d7385ce5e48002dbaf464 100644
--- a/pki/base/util/src/netscape/security/x509/PrintableConverter.java
+++ b/pki/base/util/src/netscape/security/x509/PrintableConverter.java
@@ -18,10 +18,13 @@
 package netscape.security.x509;
 
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetEncoder;
 
 import netscape.security.util.ASN1CharStrConvMap;
 import netscape.security.util.DerValue;
-import sun.io.CharToByteConverter;
 
 /**
  * A AVAValueConverter that converts a Printable String attribute to a DerValue 
@@ -48,7 +51,7 @@ public class PrintableConverter implements AVAValueConverter
      * 
      * @return			a DerValue. 
      * 
-     * @exception IOException	if a Printable CharToByteConverter is not 
+     * @exception IOException	if a Printable encoder is not
      *				available for the conversion.
      */
     public DerValue getValue(String valueString)
@@ -57,31 +60,20 @@ public class PrintableConverter implements AVAValueConverter
 	return getValue(valueString, null);
     }
 
-    public DerValue getValue(String valueString, byte[] encodingOrder)
-	throws IOException
-    {
-	CharToByteConverter printable;
-	byte[] bbuf = new byte[valueString.length()];
-	try {
-	    printable = ASN1CharStrConvMap.getDefault().getCBC(
-				DerValue.tag_PrintableString);
-	    if (printable == null) {
-		throw new IOException("No CharToByteConverter for printable");
-	    }
-	    printable.convert(valueString.toCharArray(), 0, 
-			      valueString.length(), bbuf, 0, bbuf.length);
-	}
-	catch (java.io.CharConversionException e) {
-	    throw new IllegalArgumentException(
-			"Invalid Printable String AVA Value");
-	}
-	catch (InstantiationException e) {
-	    throw new IOException("Cannot instantiate CharToByteConverter");
-	}
-	catch (IllegalAccessException e) {
-	    throw new IOException("Cannot load CharToByteConverter");
-	}
-	return new DerValue(DerValue.tag_PrintableString, bbuf);
+    public DerValue getValue(String valueString, byte[] tags) throws IOException {
+        try {
+            CharsetEncoder encoder = ASN1CharStrConvMap.getDefault().getEncoder(DerValue.tag_PrintableString);
+            if (encoder == null) throw new IOException("No encoder for printable");
+
+            CharBuffer charBuffer = CharBuffer.wrap(valueString.toCharArray());
+            ByteBuffer byteBuffer = encoder.encode(charBuffer);
+
+            return new DerValue(DerValue.tag_PrintableString,
+                byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.limit());
+
+        } catch (CharacterCodingException e) {
+            throw new IllegalArgumentException("Invalid Printable String AVA Value", e);
+        }
     }
 
     /**
-- 
1.7.5.1

