directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dran...@apache.org
Subject [07/13] directory-kerby git commit: Consolidated facility and support modules into kerby-common
Date Sat, 16 Jan 2016 09:38:35 GMT
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetOf.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetOf.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetOf.java
new file mode 100644
index 0000000..a351eaf
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetOf.java
@@ -0,0 +1,28 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.UniversalTag;
+
+public class Asn1SetOf<T extends Asn1Type> extends Asn1CollectionOf<T> {
+    public Asn1SetOf() {
+        super(UniversalTag.SET_OF);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetType.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetType.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetType.java
new file mode 100644
index 0000000..63b64cd
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1SetType.java
@@ -0,0 +1,38 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Asn1FieldInfo;
+import org.apache.kerby.asn1.UniversalTag;
+
+/**
+ * For set type that consists of tagged fields
+ */
+public class Asn1SetType extends Asn1CollectionType {
+
+    public Asn1SetType(Asn1FieldInfo[] tags) {
+        super(UniversalTag.SET, tags);
+    }
+
+    @Override
+    protected Asn1Collection createCollection() {
+        return new Asn1Set();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
new file mode 100644
index 0000000..2980086
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
@@ -0,0 +1,215 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1Item;
+import org.apache.kerby.asn1.parse.Asn1ParseResult;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * ASN1 simple type, of single value other than complex type of multiple values.
+ */
+public abstract class Asn1Simple<T> extends AbstractAsn1Type<T> {
+    private byte[] bytes;
+
+    /**
+     * Default constructor, generally for decoding as a value container
+     * @param tagNo The tag number
+     */
+    public Asn1Simple(UniversalTag tagNo) {
+        this(tagNo, null);
+    }
+
+    /**
+     * Constructor with a value, generally for encoding of the value
+     * @param universalTag The tag number
+     * @param value The value
+     */
+    public Asn1Simple(UniversalTag universalTag, T value) {
+        super(universalTag, value);
+        usePrimitive(true);
+    }
+
+    @Override
+    public boolean isDefinitiveLength() {
+        return true; // TO-BE-FIXED: some primitive types may not.
+    }
+
+    protected byte[] getBytes() {
+        return bytes;
+    }
+
+    protected void setBytes(byte[] bytes) {
+        this.bytes = bytes;
+    }
+
+    protected byte[] encodeBody() {
+        if (bytes == null) {
+            toBytes();
+        }
+        return bytes;
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) {
+        byte[] body = encodeBody();
+        if (body != null) {
+            buffer.put(body);
+        }
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        if (getValue() == null) {
+            return 0;
+        }
+        if (bytes == null) {
+            toBytes();
+        }
+        return bytes.length;
+    }
+
+    @Override
+    protected void decodeBody(Asn1ParseResult parseResult) throws IOException {
+        Asn1Item item = (Asn1Item) parseResult;
+        byte[] leftBytes = item.readBodyBytes();
+        if (leftBytes.length > 0) {
+            setBytes(leftBytes);
+            toValue();
+        }
+    }
+
+    protected void toValue() throws IOException { }
+
+    protected void toBytes() { }
+
+    public static boolean isSimple(Tag tag) {
+        return isSimple(tag.universalTag());
+    }
+
+    public static boolean isSimple(int tag) {
+        return isSimple(new Tag(tag));
+    }
+
+    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;
+        }
+    }
+
+    /**
+     * Create a simple ASN1 object given tagNo, using the default constructor
+     * with no value provided
+     * @param tagNo The tag number
+     * @return A simple ASN1 object
+     */
+    public static Asn1Simple<?> createSimple(int tagNo) {
+        if (!isSimple(tagNo)) {
+            throw new IllegalArgumentException("Not simple type, tag: " + tagNo);
+        }
+        return createSimple(UniversalTag.fromValue(tagNo));
+    }
+
+    /**
+     * Create a simple ASN1 object given tagNo, using the default constructor
+     * with no value provided
+     * @param tagNo The tag number
+     * @return The simple ASN1 object
+     */
+    public static Asn1Simple<?> 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 Asn1Null.INSTANCE;
+            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());
+        }
+    }
+
+    @Override
+    public String toString() {
+        String typeStr = simpleInfo();
+        T theValue = getValue();
+        String valueStr = (theValue != null ? String.valueOf(theValue) : "null");
+        return typeStr + valueStr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Specific.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Specific.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Specific.java
new file mode 100644
index 0000000..423e67e
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Specific.java
@@ -0,0 +1,57 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1ParseResult;
+
+import java.io.IOException;
+
+/**
+ * Application or context specific object mainly for using implicit encoding.
+ */
+public class Asn1Specific extends AbstractAsn1Type<byte[]> {
+
+    public Asn1Specific(Tag tag, byte[] value) {
+        super(tag, value);
+    }
+
+    public Asn1Specific(Tag tag) {
+        super(tag);
+    }
+
+    @Override
+    protected int encodingBodyLength() {
+        if (getValue() != null) {
+            return getValue().length;
+        }
+        return 0;
+    }
+
+    @Override
+    protected void decodeBody(Asn1ParseResult parseResult) throws IOException {
+        setValue(parseResult.readBodyBytes());
+    }
+
+    @Override
+    public String toString() {
+        return tag().typeStr() + "  <" + getValue().length + " bytes>";
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1String.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1String.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1String.java
new file mode 100644
index 0000000..355dd8c
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1String.java
@@ -0,0 +1,292 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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 universalTag) {
+        super(universalTag, null);
+    }
+
+    public Asn1String(UniversalTag tagNo, String value) {
+        super(tagNo, value);
+    }
+
+    @Override
+    protected void toBytes() {
+        if (getValue() != null) {
+            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));
+            } 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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61String.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61String.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61String.java
new file mode 100644
index 0000000..d00eb11
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61String.java
@@ -0,0 +1,32 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61Utf8String.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61Utf8String.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61Utf8String.java
new file mode 100644
index 0000000..9f75aee
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1T61Utf8String.java
@@ -0,0 +1,42 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
new file mode 100644
index 0000000..98eefa2
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
@@ -0,0 +1,115 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Asn1Dumpable;
+import org.apache.kerby.asn1.Asn1Dumper;
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1Container;
+import org.apache.kerby.asn1.parse.Asn1ParseResult;
+
+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> implements Asn1Dumpable {
+
+    public Asn1Tagging(int tagNo, T value,
+                       boolean isAppSpecific, boolean isImplicit) {
+        super(makeTag(isAppSpecific, tagNo), value);
+        if (value == null) {
+            initValue();
+        }
+        useImplicit(isImplicit);
+    }
+
+    private static Tag makeTag(boolean isAppSpecific, int tagNo) {
+        return isAppSpecific ? Tag.newAppTag(tagNo) : Tag.newCtxTag(tagNo);
+    }
+
+    @Override
+    public void useImplicit(boolean isImplicit) {
+        super.useImplicit(isImplicit);
+
+        if (!isImplicit) {
+            //In effect, explicitly tagged types are structured types consisting
+            // of one component, the underlying type.
+            usePrimitive(false);
+        } else {
+            usePrimitive(getValue().isPrimitive());
+        }
+    }
+
+    @Override
+    protected int encodingBodyLength() throws IOException {
+        Asn1Encodeable value = (Asn1Encodeable) getValue();
+        if (isImplicit()) {
+            return value.encodingBodyLength();
+        } else {
+            return value.encodingLength();
+        }
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) throws IOException {
+        Asn1Encodeable value = (Asn1Encodeable) getValue();
+        if (isImplicit()) {
+            value.encodeBody(buffer);
+        } else {
+            value.encode(buffer);
+        }
+    }
+
+    @Override
+    protected void decodeBody(Asn1ParseResult parseResult) throws IOException {
+        Asn1Encodeable value = (Asn1Encodeable) getValue();
+        if (isImplicit()) {
+            value.decodeBody(parseResult);
+        } else {
+            Asn1Container container = (Asn1Container) parseResult;
+            Asn1ParseResult body = container.getChildren().get(0);
+            value.decode(body);
+        }
+    }
+
+    private void initValue() {
+        Class<? extends Asn1Type> valueType = (Class<T>) ((ParameterizedType)
+                getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+        AbstractAsn1Type<?> value;
+        try {
+            value = (AbstractAsn1Type<?>) valueType.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to create tagged value", e);
+        }
+        setValue((T) value);
+    }
+
+    @Override
+    public void dumpWith(Asn1Dumper dumper, int indents) {
+        Asn1Type taggedValue = getValue();
+        dumper.indent(indents).appendType(getClass());
+        dumper.append(simpleInfo()).newLine();
+        dumper.dumpType(indents, taggedValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
new file mode 100644
index 0000000..9595866
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
@@ -0,0 +1,191 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Asn1Dumpable;
+import org.apache.kerby.asn1.Asn1Dumper;
+import org.apache.kerby.asn1.Asn1FieldInfo;
+import org.apache.kerby.asn1.EnumType;
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1ParseResult;
+
+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 Asn1TaggingCollection
+    extends AbstractAsn1Type<Asn1CollectionType> implements Asn1Dumpable {
+
+    private Asn1Tagging<Asn1CollectionType> tagging;
+    private Asn1CollectionType tagged;
+
+    public Asn1TaggingCollection(int taggingTagNo, Asn1FieldInfo[] tags,
+                                 boolean isAppSpecific, boolean isImplicit) {
+        super(makeTag(isAppSpecific, taggingTagNo));
+        this.tagged = createTaggedCollection(tags);
+        setValue(tagged);
+        this.tagging = new Asn1Tagging<>(taggingTagNo,
+            tagged, isAppSpecific, isImplicit);
+    }
+
+    private static Tag makeTag(boolean isAppSpecific, int tagNo) {
+        return isAppSpecific ? Tag.newAppTag(tagNo) : Tag.newCtxTag(tagNo);
+    }
+
+    protected abstract Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags);
+
+    @Override
+    public Tag tag() {
+        return tagging.tag();
+    }
+
+    @Override
+    public int tagNo() {
+        return tagging.tagNo();
+    }
+
+    @Override
+    public void usePrimitive(boolean isPrimitive) {
+        tagging.usePrimitive(isPrimitive);
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return tagging.isPrimitive();
+    }
+
+    @Override
+    public void useDefinitiveLength(boolean isDefinitiveLength) {
+        tagging.useDefinitiveLength(isDefinitiveLength);
+    }
+
+    @Override
+    public boolean isDefinitiveLength() {
+        return tagging.isDefinitiveLength();
+    }
+
+    @Override
+    public void useImplicit(boolean isImplicit) {
+        tagging.useImplicit(isImplicit);
+    }
+
+    @Override
+    public boolean isImplicit() {
+        return tagging.isImplicit();
+    }
+
+    @Override
+    public void useDER() {
+        tagging.useDER();
+    }
+
+    @Override
+    public boolean isDER() {
+        return tagging.isDER();
+    }
+
+    @Override
+    public void useBER() {
+        tagging.useBER();
+    }
+
+    @Override
+    public boolean isBER() {
+        return tagging.isBER();
+    }
+
+    @Override
+    public void useCER() {
+        tagging.useCER();
+    }
+
+    @Override
+    public boolean isCER() {
+        return tagging.isCER();
+    }
+
+
+    @Override
+    protected int encodingBodyLength() throws IOException {
+        return tagging.encodingBodyLength();
+    }
+
+    @Override
+    protected void encodeBody(ByteBuffer buffer) throws IOException {
+        tagging.encodeBody(buffer);
+    }
+
+    @Override
+    public void decode(ByteBuffer content) throws IOException {
+        tagging.decode(content);
+    }
+
+    @Override
+    protected void decodeBody(Asn1ParseResult parseResult) throws IOException {
+        tagging.decodeBody(parseResult);
+    }
+
+    protected <T extends Asn1Type> T getFieldAs(EnumType index, Class<T> t) {
+        return tagged.getFieldAs(index, t);
+    }
+
+    protected void setFieldAs(EnumType index, Asn1Type value) {
+        tagged.setFieldAs(index, value);
+    }
+
+    protected String getFieldAsString(EnumType index) {
+        return tagged.getFieldAsString(index);
+    }
+
+    protected byte[] getFieldAsOctets(EnumType index) {
+        return tagged.getFieldAsOctets(index);
+    }
+
+    protected void setFieldAsOctets(EnumType index, byte[] bytes) {
+        tagged.setFieldAsOctets(index, bytes);
+    }
+
+    protected Integer getFieldAsInteger(EnumType index) {
+        return tagged.getFieldAsInteger(index);
+    }
+
+    protected void setFieldAsInt(EnumType index, int value) {
+        tagged.setFieldAsInt(index, value);
+    }
+
+    protected byte[] getFieldAsOctetBytes(EnumType index) {
+        return tagged.getFieldAsOctets(index);
+    }
+
+    protected void setFieldAsOctetBytes(EnumType index, byte[] value) {
+        tagged.setFieldAsOctets(index, value);
+    }
+
+    @Override
+    public void dumpWith(Asn1Dumper dumper, int indents) {
+        Asn1Type taggedValue = getValue();
+        dumper.indent(indents).appendType(getClass());
+        dumper.append(simpleInfo()).newLine();
+        dumper.dumpType(indents, taggedValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSequence.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSequence.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSequence.java
new file mode 100644
index 0000000..61128de
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSequence.java
@@ -0,0 +1,38 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Asn1FieldInfo;
+
+/**
+ * For tagging a sequence type with tagNo, either application specific or context specific class
+ */
+public class Asn1TaggingSequence extends Asn1TaggingCollection {
+
+    public Asn1TaggingSequence(int taggingTagNo, Asn1FieldInfo[] tags,
+                               boolean isAppSpecific, boolean isImplicit) {
+        super(taggingTagNo, tags, isAppSpecific, isImplicit);
+    }
+
+    @Override
+    protected Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags) {
+        return new Asn1SequenceType(tags);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSet.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSet.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSet.java
new file mode 100644
index 0000000..e9eb17f
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingSet.java
@@ -0,0 +1,39 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Asn1FieldInfo;
+
+/**
+ * For tagging a sequence type with tagNo, either application specific or
+ * context specific class
+ */
+public class Asn1TaggingSet extends Asn1TaggingCollection {
+
+    public Asn1TaggingSet(int taggingTagNo, Asn1FieldInfo[] tags,
+                          boolean isAppSpecific, boolean isImplicit) {
+        super(taggingTagNo, tags, isAppSpecific, isImplicit);
+    }
+
+    @Override
+    protected Asn1CollectionType createTaggedCollection(Asn1FieldInfo[] tags) {
+        return new Asn1SetType(tags);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Type.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Type.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Type.java
new file mode 100644
index 0000000..6b0fa67
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Type.java
@@ -0,0 +1,189 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.TaggingOption;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * The ASN1 type interface for all ASN1 types.
+ */
+public interface Asn1Type {
+    /**
+     * Encoding type
+     */
+    enum EncodingType {
+        BER,
+        DER,
+        CER;
+    }
+
+    /**
+     *
+     * @return The tag
+     */
+    Tag tag();
+
+    /**
+     * Use primitive or constructed.
+     */
+    void usePrimitive(boolean isPrimitive);
+
+    /**
+     * Tells if it is PRIMITIVE or not.
+     *
+     * @return true if using PRIMITIVE, false otherwise
+     */
+    boolean isPrimitive();
+
+    /**
+     * Use definitive length or not.
+     * Note definitive length only makes sense when it's constructed.
+     */
+    void useDefinitiveLength(boolean isDefinitiveLength);
+
+    /**
+     * Tells if it's definitive length or not.
+     * @return The boolean value
+     */
+    boolean isDefinitiveLength();
+
+    /**
+     * Use implicit or not.
+     */
+    void useImplicit(boolean isImplicit);
+
+    /**
+     * Tells if it's is IMPLICIT or not.
+     *
+     * @return true if using IMPLICIT, false otherwise
+     */
+    boolean isImplicit();
+
+    /**
+     * Set encoding type as DER.
+     */
+    void useDER();
+
+    /**
+     * Tells if it's is DER
+     *
+     * @return true if using DER, false otherwise
+     */
+    boolean isDER();
+
+    /**
+     * Set encoding type as BER.
+     */
+    void useBER();
+
+    /**
+     * Tells if it's is BER
+     *
+     * @return true if using BER, false otherwise
+     */
+    boolean isBER();
+
+    /**
+     * Set encoding type as CER.
+     */
+    void useCER();
+
+    /**
+     * Tells if it's is CER
+     *
+     * @return true if using CER, false otherwise
+     */
+    boolean isCER();
+
+    /**
+     * Get length of encoding bytes by just calculating without real encoding.
+     * Generally it's called to prepare for the encoding buffer.
+     * @return length of encoding bytes
+     */
+    int encodingLength() throws IOException;
+
+    /**
+     * Encode the type, by recursively.
+     * @return encoded bytes
+     */
+    byte[] encode() throws IOException;
+
+    /**
+     * Encode the type, by recursively, using the provided buffer.
+     * @param buffer The byte buffer
+     */
+    void encode(ByteBuffer buffer) throws IOException;
+
+    /**
+     * Decode the content bytes into this type.
+     * @param content The content bytes
+     * @throws IOException e
+     */
+    void decode(byte[] content) throws IOException;
+
+    /**
+     * Decode the content bytes into this type.
+     * @param content The content bytes
+     * @throws IOException e
+     */
+    void decode(ByteBuffer content) throws IOException;
+
+    /**
+     * Tag and encode this type using the provided tagging option.
+     * @param taggingOption The tagging option
+     * @return encoded bytes
+     */
+    byte[] taggedEncode(TaggingOption taggingOption) throws IOException;
+
+    /**
+     * Tag and encode this type using the provided tagging option.
+     * @param buffer The byte buffer
+     * @param taggingOption The tagging option
+     */
+    void taggedEncode(ByteBuffer buffer, TaggingOption taggingOption) throws IOException;
+
+    /**
+     * Decode the content bytes into this type as it's tagged with the provided
+     * tagging option.
+     *
+     * See {@link org.apache.kerby.asn1.TaggingOption}
+     *
+     * @param content The content bytes
+     * @param taggingOption The tagging option
+     * @throws IOException e
+     */
+    void taggedDecode(ByteBuffer content, TaggingOption taggingOption) throws IOException;
+
+    /**
+     * Decode the content bytes into this type as it's tagged with the provided
+     * tagging option.
+     *
+     * See {@link org.apache.kerby.asn1.TaggingOption}
+     *
+     * @param content The content bytes
+     * @param taggingOption The tagging option
+     * @throws IOException e
+     */
+    void taggedDecode(byte[] content, TaggingOption taggingOption) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UniversalString.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UniversalString.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UniversalString.java
new file mode 100644
index 0000000..32b08f3
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UniversalString.java
@@ -0,0 +1,32 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UtcTime.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UtcTime.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UtcTime.java
new file mode 100644
index 0000000..2d0e884
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1UtcTime.java
@@ -0,0 +1,87 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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 = 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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Utf8String.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Utf8String.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Utf8String.java
new file mode 100644
index 0000000..a92f145
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Utf8String.java
@@ -0,0 +1,46 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1VisibleString.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1VisibleString.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1VisibleString.java
new file mode 100644
index 0000000..608d2ad
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1VisibleString.java
@@ -0,0 +1,32 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.type;
+
+import org.apache.kerby.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-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Util.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Util.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Util.java
new file mode 100644
index 0000000..a1f3438
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Util.java
@@ -0,0 +1,119 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.util;
+
+import org.apache.kerby.asn1.Tag;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The abstract ASN1 object for all the ASN1 types. It provides basic
+ * encoding and decoding utilities.
+ */
+public final class Asn1Util {
+    private Asn1Util() {
+        
+    }
+
+    public static int lengthOfBodyLength(int bodyLength) {
+        int length = 1;
+
+        if (bodyLength > 127) {
+            int payload = bodyLength;
+            while (payload != 0) {
+                payload >>= 8;
+                length++;
+            }
+        }
+
+        return length;
+    }
+
+    public static int lengthOfTagLength(int tagNo) {
+        int length = 1;
+
+        if (tagNo >= 31) {
+            if (tagNo < 128) {
+                length++;
+            } else {
+                length++;
+
+                do {
+                    tagNo >>= 7;
+                    length++;
+                } while (tagNo > 127);
+            }
+        }
+
+        return length;
+    }
+
+    public static void encodeTag(ByteBuffer buffer, Tag tag) {
+        int flags = tag.tagFlags();
+        int tagNo = tag.tagNo();
+
+        if (tagNo < 31) {
+            buffer.put((byte) (flags | tagNo));
+        } else {
+            buffer.put((byte) (flags | 0x1f));
+            if (tagNo < 128) {
+                buffer.put((byte) tagNo);
+            } else {
+                byte[] tmpBytes = new byte[5]; // 5 * 7 > 32
+                int iPut = tmpBytes.length;
+
+                tmpBytes[--iPut] = (byte) (tagNo & 0x7f);
+                do {
+                    tagNo >>= 7;
+                    tmpBytes[--iPut] = (byte) (tagNo & 0x7f | 0x80);
+                } while (tagNo > 127);
+
+                buffer.put(tmpBytes, iPut, tmpBytes.length - iPut);
+            }
+        }
+    }
+
+    public static void encodeLength(ByteBuffer buffer, int bodyLength) {
+        if (bodyLength < 128) {
+            buffer.put((byte) bodyLength);
+        } else {
+            int length = 0;
+            int payload = bodyLength;
+
+            while (payload != 0) {
+                payload >>= 8;
+                length++;
+            }
+
+            buffer.put((byte) (length | 0x80));
+
+            payload = bodyLength;
+            for (int i = length - 1; i >= 0; i--) {
+                buffer.put((byte) (payload >> (i * 8)));
+            }
+        }
+    }
+
+    public static byte[] readAllLeftBytes(ByteBuffer buffer) {
+        byte[] result = new byte[buffer.remaining()];
+        buffer.get(result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/HexUtil.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/HexUtil.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/HexUtil.java
new file mode 100644
index 0000000..66a0ee8
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/HexUtil.java
@@ -0,0 +1,113 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1.util;
+
+/**
+ * This is only for test, be careful when use in production codes.
+ */
+public class HexUtil {
+
+    static final String HEX_CHARS_STR = "0123456789ABCDEF";
+    static final char[] HEX_CHARS = HEX_CHARS_STR.toCharArray();
+
+    /**
+     * Convert bytes into friendly format as:
+     * 0x02 02 00 80
+     */
+    public static String bytesToHexFriendly(byte[] bytes) {
+        int len = bytes.length * 2;
+        len += bytes.length; // for ' ' appended for each char
+        len += 2; // for '0x' prefix
+        char[] hexChars = new char[len];
+        hexChars[0] = '0';
+        hexChars[1] = 'x';
+        for (int j = 0; j < bytes.length; j++) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 3 + 2] = HEX_CHARS[v >>> 4];
+            hexChars[j * 3 + 3] = HEX_CHARS[v & 0x0F];
+            hexChars[j * 3 + 4] = ' ';
+        }
+
+        return new String(hexChars);
+    }
+
+    /**
+     * Convert friendly hex string like follows into byte array
+     * 0x02 02 00 80
+     */
+    public static byte[] hex2bytesFriendly(String hexString) {
+        hexString = hexString.toUpperCase();
+        String hexStr = hexString;
+        if (hexString.startsWith("0X")) {
+            hexStr = hexString.substring(2);
+        }
+        String[] hexParts = hexStr.split(" ");
+
+        byte[] bytes = new byte[hexParts.length];
+        char[] hexPart;
+        for (int i = 0; i < hexParts.length; ++i) {
+            hexPart = hexParts[i].toCharArray();
+            if (hexPart.length != 2) {
+                throw new IllegalArgumentException("Invalid hex string to convert");
+            }
+            bytes[i] = (byte) ((HEX_CHARS_STR.indexOf(hexPart[0]) << 4)
+                + HEX_CHARS_STR.indexOf(hexPart[1]));
+        }
+
+        return bytes;
+    }
+
+    /**
+     * Convert bytes into format as:
+     * 02020080
+     * @param bytes The bytes
+     * @return The hex string
+     */
+    public static String bytesToHex(byte[] bytes) {
+        int len = bytes.length * 2;
+        char[] hexChars = new char[len];
+        for (int j = 0; j < bytes.length; j++) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = HEX_CHARS[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
+        }
+
+        return new String(hexChars);
+    }
+
+    /**
+     * Convert hex string like follows into byte array
+     * 02020080
+     * @param hexString The hex string
+     * @return The bytes
+     */
+    public static byte[] hex2bytes(String hexString) {
+        hexString = hexString.toUpperCase();
+        int len = hexString.length() / 2;
+        byte[] bytes = new byte[len];
+        char[] hexChars = hexString.toCharArray();
+        for (int i = 0, j = 0; i < len; ++i) {
+            bytes[i] = (byte) ((HEX_CHARS_STR.indexOf(hexChars[j++]) << 4)
+                + HEX_CHARS_STR.indexOf(hexChars[j++]));
+        }
+
+        return bytes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/IOUtil.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/IOUtil.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/IOUtil.java
new file mode 100644
index 0000000..02d1531
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/IOUtil.java
@@ -0,0 +1,109 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.asn1.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * Some IO and file related utilities.
+ */
+public final class IOUtil {
+    private IOUtil() { }
+
+    public static byte[] readInputStream(InputStream in) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int length = 0;
+        while ((length = in.read(buffer)) != -1) {
+            baos.write(buffer, 0, length);
+        }
+        in.close();
+        return baos.toByteArray();
+    }
+
+    public static void readInputStream(InputStream in,
+                                       byte[] buf) throws IOException {
+        int toRead = buf.length;
+        int off = 0;
+        while (toRead > 0) {
+            int ret = in.read(buf, off, toRead);
+            if (ret < 0) {
+                throw new IOException("Bad inputStream, premature EOF");
+            }
+            toRead -= ret;
+            off += ret;
+        }
+        in.close();
+    }
+
+    /**
+     * Read an input stream and return the content as string assuming UTF8.
+     * @param in The input stream
+     * @return The content
+     * @throws IOException e
+     */
+    public static String readInput(InputStream in) throws IOException {
+        byte[] content = readInputStream(in);
+        return Utf8.toString(content);
+    }
+
+    /**
+     * Read a file and return the content as string assuming UTF8.
+     * @param file The file to read
+     * @return The content
+     * @throws IOException e
+     */
+    public static String readFile(File file) throws IOException {
+        long len = 0;
+        if (file.length() >= Integer.MAX_VALUE) {
+            throw new IOException("Too large file, unexpected!");
+        } else {
+            len = file.length();
+        }
+        byte[] buf = new byte[(int) len];
+
+        InputStream is = new FileInputStream(file);
+        readInputStream(is, buf);
+
+        return Utf8.toString(buf);
+    }
+
+    /**
+     * Write a file with the content assuming UTF8.
+     * @param content The content
+     * @param file The file to write
+     * @throws IOException e
+     */
+    public static void writeFile(String content, File file) throws IOException {
+        FileOutputStream outputStream = new FileOutputStream(file);
+        FileChannel fc = outputStream.getChannel();
+
+        ByteBuffer buffer = ByteBuffer.wrap(Utf8.toBytes(content));
+        fc.write(buffer);
+        outputStream.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Utf8.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Utf8.java b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Utf8.java
new file mode 100644
index 0000000..d24b12b
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Utf8.java
@@ -0,0 +1,34 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.asn1.util;
+
+import java.nio.charset.StandardCharsets;
+
+public final class Utf8 {
+    private Utf8() { }
+
+    public static String toString(byte[] bytes) {
+        return new String(bytes, StandardCharsets.UTF_8);
+    }
+
+    public static byte[] toBytes(String s) {
+        return s.getBytes(StandardCharsets.UTF_8);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1BooleanTest.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1BooleanTest.java b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1BooleanTest.java
new file mode 100644
index 0000000..5557975
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1BooleanTest.java
@@ -0,0 +1,70 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1;
+
+import org.apache.kerby.asn1.type.Asn1Boolean;
+import org.apache.kerby.asn1.util.HexUtil;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class Asn1BooleanTest {
+
+    @Test
+    public void testEncoding() throws IOException {
+        testEncodingWith(true, "0x01 01 FF", true);
+        testEncodingWith(false, "0x01 01 00", true);
+    }
+
+    private void testEncodingWith(Boolean value, String expectedEncoding,
+                                  boolean isDer) throws IOException {
+        byte[] expected = HexUtil.hex2bytesFriendly(expectedEncoding);
+        Asn1Boolean aValue = new Asn1Boolean(value);
+        if (isDer) {
+            aValue.useDER();
+        } else {
+            aValue.useBER();
+        }
+        byte[] encodingBytes = aValue.encode();
+        assertThat(encodingBytes).isEqualTo(expected);
+    }
+
+    @Test
+    public void testDecoding() throws IOException {
+        testDecodingWith(true, "0x01 01 FF", true);
+        testDecodingWith(false, "0x01 01 7F", true);
+        testDecodingWith(true, "0x01 01 7F", false);
+        testDecodingWith(false, "0x01 01 00", true);
+    }
+
+    private void testDecodingWith(Boolean expectedValue, String content,
+                                  boolean isDer) throws IOException {
+        Asn1Boolean decoded = new Asn1Boolean();
+        if (isDer) {
+            decoded.useDER();
+        } else {
+            decoded.useBER();
+        }
+        decoded.decode(HexUtil.hex2bytesFriendly(content));
+        assertThat(decoded.getValue()).isEqualTo(expectedValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1CollectionTest.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1CollectionTest.java b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1CollectionTest.java
new file mode 100644
index 0000000..50d51af
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1CollectionTest.java
@@ -0,0 +1,60 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1;
+
+import org.apache.kerby.asn1.type.Asn1Boolean;
+import org.apache.kerby.asn1.type.Asn1IA5String;
+import org.apache.kerby.asn1.type.Asn1Sequence;
+import org.apache.kerby.asn1.type.Asn1String;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class Asn1CollectionTest {
+    static final String TEST_STR = "Jones";
+    static final Boolean TEST_BOOL = true;
+    static final byte[] EXPECTED_BYTES = new byte[] {(byte) 0x30, (byte) 0x0A,
+            (byte) 0x16, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E,
+            (byte) 0x65, (byte) 0x73, (byte) 0x01, (byte) 0x01, (byte) 0xFF
+    };
+
+    @Test
+    public void testSequenceEncoding() throws IOException {
+        Asn1Sequence seq = new Asn1Sequence();
+        seq.addItem(new Asn1IA5String(TEST_STR));
+        seq.addItem(new Asn1Boolean(TEST_BOOL));
+
+        assertThat(seq.encode()).isEqualTo(EXPECTED_BYTES);
+    }
+
+    @Test
+    public void testSequenceDecoding() throws IOException {
+        Asn1Sequence seq = new Asn1Sequence();
+        seq.decode(EXPECTED_BYTES);
+        Asn1String field =
+            (Asn1String) seq.getValue().get(0);
+        assertThat(field.getValue()).isEqualTo(TEST_STR);
+
+        Asn1Boolean field2 = (Asn1Boolean) seq.getValue().get(1);
+        assertThat(field2.getValue()).isEqualTo(TEST_BOOL);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1ConstructedOctetStringTest.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1ConstructedOctetStringTest.java b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1ConstructedOctetStringTest.java
new file mode 100644
index 0000000..7b110a9
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1ConstructedOctetStringTest.java
@@ -0,0 +1,36 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1;
+
+import org.apache.kerby.asn1.type.Asn1OctetString;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class Asn1ConstructedOctetStringTest {
+
+    @Test
+    public void testDecoding() throws IOException {
+        byte[] data = TestUtil.readBytesFromTxtFile("/constructed-octet-string.txt");
+        Asn1OctetString octetString = new Asn1OctetString();
+        octetString.decode(data);
+        Asn1.dump(octetString);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1DumpTest.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1DumpTest.java b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1DumpTest.java
new file mode 100644
index 0000000..fb83fc0
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1DumpTest.java
@@ -0,0 +1,95 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.asn1;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class Asn1DumpTest {
+
+    @Test
+    @org.junit.Ignore
+    public void testDumpWithPersonnelRecord() throws IOException {
+        try {
+            PersonnelRecord pr = DataTest.createSamplePersonnel();
+            Asn1.dump(pr);
+
+            byte[] data = DataTest.createSammplePersonnelEncodingData();
+            Asn1.parseAndDump(data);
+            Asn1.decodeAndDump(data);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    @org.junit.Ignore
+    public void testDumpWithCompressedData() throws IOException {
+        String hexStr = TestUtil.readStringFromTxtFile("/compressed-data.txt");
+        try {
+            Asn1.parseAndDump(hexStr);
+            Asn1.decodeAndDump(hexStr);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    @org.junit.Ignore
+    public void testDumpWithSignedData() throws IOException {
+        String hexStr = TestUtil.readStringFromTxtFile("/signed-data.txt");
+        try {
+            Asn1.parseAndDump(hexStr);
+            Asn1.decodeAndDump(hexStr);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    @org.junit.Ignore
+    public void testDumpWithDerData() throws IOException {
+        byte[] data = TestUtil.readBytesFromBinFile("/der-data.dat");
+        try {
+            Asn1.parseAndDump(data);
+            Asn1.decodeAndDump(data);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void testDumpWithEmptyContainer() throws IOException {
+        byte[] data = TestUtil.readBytesFromTxtFile("/empty-container.txt");
+        try {
+            Asn1.parseAndDump(data);
+            Asn1.decodeAndDump(data);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9e4dbd6e/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1FlagsTest.java
----------------------------------------------------------------------
diff --git a/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1FlagsTest.java b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1FlagsTest.java
new file mode 100644
index 0000000..3182811
--- /dev/null
+++ b/kerby-common/kerby-asn1/src/test/java/org/apache/kerby/asn1/Asn1FlagsTest.java
@@ -0,0 +1,158 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.asn1;
+
+import org.apache.kerby.asn1.type.Asn1Flags;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class Asn1FlagsTest {
+  
+  public static final int FLAG_0 = 0b00000000000000000000000000000001;
+  public static final int FLAG_1 = 0b00000000000000000000000000000010;
+  public static final int FLAG_2 = 0x00000004;
+  public static final int FLAG_3 = 0x00000008;
+  public static final int FLAG_4 = 16;
+  public static final int FLAG_5 = 32;
+  
+  public enum TestEnum implements EnumType {
+    FLAG_0(0x00000001),
+    FLAG_1(0x00000002),
+    FLAG_2(0x00000004),
+    FLAG_3(0x00000008),
+    FLAG_4(0x00000010),
+    FLAG_5(0x00000020);
+    
+    private int value;
+    
+    private TestEnum(int value) {
+      this.value = value;
+    }
+
+    @Override
+    public int getValue() {
+      return value;
+    }
+
+
+    @Override
+    public String getName() {
+      return name();
+    }
+  }
+  
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+  
+  private Asn1Flags flags;
+  
+  @Before
+  public void setUp() {
+    flags = new Asn1Flags(FLAG_5 | FLAG_3 | FLAG_1);
+  }
+
+  @Test
+  public void testToValue() throws IOException {
+    byte[] value = {(byte) 0xDE, (byte) 0xAD, (byte) 0xBE, (byte) 0xEF};
+    flags.setValue(value);
+    assertEquals(0b11011110101011011011111011101111, flags.getFlags());
+  }
+
+  @Test
+  public void testFlags() {
+    flags = new Asn1Flags();
+    assertEquals(0b00000000000000000000000000000000, flags.getFlags());
+  }
+
+  @Test
+  public void testFlagsInt() {
+    flags = new Asn1Flags(FLAG_4 | FLAG_2 | FLAG_0);
+    assertEquals(0b00000000000000000000000000010101, flags.getFlags());
+  }
+
+  @Test
+  public void testSetFlags() {
+    flags.setFlags(FLAG_4 | FLAG_2 | FLAG_0);
+    assertEquals(0b00000000000000000000000000010101, flags.getFlags());
+  }
+
+  @Test
+  public void testGetFlags() {
+    assertEquals(0b00000000000000000000000000101010, flags.getFlags());
+  }
+
+  @Test
+  public void testIsFlagSetInt() {
+    assertTrue(flags.isFlagSet(FLAG_5));
+    assertFalse(flags.isFlagSet(FLAG_4));
+  }
+
+  @Test
+  public void testSetFlagInt() {
+    flags.setFlag(FLAG_4);
+    assertEquals(0b00000000000000000000000000111010, flags.getFlags());
+  }
+
+  @Test
+  public void testClearFlagInt() {
+    flags.clearFlag(FLAG_3);
+    assertEquals(0b00000000000000000000000000100010, flags.getFlags());
+  }
+
+  @Test
+  public void testClear() {
+    flags.clear();
+    assertEquals(0b00000000000000000000000000000000, flags.getFlags());
+  }
+
+  @Test
+  public void testIsFlagSetEnum() {
+    assertTrue(flags.isFlagSet(TestEnum.FLAG_5));
+    assertFalse(flags.isFlagSet(TestEnum.FLAG_4));
+  }
+
+  @Test
+  public void testSetFlagEnum() {
+    flags.setFlag(TestEnum.FLAG_4);
+    assertEquals(0b00000000000000000000000000111010, flags.getFlags());
+  }
+
+  @Test
+  public void testSetFlagEnumBoolean() {
+    flags.setFlag(TestEnum.FLAG_4, true);
+    assertEquals(0b00000000000000000000000000111010, flags.getFlags());
+    flags.setFlag(TestEnum.FLAG_4, false);
+    assertEquals(0b00000000000000000000000000101010, flags.getFlags());
+  }
+
+  @Test
+  public void testClearFlagEnum() {
+    flags.clearFlag(TestEnum.FLAG_3);
+    assertEquals(0b00000000000000000000000000100010, flags.getFlags());
+  }
+}


Mime
View raw message