You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/01/12 14:06:16 UTC

[08/50] [abbrv] directory-kerberos git commit: Renaming packages in contrib projects, using "apache"

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralString.java
new file mode 100644
index 0000000..a76931b
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralString.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1GeneralString extends Asn1String
+{
+    public Asn1GeneralString() {
+        super(UniversalTag.GENERAL_STRING);
+    }
+
+    public Asn1GeneralString(String value) {
+        super(UniversalTag.GENERAL_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralizedTime.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralizedTime.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralizedTime.java
new file mode 100644
index 0000000..d2e53fc
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1GeneralizedTime.java
@@ -0,0 +1,115 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+public class Asn1GeneralizedTime extends Asn1Simple<Date>
+{
+    public Asn1GeneralizedTime() {
+        this(null);
+    }
+
+    /**
+     * time in milliseconds
+     */
+    public Asn1GeneralizedTime(long time) {
+        super(UniversalTag.GENERALIZED_TIME, new Date(time));
+    }
+
+    public Asn1GeneralizedTime(Date date) {
+        super(UniversalTag.UTC_TIME, date);
+    }
+
+    protected void toValue() throws IOException {
+        String dateStr = new String(getBytes(), StandardCharsets.US_ASCII);
+        SimpleDateFormat sdf;
+        String fixedDateStr = dateStr;
+
+        boolean withZ = dateStr.endsWith("Z");
+        String timeZonePart = getTimeZonePart(dateStr);
+        boolean withZone = timeZonePart != null;
+        String millSecs = getMillSeconds(dateStr);
+
+        fixedDateStr = dateStr.substring(0, 14) + millSecs;
+        if (withZ) {
+            sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+            sdf.setTimeZone(new SimpleTimeZone(0, "Z"));
+        } else if (withZone) {
+            fixedDateStr += timeZonePart;
+            sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSz");
+            sdf.setTimeZone(new SimpleTimeZone(0, "Z"));
+        } else {
+            sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+            sdf.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
+        }
+
+        try {
+            setValue(sdf.parse(fixedDateStr));
+        } catch (ParseException e) {
+            throw new IOException("Failed to parse as generalized time string " + dateStr);
+        }
+    }
+
+    @Override
+    protected void toBytes() {
+        Date date = getValue();
+        SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
+        dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
+
+        String str = dateF.format(date);
+        byte[] bytes = str.getBytes(StandardCharsets.US_ASCII);
+        setBytes(bytes);
+    }
+
+    /**
+     * Extract the fractional part in seconds and convert into integer by (frac * 1000) as milli seconds
+     */
+    private String getMillSeconds(String dateStr) {
+        char[] millDigits = new char[] {'0', '0', '0'};
+
+        int iPos = dateStr.indexOf('.');
+        if (iPos > 0) {
+            if (iPos != 14) {
+                throw new IllegalArgumentException("Bad generalized time string, " +
+                        "with improper milli seconds " + dateStr);
+            }
+
+            char chr;
+            int j = 0;
+            for (int i = 15; i < dateStr.length() && j < millDigits.length; i++) {
+                chr = dateStr.charAt(i);
+                if ('0' <= chr && chr <= '9') {
+                    millDigits[j++] = chr;
+                } else break;
+            }
+        }
+
+        return new String(millDigits);
+    }
+
+    /**
+     * Extract the timezone part if any
+     */
+    private String getTimeZonePart(String dateStr) {
+        int iPos = dateStr.indexOf('+');
+        if (iPos == -1) {
+            iPos = dateStr.indexOf('-');
+        }
+        if (iPos > 0 && iPos != dateStr.length() - 5) {
+            throw new IllegalArgumentException("Bad generalized time string, " +
+                    "with improper timezone part " + dateStr);
+        }
+
+        if (iPos > 0) {
+            return dateStr.substring(iPos);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1IA5String.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1IA5String.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1IA5String.java
new file mode 100644
index 0000000..bf86ab9
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1IA5String.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1IA5String extends Asn1String
+{
+    public Asn1IA5String() {
+        super(UniversalTag.IA5_STRING);
+    }
+
+    public Asn1IA5String(String value) {
+        super(UniversalTag.IA5_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Integer.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Integer.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Integer.java
new file mode 100644
index 0000000..210ac2b
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Integer.java
@@ -0,0 +1,27 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+public class Asn1Integer extends Asn1Simple<Integer>
+{
+    public Asn1Integer() {
+        this(null);
+    }
+
+    public Asn1Integer(Integer value) {
+        super(UniversalTag.INTEGER, value);
+    }
+
+    @Override
+    protected void toBytes() {
+        setBytes(BigInteger.valueOf(getValue()).toByteArray());
+    }
+
+    @Override
+    protected void toValue() throws IOException {
+        setValue(new BigInteger(getBytes()).intValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Item.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Item.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Item.java
new file mode 100644
index 0000000..b7d6f5d
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Item.java
@@ -0,0 +1,136 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.Asn1Factory;
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.TaggingOption;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Asn1Item serves two purposes:
+ * 1. Wrapping an existing Asn1Type value for Asn1Collection;
+ * 2. Wrapping a half decoded value whose body content is left to be decoded later when appropriate.
+ * Why not fully decoded at once? Lazy and decode on demand for collection, or impossible due to lacking
+ * key parameters, like implicit encoded value for tagged value.
+ *
+ * For not fully decoded value, you tell your case using isSimple/isCollection/isTagged/isContextSpecific etc.,
+ * then call decodeValueAsSimple/decodeValueAsCollection/decodeValueAsImplicitTagged/decodeValueAsExplicitTagged etc.
+ * to decode it fully. Or if you have already derived the value holder or the holder type, you can use decodeValueWith
+ * or decodeValueAs with your holder or hodler type.
+ */
+public class Asn1Item extends AbstractAsn1Type<Asn1Type>
+{
+    private LimitedByteBuffer bodyContent;
+
+    public Asn1Item(Asn1Type value) {
+        super(value.tagFlags(), value.tagNo(), value);
+    }
+
+    public Asn1Item(int tag, int tagNo, LimitedByteBuffer bodyContent) {
+        super(tag, tagNo);
+        this.bodyContent = bodyContent;
+    }
+
+    public LimitedByteBuffer getBodyContent() {
+        return bodyContent;
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        if (getValue() != null) {
+            return ((AbstractAsn1Type) getValue()).encodingBodyLength();
+        }
+        return (int) bodyContent.hasLeft();
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) {
+        if (getValue() != null) {
+            ((AbstractAsn1Type) getValue()).encodeBody(buffer);
+        } else {
+            try {
+                buffer.put(bodyContent.readAllLeftBytes());
+            } catch (IOException e) {
+                throw new RuntimeException("Failed to read all left bytes from body content", e);
+            }
+        }
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer bodyContent) throws IOException {
+        this.bodyContent = bodyContent;
+    }
+
+    public boolean isFullyDecoded() {
+        return getValue() != null;
+    }
+
+    public void decodeValueAsSimple() throws IOException {
+        if (getValue() != null) return;
+        if (! isSimple()) {
+            throw new IllegalArgumentException("Attempting to decode non-simple value as simple");
+        }
+
+        Asn1Type value = Asn1Factory.create(tagNo());
+        decodeValueWith(value);
+    }
+
+    public void decodeValueAsCollection() throws IOException {
+        if (getValue() != null) return;
+        if (! isCollection()) {
+            throw new IllegalArgumentException("Attempting to decode non-collection value as collection");
+        }
+
+        Asn1Type value = Asn1Factory.create(tagNo());
+        decodeValueWith(value);
+    }
+
+    public void decodeValueAs(Class<? extends Asn1Type> type) throws IOException {
+        Asn1Type value;
+        try {
+            value = type.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Invalid type: " + type.getCanonicalName(), e);
+        }
+        decodeValueWith(value);
+    }
+
+    public void decodeValueWith(Asn1Type value) throws IOException {
+        setValue(value);
+        ((AbstractAsn1Type) value).decode(tagFlags(), tagNo(), bodyContent);
+    }
+
+    public void decodeValueAsImplicitTagged(int originalTag, int originalTagNo) throws IOException {
+        if (! isTagged()) {
+            throw new IllegalArgumentException("Attempting to decode non-tagged value using tagging way");
+        }
+        Asn1Item taggedValue = new Asn1Item(originalTag, originalTagNo, getBodyContent());
+        decodeValueWith(taggedValue);
+    }
+
+    public void decodeValueAsExplicitTagged() throws IOException {
+        if (! isTagged()) {
+            throw new IllegalArgumentException("Attempting to decode non-tagged value using tagging way");
+        }
+        Asn1Item taggedValue = decodeOne(getBodyContent());
+        decodeValueWith(taggedValue);
+    }
+
+    private void decodeValueWith(Asn1Item taggedValue) throws IOException {
+        taggedValue.decodeValueAsSimple();
+        if (taggedValue.isFullyDecoded()) {
+            setValue(taggedValue.getValue());
+        } else {
+            setValue(taggedValue);
+        }
+    }
+
+    public void decodeValueWith(Asn1Type value, TaggingOption taggingOption) throws IOException {
+        if (! isTagged()) {
+            throw new IllegalArgumentException("Attempting to decode non-tagged value using tagging way");
+        }
+        ((AbstractAsn1Type) value).taggedDecode(tagFlags(), tagNo(), getBodyContent(), taggingOption);
+        setValue(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Null.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Null.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Null.java
new file mode 100644
index 0000000..f4cdc77
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Null.java
@@ -0,0 +1,33 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+
+public class Asn1Null extends Asn1Simple<Object>
+{
+    public static final Asn1Null NULL = new Asn1Null();
+    private static final byte[]  EMPTY_BYTES = new byte[0];
+
+    public Asn1Null() {
+        super(null, UniversalTag.NULL);
+    }
+
+    @Override
+    protected byte[] encodeBody() {
+        return EMPTY_BYTES;
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        return 0;
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer content) throws IOException {
+        if (content.hasLeft() != 0) {
+            throw new IOException("Unexpected bytes found for NULL");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1NumericsString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1NumericsString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1NumericsString.java
new file mode 100644
index 0000000..fc7092f
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1NumericsString.java
@@ -0,0 +1,31 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1NumericsString extends Asn1String
+{
+    public Asn1NumericsString() {
+        this(null);
+    }
+
+    public Asn1NumericsString(String value) {
+        super(UniversalTag.NUMERIC_STRING, value);
+        if (value != null) {
+            if (!isNumeric(value)) {
+                throw new IllegalArgumentException("Invalid numeric string");
+            }
+        }
+    }
+
+    public static boolean isNumeric(String  s) {
+        char c;
+        for (int i = s.length() - 1; i >= 0; i--) {
+            c = s.charAt(i);
+            if ((c >= '0' && c <= '9') || c == ' ') {
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1ObjectIdentifier.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1ObjectIdentifier.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1ObjectIdentifier.java
new file mode 100644
index 0000000..515a879
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1ObjectIdentifier.java
@@ -0,0 +1,145 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+public class Asn1ObjectIdentifier extends Asn1Simple<String>
+{
+    public Asn1ObjectIdentifier() {
+        this(null);
+    }
+
+    public Asn1ObjectIdentifier(String value) {
+        super(UniversalTag.OBJECT_IDENTIFIER, value);
+    }
+
+    @Override
+    protected void toBytes() {
+        byte[][] bytesArr = convert(getValue());
+        int allLen = 0;
+        for (byte[] bytes : bytesArr) {
+            allLen += bytes.length;
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(allLen);
+        for (byte[] bytes : bytesArr) {
+            buffer.put(bytes);
+        }
+        setBytes(buffer.array());
+    }
+
+    protected void toValue() {
+        StringBuilder sb = new StringBuilder();
+
+        byte[] bytes = getBytes();
+        byte[][] bytesGroups = group(bytes);
+        BigInteger[] coms = convert(bytesGroups);
+
+        long first = coms[0].longValue();
+        sb.append(first / 40).append('.');
+        sb.append(first % 40);
+        if (coms.length > 1) {
+            sb.append('.');
+        }
+
+        for (int i = 1; i < coms.length; ++i) {
+            sb.append(coms[i].toString());
+            if (i != coms.length - 1) {
+                sb.append('.');
+            }
+        }
+
+        String value = sb.toString();
+        setValue(value);
+    }
+
+    private BigInteger[] convert(byte[][] bytesGroups) {
+        BigInteger[] comps = new BigInteger[bytesGroups.length];
+
+        for (int i = 0; i < bytesGroups.length; ++i) {
+            comps[i] = convert(bytesGroups[i]);
+        }
+
+        return comps;
+    }
+
+    private BigInteger convert(byte[] bytes) {
+        BigInteger value = BigInteger.valueOf(bytes[0] & 0x7f);
+        for (int i = 1; i < bytes.length; ++i) {
+            value = value.shiftLeft(7);
+            value = value.or(BigInteger.valueOf(bytes[i] & 0x7f));
+        }
+
+        return value;
+    }
+
+    /**
+     * divide and group bytes together belonging to each component
+     */
+    private byte[][] group(byte[] bytes) {
+        int count = 0, i, j;
+        int[] countArr = new int[bytes.length]; // how many bytes for each group
+        for (i = 0; i < countArr.length; ++i) countArr[i] = 0;
+
+        for (j = 0, i = 0; i < bytes.length; ++i) {
+            if ((bytes[i] & 0x80) != 0) {
+                countArr[j]++;
+            } else {
+                countArr[j++]++;
+            }
+        }
+        count = j;
+
+        byte[][] bytesGroups = new byte[count][];
+        for (i = 0; i < count; ++i) {
+            bytesGroups[i] = new byte[countArr[i]];
+        }
+
+        int k = 0;
+        for (j = 0, i = 0; i < bytes.length; ++i) {
+            bytesGroups[j][k++] = bytes[i];
+            if ((bytes[i] & 0x80) == 0) {
+                j++;
+                k = 0;
+            }
+        }
+
+        return bytesGroups;
+    }
+
+    private byte[][] convert(String oid) {
+        String[] parts = oid.split("\\.");
+        BigInteger[] coms = new BigInteger[parts.length - 1];
+        for (int i = 1; i < parts.length; ++i) {
+            coms[i - 1] = new BigInteger(parts[i]);
+        }
+        coms[0] = coms[0].add(BigInteger.valueOf(Integer.parseInt(parts[0]) * 40));
+
+        byte[][] bytesGroups = new byte[coms.length][];
+        for (int i = 0; i < coms.length; ++i) {
+            bytesGroups[i] = convert(coms[i]);
+        }
+
+        return bytesGroups;
+    }
+
+    private byte[] convert(BigInteger value) {
+        int bitLen = value.bitLength();
+
+        if (bitLen < 8) {
+            return new byte[] { value.byteValue() };
+        }
+
+        int len = (bitLen + 6) / 7;
+        byte[] bytes = new byte[len];
+        BigInteger tmpValue = value;
+        for (int i = len - 1; i >= 0; i--) {
+            bytes[i] = (byte)((tmpValue.byteValue() & 0x7f) | 0x80);
+            tmpValue = tmpValue.shiftRight(7);
+        }
+        bytes[len - 1] &= 0x7f;
+
+        return bytes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1OctetString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1OctetString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1OctetString.java
new file mode 100644
index 0000000..2d76aab
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1OctetString.java
@@ -0,0 +1,32 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+
+public class Asn1OctetString extends Asn1Simple<byte[]>
+{
+    public Asn1OctetString() {
+        this(null);
+    }
+
+    public Asn1OctetString(byte[] value) {
+        super(UniversalTag.OCTET_STRING, value);
+    }
+
+    @Override
+    protected byte[] encodeBody() {
+        return getValue();
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        return getValue().length;
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer content) throws IOException {
+        setValue(content.readAllLeftBytes());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1PrintableString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1PrintableString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1PrintableString.java
new file mode 100644
index 0000000..e0af8ec
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1PrintableString.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1PrintableString extends Asn1String
+{
+    public Asn1PrintableString() {
+        this(null);
+    }
+
+    public Asn1PrintableString(String value) {
+        super(UniversalTag.PRINTABLE_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Sequence.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Sequence.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Sequence.java
new file mode 100644
index 0000000..26b8ada
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Sequence.java
@@ -0,0 +1,11 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.TagClass;
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1Sequence extends Asn1Collection
+{
+    public Asn1Sequence() {
+        super(TagClass.UNIVERSAL, UniversalTag.SEQUENCE.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceOf.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceOf.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceOf.java
new file mode 100644
index 0000000..33e2c7b
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceOf.java
@@ -0,0 +1,19 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.TagClass;
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1SequenceOf<T extends Asn1Type> extends Asn1CollectionOf<T>
+{
+    public Asn1SequenceOf() {
+        super(TagClass.UNIVERSAL, UniversalTag.SEQUENCE_OF.getValue());
+    }
+
+    public boolean isEmpty() {
+        return (getValue() == null || getElements().size() == 0);
+    }
+
+    public void add(T element) {
+        getElements().add(element);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceType.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceType.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceType.java
new file mode 100644
index 0000000..70d13c2
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SequenceType.java
@@ -0,0 +1,18 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+/**
+ * For sequence type that consists of tagged fields
+ */
+public class Asn1SequenceType extends Asn1CollectionType {
+
+    public Asn1SequenceType(Asn1FieldInfo[] tags) {
+        super(UniversalTag.SEQUENCE.getValue(), tags);
+    }
+
+    @Override
+    protected Asn1Collection createCollection() {
+        return new Asn1Sequence();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Set.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Set.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Set.java
new file mode 100644
index 0000000..14763db
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Set.java
@@ -0,0 +1,11 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.TagClass;
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1Set extends Asn1Collection
+{
+    public Asn1Set() {
+        super(TagClass.UNIVERSAL, UniversalTag.SET.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetOf.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetOf.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetOf.java
new file mode 100644
index 0000000..b628ad6
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetOf.java
@@ -0,0 +1,11 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.TagClass;
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1SetOf<T extends Asn1Type> extends Asn1CollectionOf<T>
+{
+    public Asn1SetOf() {
+        super(TagClass.UNIVERSAL, UniversalTag.SET_OF.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetType.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetType.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetType.java
new file mode 100644
index 0000000..9843dec
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1SetType.java
@@ -0,0 +1,18 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+/**
+ * For set type that consists of tagged fields
+ */
+public class Asn1SetType extends Asn1CollectionType {
+
+    public Asn1SetType(Asn1FieldInfo[] tags) {
+        super(UniversalTag.SET.getValue(), tags);
+    }
+
+    @Override
+    protected Asn1Collection createCollection() {
+        return new Asn1Set();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Simple.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Simple.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Simple.java
new file mode 100644
index 0000000..b7d729c
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Simple.java
@@ -0,0 +1,165 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.EncodingOption;
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.TagClass;
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public abstract class Asn1Simple<T> extends AbstractAsn1Type<T> {
+    private byte[] bytes;
+
+    public Asn1Simple(UniversalTag tagNo) {
+        this(tagNo, null);
+    }
+
+    public Asn1Simple(UniversalTag tagNo, T value) {
+        super(TagClass.UNIVERSAL, tagNo.getValue(), value);
+        setEncodingOption(EncodingOption.PRIMITIVE);
+    }
+
+    protected byte[] getBytes() {
+        return bytes;
+    }
+
+    protected void setBytes(byte[] bytes) {
+        this.bytes = bytes;
+    }
+
+    @Override
+    public void encode(ByteBuffer buffer) {
+        encodeTag(buffer, tagFlags(), tagNo());
+        int bodyLen = encodingBodyLength();
+        encodeLength(buffer, bodyLen);
+        if (bodyLen > 0) {
+            buffer.put(encodeBody());
+        }
+    }
+
+    protected byte[] encodeBody() {
+        if (bytes == null) {
+            toBytes();
+        }
+        return bytes;
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) {
+        buffer.put(encodeBody());
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        if (getValue() == null) {
+            return 0;
+        }
+        if (bytes == null) {
+            toBytes();
+        }
+        return bytes.length;
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer content) throws IOException {
+        byte[] leftBytes = content.readAllLeftBytes();
+        if (leftBytes.length > 0) {
+            setBytes(leftBytes);
+            toValue();
+        }
+    }
+
+    @Override
+    public boolean isConstructed() {
+        return false;
+    }
+
+    protected void toValue() throws IOException {}
+
+    protected void toBytes() {}
+
+    public static boolean isSimple(int tagNo) {
+        return isSimple(UniversalTag.fromValue(tagNo));
+    }
+
+    public static boolean isSimple(UniversalTag tagNo) {
+        switch (tagNo) {
+            case BIT_STRING:
+            case BMP_STRING:
+            case BOOLEAN:
+            case ENUMERATED:
+            case GENERALIZED_TIME:
+            case GENERAL_STRING:
+            case IA5_STRING:
+            case INTEGER:
+            case NULL:
+            case NUMERIC_STRING:
+            case OBJECT_IDENTIFIER:
+            case OCTET_STRING:
+            case PRINTABLE_STRING:
+            case T61_STRING:
+            case UNIVERSAL_STRING:
+            case UTC_TIME:
+            case UTF8_STRING:
+            case VISIBLE_STRING:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public static Asn1Type createSimple(int tagNo) {
+        if (! isSimple(tagNo)) {
+            throw new IllegalArgumentException("Not simple type, tag: " + tagNo);
+        }
+        return createSimple(UniversalTag.fromValue(tagNo));
+    }
+
+    public static Asn1Type createSimple(UniversalTag tagNo) {
+        if (! isSimple(tagNo)) {
+            throw new IllegalArgumentException("Not simple type, tag: " + tagNo);
+        }
+
+        switch (tagNo) {
+            case BIT_STRING:
+                return new Asn1BitString();
+            case BMP_STRING:
+                return new Asn1BmpString();
+            case BOOLEAN:
+                return new Asn1Boolean();
+            case ENUMERATED:
+                return null;
+            case GENERALIZED_TIME:
+                return new Asn1GeneralizedTime();
+            case GENERAL_STRING:
+                return new Asn1GeneralString();
+            case IA5_STRING:
+                return new Asn1IA5String();
+            case INTEGER:
+                return new Asn1Integer();
+            case NULL:
+                return new Asn1Null();
+            case NUMERIC_STRING:
+                return new Asn1NumericsString();
+            case OBJECT_IDENTIFIER:
+                return new Asn1ObjectIdentifier();
+            case OCTET_STRING:
+                return new Asn1OctetString();
+            case PRINTABLE_STRING:
+                return new Asn1PrintableString();
+            case T61_STRING:
+                return new Asn1T61String();
+            case UNIVERSAL_STRING:
+                return new Asn1UniversalString();
+            case UTC_TIME:
+                return new Asn1UtcTime();
+            case UTF8_STRING:
+                return new Asn1Utf8String();
+            case VISIBLE_STRING:
+                return new Asn1VisibleString();
+            default:
+                throw new IllegalArgumentException("Unexpected tag " + tagNo.getValue());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1String.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1String.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1String.java
new file mode 100644
index 0000000..328d278
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1String.java
@@ -0,0 +1,273 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class Asn1String extends Asn1Simple<String>
+{
+    public Asn1String(UniversalTag tagNo) {
+        super(tagNo, null);
+    }
+
+    public Asn1String(UniversalTag tagNo, String value) {
+        super(tagNo, value);
+    }
+
+    @Override
+    protected void toBytes() {
+        byte[] bytes = getValue().getBytes(StandardCharsets.US_ASCII);
+        setBytes(bytes);
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        if (getValue() != null) {
+            return getValue().length();
+        }
+        return 0;
+    }
+
+    protected void toValue() throws IOException {
+        byte[] bytes = getBytes();
+        setValue(new String(bytes, StandardCharsets.US_ASCII));
+    }
+
+    public static String fromUTF8ByteArray(byte[] bytes) {
+        int i = 0;
+        int length = 0;
+
+        while (i < bytes.length) {
+            length++;
+            if ((bytes[i] & 0xf0) == 0xf0) {
+                // surrogate pair
+                length++;
+                i += 4;
+            } else if ((bytes[i] & 0xe0) == 0xe0) {
+                i += 3;
+            } else if ((bytes[i] & 0xc0) == 0xc0) {
+                i += 2;
+            } else {
+                i += 1;
+            }
+        }
+
+        char[] cs = new char[length];
+        i = 0;
+        length = 0;
+
+        while (i < bytes.length) {
+            char ch;
+
+            if ((bytes[i] & 0xf0) == 0xf0) {
+                int codePoint = ((bytes[i] & 0x03) << 18) | ((bytes[i+1] & 0x3F) << 12) | ((bytes[i+2] & 0x3F) << 6) | (bytes[i+3] & 0x3F);
+                int U = codePoint - 0x10000;
+                char W1 = (char)(0xD800 | (U >> 10));
+                char W2 = (char)(0xDC00 | (U & 0x3FF));
+                cs[length++] = W1;
+                ch = W2;
+                i += 4;
+            } else if ((bytes[i] & 0xe0) == 0xe0) {
+                ch = (char)(((bytes[i] & 0x0f) << 12)
+                        | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f));
+                i += 3;
+            } else if ((bytes[i] & 0xd0) == 0xd0) {
+                ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f));
+                i += 2;
+            } else if ((bytes[i] & 0xc0) == 0xc0) {
+                ch = (char)(((bytes[i] & 0x1f) << 6) | (bytes[i + 1] & 0x3f));
+                i += 2;
+            } else {
+                ch = (char)(bytes[i] & 0xff);
+                i += 1;
+            }
+
+            cs[length++] = ch;
+        }
+
+        return new String(cs);
+    }
+
+    public static byte[] toUTF8ByteArray(String string) {
+        return toUTF8ByteArray(string.toCharArray());
+    }
+
+    public static byte[] toUTF8ByteArray(char[] string) {
+        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+        try {
+            toUTF8ByteArray(string, bOut);
+        } catch (IOException e) {
+            throw new IllegalStateException("cannot encode string to byte array!");
+        }
+
+        return bOut.toByteArray();
+    }
+
+    public static void toUTF8ByteArray(char[] string, OutputStream sOut) throws IOException {
+        char[] c = string;
+        int i = 0;
+
+        while (i < c.length) {
+            char ch = c[i];
+
+            if (ch < 0x0080) {
+                sOut.write(ch);
+            } else if (ch < 0x0800) {
+                sOut.write(0xc0 | (ch >> 6));
+                sOut.write(0x80 | (ch & 0x3f));
+            }
+            // surrogate pair
+            else if (ch >= 0xD800 && ch <= 0xDFFF) {
+                // in error - can only happen, if the Java String class has a
+                // bug.
+                if (i + 1 >= c.length) {
+                    throw new IllegalStateException("invalid UTF-16 codepoint");
+                }
+                char W1 = ch;
+                ch = c[++i];
+                char W2 = ch;
+                // in error - can only happen, if the Java String class has a
+                // bug.
+                if (W1 > 0xDBFF) {
+                    throw new IllegalStateException("invalid UTF-16 codepoint");
+                }
+                int codePoint = (((W1 & 0x03FF) << 10) | (W2 & 0x03FF)) + 0x10000;
+                sOut.write(0xf0 | (codePoint >> 18));
+                sOut.write(0x80 | ((codePoint >> 12) & 0x3F));
+                sOut.write(0x80 | ((codePoint >> 6) & 0x3F));
+                sOut.write(0x80 | (codePoint & 0x3F));
+            } else {
+                sOut.write(0xe0 | (ch >> 12));
+                sOut.write(0x80 | ((ch >> 6) & 0x3F));
+                sOut.write(0x80 | (ch & 0x3F));
+            }
+
+            i++;
+        }
+    }
+
+    /**
+     * A locale independent version of toUpperCase.
+     *
+     * @param string input to be converted
+     * @return a US Ascii uppercase version
+     */
+    public static String toUpperCase(String string) {
+        boolean changed = false;
+        char[] chars = string.toCharArray();
+
+        for (int i = 0; i != chars.length; i++) {
+            char ch = chars[i];
+            if ('a' <= ch && 'z' >= ch) {
+                changed = true;
+                chars[i] = (char)(ch - 'a' + 'A');
+            }
+        }
+
+        if (changed) {
+            return new String(chars);
+        }
+
+        return string;
+    }
+
+    /**
+     * A locale independent version of toLowerCase.
+     *
+     * @param string input to be converted
+     * @return a US ASCII lowercase version
+     */
+    public static String toLowerCase(String string) {
+        boolean changed = false;
+        char[] chars = string.toCharArray();
+
+        for (int i = 0; i != chars.length; i++) {
+            char ch = chars[i];
+            if ('A' <= ch && 'Z' >= ch) {
+                changed = true;
+                chars[i] = (char)(ch - 'A' + 'a');
+            }
+        }
+
+        if (changed) {
+            return new String(chars);
+        }
+
+        return string;
+    }
+
+    public static byte[] toByteArray(char[] chars) {
+        byte[] bytes = new byte[chars.length];
+
+        for (int i = 0; i != bytes.length; i++) {
+            bytes[i] = (byte)chars[i];
+        }
+
+        return bytes;
+    }
+
+    public static byte[] toByteArray(String string) {
+        byte[] bytes = new byte[string.length()];
+
+        for (int i = 0; i != bytes.length; i++) {
+            char ch = string.charAt(i);
+
+            bytes[i] = (byte)ch;
+        }
+
+        return bytes;
+    }
+
+    /**
+     * Convert an array of 8 bit characters into a string.
+     *
+     * @param bytes 8 bit characters.
+     * @return resulting String.
+     */
+    public static String fromByteArray(byte[] bytes) {
+        return new String(asCharArray(bytes));
+    }
+
+    /**
+     * Do a simple conversion of an array of 8 bit characters into a string.
+     *
+     * @param bytes 8 bit characters.
+     * @return resulting String.
+     */
+    public static char[] asCharArray(byte[] bytes) {
+        char[] chars = new char[bytes.length];
+
+        for (int i = 0; i != chars.length; i++) {
+            chars[i] = (char)(bytes[i] & 0xff);
+        }
+
+        return chars;
+    }
+
+    public static String[] split(String input, char delimiter) {
+        List<String> v = new ArrayList<String>();
+        boolean moreTokens = true;
+        String subString;
+
+        while (moreTokens) {
+            int tokenLocation = input.indexOf(delimiter);
+            if (tokenLocation > 0) {
+                subString = input.substring(0, tokenLocation);
+                v.add(subString);
+                input = input.substring(tokenLocation + 1);
+            } else {
+                moreTokens = false;
+                v.add(input);
+            }
+        }
+
+        return v.toArray(new String[v.size()]);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61String.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61String.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61String.java
new file mode 100644
index 0000000..e7e3ca6
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61String.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1T61String extends Asn1String
+{
+    public Asn1T61String() {
+        this(null);
+    }
+
+    public Asn1T61String(String value) {
+        super(UniversalTag.T61_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61Utf8String.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61Utf8String.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61Utf8String.java
new file mode 100644
index 0000000..e5b264a
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1T61Utf8String.java
@@ -0,0 +1,24 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.nio.charset.StandardCharsets;
+
+public class Asn1T61Utf8String extends Asn1String
+{
+    public Asn1T61Utf8String() {
+        this(null);
+    }
+
+    public Asn1T61Utf8String(String value) {
+        super(UniversalTag.T61_STRING, value);
+    }
+
+    protected void toBytes() {
+        setBytes(getValue().getBytes(StandardCharsets.UTF_8));
+    }
+
+    protected void toValue() {
+        setValue(new String(getBytes(), StandardCharsets.UTF_8));
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Tagging.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Tagging.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Tagging.java
new file mode 100644
index 0000000..904c04f
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Tagging.java
@@ -0,0 +1,85 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.EncodingOption;
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.TagClass;
+
+import java.io.IOException;
+import java.lang.reflect.ParameterizedType;
+import java.nio.ByteBuffer;
+
+/**
+ * For tagging any Asn1Type with a tagNo
+ */
+public class Asn1Tagging<T extends Asn1Type> extends AbstractAsn1Type<T> {
+
+    public Asn1Tagging(boolean isAppSpecific) {
+        this(-1, null, isAppSpecific);
+    }
+
+    public Asn1Tagging(int tagNo, T value, boolean isAppSpecific) {
+        super(isAppSpecific ? TagClass.APPLICATION : TagClass.CONTEXT_SPECIFIC, tagNo, value);
+        setEncodingOption(EncodingOption.EXPLICIT);
+        if (value == null) {
+            initValue();
+        }
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        AbstractAsn1Type value = (AbstractAsn1Type) getValue();
+        if (encodingOption.isExplicit()) {
+            return value.encodingLength();
+        } else if (encodingOption.isImplicit()) {
+            return value.encodingBodyLength();
+        } else {
+            throw new RuntimeException("Invalid util option, only allowing explicit/implicit");
+        }
+    }
+
+    @Override
+    public boolean isConstructed() {
+        if (encodingOption.isExplicit()) {
+            return true;
+        } else if (encodingOption.isImplicit()) {
+            AbstractAsn1Type value = (AbstractAsn1Type) getValue();
+            return value.isConstructed();
+        }
+        return false;
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) {
+        AbstractAsn1Type value = (AbstractAsn1Type) getValue();
+        if (encodingOption.isExplicit()) {
+            value.encode(buffer);
+        } else if (encodingOption.isImplicit()) {
+            value.encodeBody(buffer);
+        } else {
+            throw new RuntimeException("Invalid util option, only allowing explicit/implicit");
+        }
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer content) throws IOException {
+        AbstractAsn1Type value = (AbstractAsn1Type) getValue();
+        if (encodingOption.isExplicit()) {
+            value.decode(content);
+        } else if (encodingOption.isImplicit()) {
+            value.decodeBody(content);
+        } else {
+            throw new RuntimeException("Invalid util option, only allowing explicit/implicit");
+        }
+    }
+
+    private void initValue() {
+        Class<? extends Asn1Type> valueType = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+        AbstractAsn1Type value = null;
+        try {
+            value = (AbstractAsn1Type) valueType.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to create tagged value", e);
+        }
+        setValue((T) value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Type.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Type.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Type.java
new file mode 100644
index 0000000..a4e89c8
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Type.java
@@ -0,0 +1,22 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.EncodingOption;
+import org.apache.haox.asn1.TaggingOption;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public interface Asn1Type {
+    public int tagFlags();
+    public int tagNo();
+    public void setEncodingOption(EncodingOption encodingOption);
+    public int encodingLength();
+    public byte[] encode();
+    public void encode(ByteBuffer buffer);
+    public void decode(byte[] content) throws IOException;
+    public void decode(ByteBuffer content) throws IOException;
+    public byte[] taggedEncode(TaggingOption taggingOption);
+    public void taggedEncode(ByteBuffer buffer, TaggingOption taggingOption);
+    public void taggedDecode(ByteBuffer content, TaggingOption taggingOption) throws IOException;
+    public void taggedDecode(byte[] content, TaggingOption taggingOption) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UniversalString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UniversalString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UniversalString.java
new file mode 100644
index 0000000..2297cfc
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UniversalString.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1UniversalString extends Asn1String
+{
+    public Asn1UniversalString() {
+        this(null);
+    }
+
+    public Asn1UniversalString(String value) {
+        super(UniversalTag.UNIVERSAL_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UtcTime.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UtcTime.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UtcTime.java
new file mode 100644
index 0000000..44cbc26
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1UtcTime.java
@@ -0,0 +1,70 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.SimpleTimeZone;
+
+public class Asn1UtcTime extends Asn1Simple<Date>
+{
+    public Asn1UtcTime() {
+        this(null);
+    }
+
+    public Asn1UtcTime(long time) {
+        super(UniversalTag.UTC_TIME, new Date(time * 1000L));
+    }
+
+    public Asn1UtcTime(Date date) {
+        super(UniversalTag.UTC_TIME, date);
+    }
+
+    protected void toValue() throws IOException {
+        String dateStr = new String(getBytes(), StandardCharsets.US_ASCII);
+        String fixedDateStr = dateStr;
+
+        /*
+         * Make sure fixed date str be of the complete pattern 'YYMMDDhhmmss+/-hhmm'
+         */
+        int strLen = fixedDateStr.length();
+        if (strLen == 6) { // YYMMDD
+            fixedDateStr += "000000+0000";
+        } else if (strLen == 7) { // YYMMDDZ
+            fixedDateStr = fixedDateStr.replace("Z", "000000+0000");
+        } else if (strLen == 10) { // YYMMDDhhmm
+            fixedDateStr += "00+0000";
+        } else if (strLen == 11) { // YYMMDDhhmmZ
+            fixedDateStr = fixedDateStr.replace("Z", "00+0000");
+        } else if (strLen == 12) { // YYMMDDhhmmss
+            fixedDateStr += "+0000";
+        } else if (strLen == 13) { // YYMMDDhhmmZ
+            fixedDateStr = fixedDateStr.replace("Z", "+0000");
+        } else if (strLen != 17) {
+            throw new IllegalArgumentException("Bad utc time string " + dateStr);
+        }
+
+        SimpleDateFormat sdf;
+        sdf = new SimpleDateFormat("yyMMddHHmmssZ");
+        sdf.setTimeZone(new SimpleTimeZone(0, "Z"));
+        try {
+            setValue(sdf.parse(fixedDateStr));
+        } catch (ParseException e) {
+            throw new IOException("Failed to parse " + dateStr + " as utc time", e);
+        }
+    }
+
+    @Override
+    protected void toBytes() {
+        Date date = getValue();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss'Z'");
+        sdf.setTimeZone(new SimpleTimeZone(0, "Z"));
+
+        String str = sdf.format(date);
+        byte[] bytes = str.getBytes(StandardCharsets.US_ASCII);
+        setBytes(bytes);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Utf8String.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Utf8String.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Utf8String.java
new file mode 100644
index 0000000..06d19e8
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1Utf8String.java
@@ -0,0 +1,28 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+public class Asn1Utf8String extends Asn1String
+{
+    public Asn1Utf8String() {
+        this(null);
+    }
+
+    public Asn1Utf8String(String value) {
+        super(UniversalTag.UTF8_STRING, value);
+    }
+
+    @Override
+    protected void toBytes() {
+        byte[] bytes = getValue().getBytes(StandardCharsets.UTF_8);
+        setBytes(bytes);
+    }
+
+    protected void toValue() throws IOException {
+        byte[] bytes = getBytes();
+        setValue(new String(bytes, StandardCharsets.UTF_8));
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1VisibleString.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1VisibleString.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1VisibleString.java
new file mode 100644
index 0000000..d3e043d
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/Asn1VisibleString.java
@@ -0,0 +1,14 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.UniversalTag;
+
+public class Asn1VisibleString extends Asn1String
+{
+    public Asn1VisibleString() {
+        this(null);
+    }
+
+    public Asn1VisibleString(String value) {
+        super(UniversalTag.VISIBLE_STRING, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingCollection.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingCollection.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingCollection.java
new file mode 100644
index 0000000..1d5d884
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingCollection.java
@@ -0,0 +1,86 @@
+package org.apache.haox.asn1.type;
+
+import org.apache.haox.asn1.EncodingOption;
+import org.apache.haox.asn1.LimitedByteBuffer;
+import org.apache.haox.asn1.TagClass;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * For tagging a collection type with tagNo, either application specific or context specific class
+ */
+public abstract class TaggingCollection extends AbstractAsn1Type<Asn1CollectionType> {
+    private Asn1Tagging<Asn1CollectionType> tagging;
+    private Asn1CollectionType tagged;
+
+    public TaggingCollection(int taggingTagNo, Asn1FieldInfo[] tags, boolean isAppSpecific) {
+        super(isAppSpecific ? TagClass.APPLICATION : TagClass.CONTEXT_SPECIFIC, taggingTagNo);
+        this.tagged = createTaggedCollection(tags);
+        setValue(tagged);
+        this.tagging = new Asn1Tagging<Asn1CollectionType>(taggingTagNo, tagged, isAppSpecific);
+        setEncodingOption(EncodingOption.EXPLICIT);
+    }
+
+    protected abstract Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags);
+
+    public void setEncodingOption(EncodingOption encodingOption) {
+        tagging.setEncodingOption(encodingOption);
+    }
+
+    @Override
+    public boolean isConstructed() {
+        return tagging.isConstructed();
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        return tagging.encodingBodyLength();
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) {
+        tagging.encodeBody(buffer);
+    }
+
+    @Override
+    protected void decodeBody(LimitedByteBuffer content) throws IOException {
+        tagging.decodeBody(content);
+    }
+
+    protected <T extends Asn1Type> T getFieldAs(int index, Class<T> t) {
+        return tagged.getFieldAs(index, t);
+    }
+
+    protected void setFieldAs(int index, Asn1Type value) {
+        tagged.setFieldAs(index, value);
+    }
+
+    protected String getFieldAsString(int index) {
+        return tagged.getFieldAsString(index);
+    }
+
+    protected byte[] getFieldAsOctets(int index) {
+        return tagged.getFieldAsOctets(index);
+    }
+
+    protected void setFieldAsOctets(int index, byte[] bytes) {
+        tagged.setFieldAsOctets(index, bytes);
+    }
+
+    protected Integer getFieldAsInteger(int index) {
+        return tagged.getFieldAsInteger(index);
+    }
+
+    protected void setFieldAsInt(int index, int value) {
+        tagged.setFieldAsInt(index, value);
+    }
+
+    protected byte[] getFieldAsOctetBytes(int index) {
+        return tagged.getFieldAsOctets(index);
+    }
+
+    protected void setFieldAsOctetBytes(int index, byte[] value) {
+        tagged.setFieldAsOctets(index, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSequence.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSequence.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSequence.java
new file mode 100644
index 0000000..53ccaa1
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSequence.java
@@ -0,0 +1,16 @@
+package org.apache.haox.asn1.type;
+
+/**
+ * For tagging a sequence type with tagNo, either application specific or context specific class
+ */
+public class TaggingSequence extends TaggingCollection {
+
+    public TaggingSequence(int taggingTagNo, Asn1FieldInfo[] tags, boolean isAppSpecific) {
+        super(taggingTagNo, tags, isAppSpecific);
+    }
+
+    @Override
+    protected Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags) {
+        return new Asn1SequenceType(tags);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSet.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSet.java b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSet.java
new file mode 100644
index 0000000..81bbd16
--- /dev/null
+++ b/contrib/haox-asn1/src/main/java/org/apache/haox/asn1/type/TaggingSet.java
@@ -0,0 +1,16 @@
+package org.apache.haox.asn1.type;
+
+/**
+ * For tagging a sequence type with tagNo, either application specific or context specific class
+ */
+public class TaggingSet extends TaggingCollection {
+
+    public TaggingSet(int taggingTagNo, Asn1FieldInfo[] tags, boolean isAppSpecific) {
+        super(taggingTagNo, tags, isAppSpecific);
+    }
+
+    @Override
+    protected Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags) {
+        return new Asn1SetType(tags);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Dump.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Dump.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Dump.java
deleted file mode 100644
index 4f1c651..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Dump.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.haox.asn1;
-
-import org.haox.asn1.type.Asn1Item;
-import org.haox.asn1.type.Asn1Simple;
-import org.haox.asn1.type.Asn1Type;
-
-import java.io.IOException;
-
-public class Asn1Dump {
-
-    public static void dump(byte[] content) throws IOException {
-        String dumped = dumpAsString(content);
-        System.out.println(dumped);
-    }
-
-    public static String dumpAsString(byte[] content) throws IOException {
-        StringBuilder sb = new StringBuilder();
-
-        Asn1InputBuffer buffer = new Asn1InputBuffer(content);
-        Asn1Type value;
-        while (true) {
-            value = buffer.read();
-            if (value == null) break;
-            dump(value, sb);
-        }
-
-        return sb.toString();
-    }
-
-    public static String dumpAsString(Asn1Type value) {
-        StringBuilder sb = new StringBuilder();
-        dump(value, sb);
-        return sb.toString();
-    }
-
-    private static void dump(Asn1Type value, StringBuilder buffer) {
-        if (value instanceof Asn1Simple) {
-            buffer.append(((Asn1Simple) value).getValue().toString());
-        } else if (value instanceof Asn1Item) {
-            dump((Asn1Item) value, buffer);
-        }
-    }
-
-    private static void dump(Asn1Item value, StringBuilder buffer) {
-        if (value.isFullyDecoded()) {
-            dump(value.getValue(), buffer);
-        } else {
-            buffer.append("Asn1Item");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Factory.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Factory.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Factory.java
deleted file mode 100644
index cbd7dfb..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1Factory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.haox.asn1;
-
-import org.haox.asn1.type.Asn1Collection;
-import org.haox.asn1.type.Asn1Simple;
-import org.haox.asn1.type.Asn1Type;
-
-public class Asn1Factory {
-
-    public static Asn1Type create(int tagNo) {
-        UniversalTag tagNoEnum = UniversalTag.fromValue(tagNo);
-        if (tagNoEnum != UniversalTag.UNKNOWN) {
-            return create(tagNoEnum);
-        }
-        throw new IllegalArgumentException("Unexpected tag " + tagNo);
-    }
-
-    public static Asn1Type create(UniversalTag tagNo) {
-        if (Asn1Simple.isSimple(tagNo)) {
-            return Asn1Simple.createSimple(tagNo);
-        } else if (Asn1Collection.isCollection(tagNo)) {
-            return Asn1Collection.createCollection(tagNo);
-        }
-        throw new IllegalArgumentException("Unexpected tag " + tagNo);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1InputBuffer.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1InputBuffer.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1InputBuffer.java
deleted file mode 100644
index 4eba011..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1InputBuffer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.haox.asn1;
-
-import org.haox.asn1.type.AbstractAsn1Type;
-import org.haox.asn1.type.Asn1Item;
-import org.haox.asn1.type.Asn1Type;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Asn1 decoder
- */
-public class Asn1InputBuffer {
-    private final LimitedByteBuffer limitedBuffer;
-
-    public Asn1InputBuffer(byte[] bytes) {
-        this(new LimitedByteBuffer(bytes));
-    }
-
-    public Asn1InputBuffer(ByteBuffer byteBuffer) {
-        this(new LimitedByteBuffer(byteBuffer));
-    }
-
-    public Asn1InputBuffer(LimitedByteBuffer limitedByteBuffer) {
-        this.limitedBuffer = limitedByteBuffer;
-    }
-
-    public Asn1Type read() throws IOException {
-        if (! limitedBuffer.available()) {
-            return null;
-        }
-        Asn1Item one = AbstractAsn1Type.decodeOne(limitedBuffer);
-        if (one.isSimple()) {
-            one.decodeValueAsSimple();
-        } else if (one.isCollection()) {
-            one.decodeValueAsCollection();
-        }
-        if (one.isFullyDecoded()) {
-            return one.getValue();
-        }
-        return one;
-    }
-
-    public void readBytes(byte[] bytes) throws IOException {
-        limitedBuffer.readBytes(bytes);
-    }
-
-    public byte[] readAllLeftBytes() throws IOException {
-        return limitedBuffer.readAllLeftBytes();
-    }
-
-    public void skipNext() throws IOException {
-        if (limitedBuffer.available()) {
-            AbstractAsn1Type.skipOne(limitedBuffer);
-        }
-    }
-
-    public void skipBytes(int len) throws IOException {
-        if (limitedBuffer.available()) {
-            limitedBuffer.skip(len);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1OutputBuffer.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1OutputBuffer.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1OutputBuffer.java
deleted file mode 100644
index 62fe95f..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/Asn1OutputBuffer.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.haox.asn1;
-
-import org.haox.asn1.type.AbstractAsn1Type;
-import org.haox.asn1.type.Asn1Type;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Asn1 encoder
- */
-public class Asn1OutputBuffer {
-    private List<Asn1Type> objects;
-
-    public Asn1OutputBuffer() {
-        this.objects = new ArrayList<Asn1Type>(3);
-    }
-
-    public void write(Asn1Type value) {
-        objects.add(value);
-    }
-
-    public void write(Asn1Type value, EncodingOption option) {
-        value.setEncodingOption(option);
-        objects.add(value);
-    }
-
-    public ByteBuffer getOutput() {
-        int len = encodingLength();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(len);
-        encode(byteBuffer);
-        return byteBuffer;
-    }
-
-    private int encodingLength() {
-        int allLen = 0;
-        for (Asn1Type item : objects) {
-            if (item != null) {
-                allLen += ((AbstractAsn1Type) item).encodingLength();
-            }
-        }
-        return allLen;
-    }
-
-    private void encode(ByteBuffer buffer) {
-        for (Asn1Type item : objects) {
-            if (item != null) {
-                item.encode(buffer);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/EncodingOption.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/EncodingOption.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/EncodingOption.java
deleted file mode 100644
index 5d997a9..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/EncodingOption.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.haox.asn1;
-
-public enum EncodingOption
-{
-    UNKNOWN(-1),
-    PRIMITIVE(1),
-    CONSTRUCTED(2),
-    CONSTRUCTED_DEFLEN(3),
-    CONSTRUCTED_INDEFLEN(4),
-    IMPLICIT(5),
-    EXPLICIT(6),
-    BER(7),
-    DER(8),
-    CER(9);
-
-    private int value;
-
-    private EncodingOption(int value) {
-        this.value = value;
-    }
-
-    public static int CONSTRUCTED_FLAG = 0x20;
-
-    public static boolean isConstructed(int tag) {
-        return (tag & CONSTRUCTED_FLAG) != 0;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public boolean isPrimitive() {
-        return this == PRIMITIVE;
-    }
-
-    public boolean isConstructed() {
-        return this == CONSTRUCTED || this == CONSTRUCTED_DEFLEN || this == CONSTRUCTED_INDEFLEN;
-    }
-
-    public boolean isImplicit() {
-        return this == IMPLICIT;
-    }
-
-    public boolean isExplicit() {
-        return this == EXPLICIT;
-    }
-
-    public boolean isDer() {
-        return this == DER;
-    }
-
-    public boolean isCer() {
-        return this == CER;
-    }
-
-    public static EncodingOption fromValue(int value) {
-        for (EncodingOption e : values()) {
-            if (e.getValue() == value) {
-                return (EncodingOption) e;
-            }
-        }
-
-        return UNKNOWN;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/LimitedByteBuffer.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/LimitedByteBuffer.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/LimitedByteBuffer.java
deleted file mode 100644
index 01babab..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/LimitedByteBuffer.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.haox.asn1;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-public class LimitedByteBuffer {
-    private final ByteBuffer byteBuffer;
-    private final int limit;
-    private int startOffset;
-
-    public LimitedByteBuffer(byte[] bytes) {
-        this.byteBuffer = ByteBuffer.wrap(bytes);
-        this.limit = bytes.length;
-        this.startOffset = 0;
-    }
-
-    public LimitedByteBuffer(ByteBuffer byteBuffer) {
-        this(byteBuffer, byteBuffer.limit());
-    }
-
-    public LimitedByteBuffer(ByteBuffer byteBuffer, int limit) {
-        this.byteBuffer = byteBuffer;
-        this.limit = limit;
-        this.startOffset = byteBuffer.position();
-    }
-
-    public LimitedByteBuffer(LimitedByteBuffer other, int limit) {
-        if (limit > other.hasLeft()) {
-            throw new IllegalArgumentException("limit is too large, out of bound");
-        }
-        this.byteBuffer = other.byteBuffer.duplicate();
-        this.limit = limit;
-        this.startOffset = byteBuffer.position();
-    }
-
-    public boolean available() {
-        return byteBuffer.hasRemaining() &&
-                byteBuffer.position() - startOffset < limit;
-    }
-
-    public long hasRead() {
-        return byteBuffer.position() - startOffset;
-    }
-    public long hasLeft() {
-        return limit - hasRead();
-    }
-
-    public byte readByte() throws IOException {
-        if (!available()) {
-            throw new IOException("Buffer EOF");
-        }
-        return byteBuffer.get();
-    }
-
-    public byte[] readAllLeftBytes() throws IOException {
-        return readBytes((int) hasLeft());
-    }
-
-    public void skip(int len) throws IOException {
-        checkLen(len);
-        int newPos = byteBuffer.position() + len;
-        byteBuffer.position(newPos);
-    }
-
-    public byte[] readBytes(int len) throws IOException {
-        checkLen(len);
-
-        byte[] bytes = new byte[len];
-        if (len > 0) {
-            byteBuffer.get(bytes);
-        }
-        return bytes;
-    }
-
-    private void checkLen(int len) throws IOException {
-        if (len < 0) {
-            throw new IllegalArgumentException("Bad argument len: " + len);
-        }
-        if (len > 0) {
-            if (!available()) {
-                throw new IOException("Buffer EOF");
-            }
-            if (hasLeft() < len) {
-                throw new IOException("Out of Buffer");
-            }
-        }
-    }
-
-    public void readBytes(byte[] bytes) throws IOException {
-        if (bytes == null) {
-            throw new IllegalArgumentException("Bad argument bytes: null");
-        }
-        if (!available()) {
-            throw new IOException("Buffer EOF");
-        }
-        if (hasLeft() < bytes.length) {
-            throw new IOException("Out of Buffer");
-        }
-
-        byteBuffer.get(bytes);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/TagClass.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/TagClass.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/TagClass.java
deleted file mode 100644
index ad39e45..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/TagClass.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.haox.asn1;
-
-public enum TagClass {
-    UNKNOWN(-1),
-    UNIVERSAL(0x00),
-    APPLICATION(0x40),
-    CONTEXT_SPECIFIC(0x80),
-    PRIVATE(0xC0);
-
-    private int value;
-
-    private TagClass(int value) {
-        this.value = value;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public boolean isUniversal() {
-        return this == UNIVERSAL;
-    }
-
-    public boolean isAppSpecific() {
-        return this == APPLICATION;
-    }
-
-    public boolean isContextSpecific() {
-        return this == CONTEXT_SPECIFIC;
-    }
-
-    public boolean isTagged() {
-        return this == APPLICATION || this == CONTEXT_SPECIFIC;
-    }
-
-    public static TagClass fromValue(int value) {
-        // Optimized by Emmanuel
-        switch (value) {
-            case 0x00:
-                return TagClass.UNIVERSAL;
-            case 0x40:
-                return TagClass.APPLICATION;
-            case 0x80:
-                return TagClass.CONTEXT_SPECIFIC;
-            case 0xC0:
-                return TagClass.PRIVATE;
-            default:
-                return TagClass.UNKNOWN;
-        }
-    }
-
-    public static TagClass fromTagFlags(int tag) {
-        return fromValue(tag & 0xC0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/TaggingOption.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/TaggingOption.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/TaggingOption.java
deleted file mode 100644
index 73a3a45..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/TaggingOption.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.haox.asn1;
-
-public class TaggingOption
-{
-    private int tagNo;
-    private boolean isImplicit;
-    private boolean isAppSpecific;
-
-    public static TaggingOption newImplicitAppSpecific(int tagNo) {
-        return new TaggingOption(tagNo, true, true);
-    }
-
-    public static TaggingOption newExplicitAppSpecific(int tagNo) {
-        return new TaggingOption(tagNo, false, true);
-    }
-
-    public static TaggingOption newImplicitContextSpecific(int tagNo) {
-        return new TaggingOption(tagNo, true, false);
-    }
-
-    public static TaggingOption newExplicitContextSpecific(int tagNo) {
-        return new TaggingOption(tagNo, false, false);
-    }
-
-    private TaggingOption(int tagNo, boolean isImplicit, boolean isAppSpecific) {
-        this.tagNo = tagNo;
-        this.isImplicit = isImplicit;
-        this.isAppSpecific = isAppSpecific;
-    }
-
-    public int tagFlags(boolean isTaggedConstructed) {
-        boolean isConstructed = isImplicit ? isTaggedConstructed : true;
-        TagClass tagClass = isAppSpecific ? TagClass.APPLICATION : TagClass.CONTEXT_SPECIFIC;
-        int flags = tagClass.getValue() | (isConstructed ? EncodingOption.CONSTRUCTED_FLAG : 0x00);
-        return flags;
-    }
-
-    public int getTagNo() {
-        return tagNo;
-    }
-
-    public boolean isAppSpecific() {
-        return isAppSpecific;
-    }
-
-    public boolean isImplicit() {
-        return isImplicit;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/5a980a4d/contrib/haox-asn1/src/main/java/org/haox/asn1/UniversalTag.java
----------------------------------------------------------------------
diff --git a/contrib/haox-asn1/src/main/java/org/haox/asn1/UniversalTag.java b/contrib/haox-asn1/src/main/java/org/haox/asn1/UniversalTag.java
deleted file mode 100644
index 8643fbe..0000000
--- a/contrib/haox-asn1/src/main/java/org/haox/asn1/UniversalTag.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.haox.asn1;
-
-// Optimized by Emmanuel
-public enum UniversalTag {
-    UNKNOWN             (-1),
-    CHOICE              (-2), // Only for internal using
-    BOOLEAN             (0x01),
-    INTEGER             (0x02),
-    BIT_STRING          (0x03),
-    OCTET_STRING        (0x04),
-    NULL                (0x05),
-    OBJECT_IDENTIFIER   (0x06),
-    OBJECT_DESCRIPTOR   (0x07),     // Added for completness
-    EXTERNAL            (0x08),
-    REAL                (0x09),
-    ENUMERATED          (0x0a),
-    EMBEDDED_PDV        (0x0b),     // Added for completness
-    UTF8_STRING         (0x0c),
-    RELATIVE_OID        (0x0d),     // Added for completness
-    RESERVED_14         (0x0e),     // Added for completness
-    RESERVED_15         (0x0f),     // Added for completness
-    SEQUENCE            (0x10),
-    SEQUENCE_OF         (0x10),
-    SET                 (0x11),
-    SET_OF              (0x11),
-    NUMERIC_STRING      (0x12),
-    PRINTABLE_STRING    (0x13),
-    T61_STRING          (0x14),
-    VIDEOTEX_STRING     (0x15),
-    IA5_STRING          (0x16),
-    UTC_TIME            (0x17),
-    GENERALIZED_TIME    (0x18),
-    GRAPHIC_STRING      (0x19),
-    VISIBLE_STRING      (0x1a),
-    GENERAL_STRING      (0x1b),
-    UNIVERSAL_STRING    (0x1c),
-    CHARACTER_STRING    (0x1d),     // Added for completness
-    BMP_STRING          (0x1e),
-    RESERVED_31         (0x1f);     // Added for completness
-
-    private int value;
-
-    private UniversalTag(int value) {
-        this.value = value;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public static UniversalTag fromValue(int value) {
-        switch (value) {
-            case 0x01 : return BOOLEAN;
-            case 0x02 : return INTEGER;
-            case 0x03 : return BIT_STRING;
-            case 0x04 : return OCTET_STRING;
-            case 0x05 : return NULL;
-            case 0x06 : return OBJECT_IDENTIFIER;
-            case 0x07 : return OBJECT_DESCRIPTOR;
-            case 0x08 : return EXTERNAL;
-            case 0x09 : return REAL;
-            case 0x0A : return ENUMERATED;
-            case 0x0B : return EMBEDDED_PDV;
-            case 0x0C : return UTF8_STRING;
-            case 0x0D : return RELATIVE_OID;
-            case 0x0E : return RESERVED_14;
-            case 0x0F : return RESERVED_15;
-            case 0x10 : return SEQUENCE;
-            case 0x11 : return SET;
-            case 0x12 : return NUMERIC_STRING;
-            case 0x13 : return PRINTABLE_STRING;
-            case 0x14 : return T61_STRING;
-            case 0x15 : return VIDEOTEX_STRING;
-            case 0x16 : return IA5_STRING;
-            case 0x17 : return UTC_TIME;
-            case 0x18 : return GENERALIZED_TIME;
-            case 0x19 : return GRAPHIC_STRING;
-            case 0x1A : return VISIBLE_STRING;
-            case 0x1B : return GENERAL_STRING;
-            case 0x1C : return UNIVERSAL_STRING;
-            case 0x1D : return CHARACTER_STRING;
-            case 0x1E : return BMP_STRING;
-            case 0x1F : return RESERVED_31;
-            default : return UNKNOWN;
-        }
-    }
-}