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/11/28 14:49:05 UTC

directory-kerby git commit: Separate encode/decode specific stuffs from AbstractAsn1Type into Asn1Object

Repository: directory-kerby
Updated Branches:
  refs/heads/master af7deb64e -> 9601a5a8e


Separate encode/decode specific stuffs from AbstractAsn1Type into Asn1Object


Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/9601a5a8
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/9601a5a8
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/9601a5a8

Branch: refs/heads/master
Commit: 9601a5a8e83d1c39df581b2cff6a260a5330dc72
Parents: af7deb6
Author: Kai Zheng <ka...@intel.com>
Authored: Sat Nov 28 17:30:37 2015 +0800
Committer: Kai Zheng <ka...@intel.com>
Committed: Sat Nov 28 17:30:37 2015 +0800

----------------------------------------------------------------------
 .../org/apache/kerby/asn1/Asn1InputBuffer.java  |   6 +-
 .../org/apache/kerby/asn1/Asn1OutputBuffer.java |   3 +-
 .../kerby/asn1/type/AbstractAsn1Type.java       | 440 +----------------
 .../org/apache/kerby/asn1/type/Asn1Object.java  | 484 +++++++++++++++++++
 .../kerberos/kerb/common/CheckSumUtil.java      |   6 +-
 .../kerberos/kerb/common/EncryptionUtil.java    |   4 +-
 .../apache/kerby/kerberos/kerb/KrbCodec.java    |   8 +-
 7 files changed, 500 insertions(+), 451 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1InputBuffer.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1InputBuffer.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1InputBuffer.java
index aeb5864..9d90319 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1InputBuffer.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1InputBuffer.java
@@ -19,8 +19,8 @@
  */
 package org.apache.kerby.asn1;
 
-import org.apache.kerby.asn1.type.AbstractAsn1Type;
 import org.apache.kerby.asn1.type.Asn1Item;
+import org.apache.kerby.asn1.type.Asn1Object;
 import org.apache.kerby.asn1.type.Asn1Type;
 
 import java.io.IOException;
@@ -68,7 +68,7 @@ public class Asn1InputBuffer {
         if (!limitedBuffer.available()) {
             return null;
         }
-        Asn1Item one = AbstractAsn1Type.decodeOne(limitedBuffer);
+        Asn1Item one = Asn1Object.decodeOne(limitedBuffer);
         if (one.isSimple()) {
             one.decodeValueAsSimple();
         } else if (one.isCollection()) {
@@ -96,7 +96,7 @@ public class Asn1InputBuffer {
 
     public void skipNext() throws IOException {
         if (limitedBuffer.available()) {
-            AbstractAsn1Type.skipOne(limitedBuffer);
+            Asn1Object.skipOne(limitedBuffer);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1OutputBuffer.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1OutputBuffer.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1OutputBuffer.java
index f50d092..7748df6 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1OutputBuffer.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1OutputBuffer.java
@@ -20,6 +20,7 @@
 package org.apache.kerby.asn1;
 
 import org.apache.kerby.asn1.type.AbstractAsn1Type;
+import org.apache.kerby.asn1.type.Asn1Object;
 import org.apache.kerby.asn1.type.Asn1Type;
 
 import java.nio.ByteBuffer;
@@ -51,7 +52,7 @@ public class Asn1OutputBuffer {
         int allLen = 0;
         for (Asn1Type item : objects) {
             if (item != null) {
-                allLen += ((AbstractAsn1Type<?>) item).encodingLength();
+                allLen += ((Asn1Object) item).encodingLength();
             }
         }
         return allLen;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/AbstractAsn1Type.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/AbstractAsn1Type.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/AbstractAsn1Type.java
index 7446c7c..4dc2c28 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/AbstractAsn1Type.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/AbstractAsn1Type.java
@@ -19,12 +19,7 @@
  */
 package org.apache.kerby.asn1.type;
 
-import org.apache.kerby.asn1.LimitedByteBuffer;
 import org.apache.kerby.asn1.TagClass;
-import org.apache.kerby.asn1.TaggingOption;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
 
 /**
  * The abstract ASN1 type for all the ASN1 types. It provides basic
@@ -32,20 +27,10 @@ import java.nio.ByteBuffer;
  *
  * @param <T> the type of the value encoded/decoded or wrapped by this
  */
-public abstract class AbstractAsn1Type<T> implements Asn1Type {
-
-    private TagClass tagClass = TagClass.UNKNOWN;
-    private int tagNo = -1;
-    private int tagFlags = 0;
-    private int encodingLen = -1;
+public abstract class AbstractAsn1Type<T> extends Asn1Object {
     // The wrapped real value.
     private T value;
 
-    // encoding options
-    private EncodingType encodingType = EncodingType.BER;
-    private boolean isImplicit = true;
-    private boolean isDefinitiveLength = false;
-
     /**
      * Default constructor, generally for decoding as a value container
      * @param tagClass The tag class
@@ -82,11 +67,8 @@ public abstract class AbstractAsn1Type<T> implements Asn1Type {
      * @param value The value
      */
     public AbstractAsn1Type(TagClass tagClass, int tagNo, T value) {
-        this.tagClass = tagClass;
-        this.tagNo = tagNo;
+        super(tagClass, tagNo);
         this.value = value;
-
-        this.tagFlags |= tagClass.getValue();
     }
 
     public T getValue() {
@@ -96,422 +78,4 @@ public abstract class AbstractAsn1Type<T> implements Asn1Type {
     public void setValue(T value) {
         this.value = value;
     }
-
-    @Override
-    public TagClass tagClass() {
-        return tagClass;
-    }
-
-    protected void setTagClass(TagClass tagClass) {
-        this.tagClass = tagClass;
-    }
-
-    @Override
-    public int tagFlags() {
-        return tagFlags;
-    }
-
-    @Override
-    public int tagNo() {
-        return tagNo;
-    }
-
-    protected void setTagFlags(int tagFlags) {
-        this.tagFlags = tagFlags & 0xe0;
-    }
-
-    protected void setTagNo(int tagNo) {
-        this.tagNo = tagNo;
-    }
-
-    @Override
-    public void usePrimitive(boolean isPrimitive) {
-        if (isPrimitive) {
-            tagFlags &= ~CONSTRUCTED_FLAG;
-        } else {
-            tagFlags |= CONSTRUCTED_FLAG;
-        }
-    }
-
-    @Override
-    public boolean isPrimitive() {
-        return (tagFlags & CONSTRUCTED_FLAG) == 0;
-    }
-
-    @Override
-    public void useDefinitiveLength(boolean isDefinitiveLength) {
-        this.isDefinitiveLength = isDefinitiveLength;
-    }
-
-    @Override
-    public boolean isDefinitiveLength() {
-        return isDefinitiveLength;
-    }
-
-    @Override
-    public void useImplicit(boolean isImplicit) {
-        this.isImplicit = isImplicit;
-    }
-
-    @Override
-    public boolean isImplicit() {
-        return isImplicit;
-    }
-
-    @Override
-    public void useDER() {
-        this.encodingType = EncodingType.DER;
-    }
-
-    @Override
-    public boolean isDER() {
-        return encodingType == EncodingType.DER;
-    }
-
-    @Override
-    public void useBER() {
-        this.encodingType = EncodingType.BER;
-    }
-
-    @Override
-    public boolean isBER() {
-        return encodingType == EncodingType.BER;
-    }
-
-    @Override
-    public void useCER() {
-        this.encodingType = EncodingType.CER;
-    }
-
-    @Override
-    public boolean isCER() {
-        return encodingType == EncodingType.CER;
-    }
-
-    @Override
-    public byte[] encode() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodingLength());
-        encode(byteBuffer);
-        byteBuffer.flip();
-        return byteBuffer.array();
-    }
-
-    @Override
-    public void encode(ByteBuffer buffer) {
-        encodeTag(buffer, tagFlags(), tagNo());
-        encodeLength(buffer, encodingBodyLength());
-        encodeBody(buffer);
-    }
-
-    protected void encodeBody(ByteBuffer buffer) { }
-
-    @Override
-    public void decode(byte[] content) throws IOException {
-        decode(new LimitedByteBuffer(content));
-    }
-
-    @Override
-    public void decode(ByteBuffer content) throws IOException {
-        decode(new LimitedByteBuffer(content));
-    }
-
-    @Override
-    public int encodingLength() {
-        if (encodingLen == -1) {
-            int bodyLen = encodingBodyLength();
-            encodingLen = lengthOfTagLength(tagNo()) + lengthOfBodyLength(bodyLen) + bodyLen;
-        }
-        return encodingLen;
-    }
-
-    public boolean isUniversal() {
-        return tagClass.isUniversal();
-    }
-
-    public boolean isAppSpecific() {
-        return tagClass.isAppSpecific();
-    }
-
-    public boolean isContextSpecific() {
-        return tagClass.isContextSpecific();
-    }
-
-    public boolean isTagged() {
-        return tagClass.isTagged();
-    }
-
-    public boolean isSimple() {
-        return isUniversal() && Asn1Simple.isSimple(tagNo);
-    }
-
-    public boolean isCollection() {
-        return isUniversal() && Asn1Collection.isCollection(tagNo);
-    }
-
-    protected abstract int encodingBodyLength();
-
-    protected void decode(LimitedByteBuffer content) throws IOException {
-        int tag = readTag(content);
-        int tagNo = readTagNo(content, tag);
-        int tmpTagFlags = tag & 0xe0;
-        int length = readLength(content);
-
-        decode(tmpTagFlags, tagNo, new LimitedByteBuffer(content, length));
-    }
-
-    public void decode(int tagFlags, int tagNo,
-                       LimitedByteBuffer content) throws IOException {
-        if (tagClass() != TagClass.UNKNOWN && tagClass()
-                != TagClass.fromTagFlags(tagFlags)) {
-            throw new IOException("Unexpected tagFlags " + tagFlags
-                    + ", expecting " + tagClass());
-        }
-        if (tagNo() != -1 && tagNo() != tagNo) {
-            throw new IOException("Unexpected tagNo " + tagNo + ", "
-                    + "expecting " + tagNo());
-        }
-
-        setTagClass(TagClass.fromTagFlags(tagFlags));
-        setTagFlags(tagFlags);
-        setTagNo(tagNo);
-
-        decodeBody(content);
-    }
-
-    protected abstract void decodeBody(LimitedByteBuffer content) throws IOException;
-
-    protected int taggedEncodingLength(TaggingOption taggingOption) {
-        int taggingTagNo = taggingOption.getTagNo();
-        int taggingBodyLen = taggingOption.isImplicit() ? encodingBodyLength()
-                : encodingLength();
-        int taggingEncodingLen = lengthOfTagLength(taggingTagNo)
-                + lengthOfBodyLength(taggingBodyLen) + taggingBodyLen;
-        return taggingEncodingLen;
-    }
-
-    public byte[] taggedEncode(TaggingOption taggingOption) {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(taggedEncodingLength(taggingOption));
-        taggedEncode(byteBuffer, taggingOption);
-        byteBuffer.flip();
-        return byteBuffer.array();
-    }
-
-    @Override
-    public void taggedEncode(ByteBuffer buffer, TaggingOption taggingOption) {
-        int taggingTagFlags = taggingOption.tagFlags(!isPrimitive());
-        encodeTag(buffer, taggingTagFlags, taggingOption.getTagNo());
-        int taggingBodyLen = taggingOption.isImplicit() ? encodingBodyLength()
-                : encodingLength();
-        encodeLength(buffer, taggingBodyLen);
-        if (taggingOption.isImplicit()) {
-            encodeBody(buffer);
-        } else {
-            encode(buffer);
-        }
-    }
-
-    public void taggedDecode(byte[] content,
-                             TaggingOption taggingOption) throws IOException {
-        taggedDecode(ByteBuffer.wrap(content), taggingOption);
-    }
-
-    @Override
-    public void taggedDecode(ByteBuffer content,
-                             TaggingOption taggingOption) throws IOException {
-        LimitedByteBuffer limitedBuffer = new LimitedByteBuffer(content);
-        taggedDecode(limitedBuffer, taggingOption);
-    }
-
-    protected void taggedDecode(LimitedByteBuffer content,
-                                TaggingOption taggingOption) throws IOException {
-        int taggingTag = readTag(content);
-        int taggingTagNo = readTagNo(content, taggingTag);
-        int taggingLength = readLength(content);
-        LimitedByteBuffer newContent = new LimitedByteBuffer(content, taggingLength);
-
-        int tmpTagFlags = taggingTag & 0xe0;
-        taggedDecode(tmpTagFlags, taggingTagNo, newContent, taggingOption);
-    }
-
-    protected void taggedDecode(int taggingTagFlags, int taggingTagNo,
-                                LimitedByteBuffer content,
-                                TaggingOption taggingOption) throws IOException {
-        int expectedTaggingTagFlags = taggingOption.tagFlags(!isPrimitive());
-        if (expectedTaggingTagFlags != taggingTagFlags) {
-            throw new IOException("Unexpected tag flags " + taggingTagFlags
-                    + ", expecting " + expectedTaggingTagFlags);
-        }
-        if (taggingOption.getTagNo() != taggingTagNo) {
-            throw new IOException("Unexpected tagNo " + taggingTagNo + ", "
-                    + "expecting " + taggingOption.getTagNo());
-        }
-
-        if (taggingOption.isImplicit()) {
-            decodeBody(content);
-        } else {
-            decode(content);
-        }
-    }
-
-    public static Asn1Item decodeOne(LimitedByteBuffer content) throws IOException {
-        int tag = readTag(content);
-        int tagNo = readTagNo(content, tag);
-        int length = readLength(content);
-        if (length < 0) {
-            throw new IOException("Unexpected length");
-        }
-        LimitedByteBuffer valueContent = new LimitedByteBuffer(content, length);
-        content.skip(length);
-
-        Asn1Item result = new Asn1Item(tag, tagNo, valueContent);
-        if (result.isSimple()) {
-            result.decodeValueAsSimple();
-        }
-        return result;
-    }
-
-    public static void skipOne(LimitedByteBuffer content) throws IOException {
-        int tag = readTag(content);
-        readTagNo(content, tag);
-        int length = readLength(content);
-        if (length < 0) {
-            throw new IOException("Unexpected length");
-        }
-        content.skip(length);
-    }
-
-    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, int flags, int 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 int readTag(LimitedByteBuffer buffer) throws IOException {
-        int tag = buffer.readByte() & 0xff;
-        if (tag == 0) {
-            throw new IOException("Bad tag 0 found");
-        }
-        return tag;
-    }
-
-    public static int readTagNo(LimitedByteBuffer buffer, int tag) throws IOException {
-        int tagNo = tag & 0x1f;
-
-        if (tagNo == 0x1f) {
-            tagNo = 0;
-
-            int b = buffer.readByte() & 0xff;
-            if ((b & 0x7f) == 0) {
-                throw new IOException("Invalid high tag number found");
-            }
-
-            while (b >= 0 && (b & 0x80) != 0) {
-                tagNo |= b & 0x7f;
-                tagNo <<= 7;
-                b = buffer.readByte();
-            }
-
-            tagNo |= b & 0x7f;
-        }
-
-        return tagNo;
-    }
-
-    public static int readLength(LimitedByteBuffer buffer) throws IOException {
-        int bodyLength = buffer.readByte() & 0xff;
-
-        if (bodyLength > 127) {
-            int length = bodyLength & 0x7f;
-            if (length > 4) {
-                throw new IOException("Bad bodyLength of more than 4 bytes: " + length);
-            }
-
-            bodyLength = 0;
-            int tmp;
-            for (int i = 0; i < length; i++) {
-                tmp = buffer.readByte() & 0xff;
-                bodyLength = (bodyLength << 8) + tmp;
-            }
-
-            if (bodyLength < 0) {
-                throw new IOException("Invalid bodyLength " + bodyLength);
-            }
-            if (bodyLength > buffer.hasLeft()) {
-                throw new IOException("Corrupt stream - less data "
-                        + buffer.hasLeft() + " than expected " + bodyLength);
-            }
-        }
-
-        return bodyLength;
-    }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Object.java
----------------------------------------------------------------------
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Object.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Object.java
new file mode 100644
index 0000000..95da847
--- /dev/null
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Object.java
@@ -0,0 +1,484 @@
+/**
+ *  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.LimitedByteBuffer;
+import org.apache.kerby.asn1.TagClass;
+import org.apache.kerby.asn1.TaggingOption;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * The abstract ASN1 object for all the ASN1 types. It provides basic
+ * encoding and decoding utilities.
+ */
+public abstract class Asn1Object implements Asn1Type {
+
+    private TagClass tagClass = TagClass.UNKNOWN;
+    private int tagNo = -1;
+    private int tagFlags = 0;
+    private int encodingLen = -1;
+
+    // encoding options
+    private EncodingType encodingType = EncodingType.BER;
+    private boolean isImplicit = true;
+    private boolean isDefinitiveLength = false;
+
+    /**
+     * Constructor with a value, generally for encoding of the value
+     * @param tagFlags The tag flags
+     * @param tagNo The tag number
+     */
+    public Asn1Object(int tagFlags, int tagNo) {
+        this(TagClass.fromTagFlags(tagFlags), tagNo);
+        setTagFlags(tagFlags);
+    }
+
+    /**
+     * Constructor with a value, generally for encoding of the value
+     * @param tagClass The tag class
+     * @param tagNo The tag number
+     */
+    public Asn1Object(TagClass tagClass, int tagNo) {
+        this.tagClass = tagClass;
+        this.tagNo = tagNo;
+
+        this.tagFlags |= tagClass.getValue();
+    }
+
+    @Override
+    public TagClass tagClass() {
+        return tagClass;
+    }
+
+    protected void setTagClass(TagClass tagClass) {
+        this.tagClass = tagClass;
+    }
+
+    @Override
+    public int tagFlags() {
+        return tagFlags;
+    }
+
+    @Override
+    public int tagNo() {
+        return tagNo;
+    }
+
+    protected void setTagFlags(int tagFlags) {
+        this.tagFlags = tagFlags & 0xe0;
+    }
+
+    protected void setTagNo(int tagNo) {
+        this.tagNo = tagNo;
+    }
+
+    @Override
+    public void usePrimitive(boolean isPrimitive) {
+        if (isPrimitive) {
+            tagFlags &= ~CONSTRUCTED_FLAG;
+        } else {
+            tagFlags |= CONSTRUCTED_FLAG;
+        }
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return (tagFlags & CONSTRUCTED_FLAG) == 0;
+    }
+
+    @Override
+    public void useDefinitiveLength(boolean isDefinitiveLength) {
+        this.isDefinitiveLength = isDefinitiveLength;
+    }
+
+    @Override
+    public boolean isDefinitiveLength() {
+        return isDefinitiveLength;
+    }
+
+    @Override
+    public void useImplicit(boolean isImplicit) {
+        this.isImplicit = isImplicit;
+    }
+
+    @Override
+    public boolean isImplicit() {
+        return isImplicit;
+    }
+
+    @Override
+    public void useDER() {
+        this.encodingType = EncodingType.DER;
+    }
+
+    @Override
+    public boolean isDER() {
+        return encodingType == EncodingType.DER;
+    }
+
+    @Override
+    public void useBER() {
+        this.encodingType = EncodingType.BER;
+    }
+
+    @Override
+    public boolean isBER() {
+        return encodingType == EncodingType.BER;
+    }
+
+    @Override
+    public void useCER() {
+        this.encodingType = EncodingType.CER;
+    }
+
+    @Override
+    public boolean isCER() {
+        return encodingType == EncodingType.CER;
+    }
+
+    @Override
+    public byte[] encode() {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(encodingLength());
+        encode(byteBuffer);
+        byteBuffer.flip();
+        return byteBuffer.array();
+    }
+
+    @Override
+    public void encode(ByteBuffer buffer) {
+        encodeTag(buffer, tagFlags(), tagNo());
+        encodeLength(buffer, encodingBodyLength());
+        encodeBody(buffer);
+    }
+
+    protected void encodeBody(ByteBuffer buffer) { }
+
+    @Override
+    public void decode(byte[] content) throws IOException {
+        decode(new LimitedByteBuffer(content));
+    }
+
+    @Override
+    public void decode(ByteBuffer content) throws IOException {
+        decode(new LimitedByteBuffer(content));
+    }
+
+    @Override
+    public int encodingLength() {
+        if (encodingLen == -1) {
+            int bodyLen = encodingBodyLength();
+            encodingLen = lengthOfTagLength(tagNo()) + lengthOfBodyLength(bodyLen) + bodyLen;
+        }
+        return encodingLen;
+    }
+
+    public boolean isUniversal() {
+        return tagClass.isUniversal();
+    }
+
+    public boolean isAppSpecific() {
+        return tagClass.isAppSpecific();
+    }
+
+    public boolean isContextSpecific() {
+        return tagClass.isContextSpecific();
+    }
+
+    public boolean isTagged() {
+        return tagClass.isTagged();
+    }
+
+    public boolean isSimple() {
+        return isUniversal() && Asn1Simple.isSimple(tagNo);
+    }
+
+    public boolean isCollection() {
+        return isUniversal() && Asn1Collection.isCollection(tagNo);
+    }
+
+    protected abstract int encodingBodyLength();
+
+    protected void decode(LimitedByteBuffer content) throws IOException {
+        int tag = readTag(content);
+        int tagNo = readTagNo(content, tag);
+        int tmpTagFlags = tag & 0xe0;
+        int length = readLength(content);
+
+        decode(tmpTagFlags, tagNo, new LimitedByteBuffer(content, length));
+    }
+
+    public void decode(int tagFlags, int tagNo,
+                       LimitedByteBuffer content) throws IOException {
+        if (tagClass() != TagClass.UNKNOWN && tagClass()
+                != TagClass.fromTagFlags(tagFlags)) {
+            throw new IOException("Unexpected tagFlags " + tagFlags
+                    + ", expecting " + tagClass());
+        }
+        if (tagNo() != -1 && tagNo() != tagNo) {
+            throw new IOException("Unexpected tagNo " + tagNo + ", "
+                    + "expecting " + tagNo());
+        }
+
+        setTagClass(TagClass.fromTagFlags(tagFlags));
+        setTagFlags(tagFlags);
+        setTagNo(tagNo);
+
+        decodeBody(content);
+    }
+
+    protected abstract void decodeBody(LimitedByteBuffer content) throws IOException;
+
+    protected int taggedEncodingLength(TaggingOption taggingOption) {
+        int taggingTagNo = taggingOption.getTagNo();
+        int taggingBodyLen = taggingOption.isImplicit() ? encodingBodyLength()
+                : encodingLength();
+        int taggingEncodingLen = lengthOfTagLength(taggingTagNo)
+                + lengthOfBodyLength(taggingBodyLen) + taggingBodyLen;
+        return taggingEncodingLen;
+    }
+
+    public byte[] taggedEncode(TaggingOption taggingOption) {
+        ByteBuffer byteBuffer = ByteBuffer.allocate(taggedEncodingLength(taggingOption));
+        taggedEncode(byteBuffer, taggingOption);
+        byteBuffer.flip();
+        return byteBuffer.array();
+    }
+
+    @Override
+    public void taggedEncode(ByteBuffer buffer, TaggingOption taggingOption) {
+        int taggingTagFlags = taggingOption.tagFlags(!isPrimitive());
+        encodeTag(buffer, taggingTagFlags, taggingOption.getTagNo());
+        int taggingBodyLen = taggingOption.isImplicit() ? encodingBodyLength()
+                : encodingLength();
+        encodeLength(buffer, taggingBodyLen);
+        if (taggingOption.isImplicit()) {
+            encodeBody(buffer);
+        } else {
+            encode(buffer);
+        }
+    }
+
+    public void taggedDecode(byte[] content,
+                             TaggingOption taggingOption) throws IOException {
+        taggedDecode(ByteBuffer.wrap(content), taggingOption);
+    }
+
+    @Override
+    public void taggedDecode(ByteBuffer content,
+                             TaggingOption taggingOption) throws IOException {
+        LimitedByteBuffer limitedBuffer = new LimitedByteBuffer(content);
+        taggedDecode(limitedBuffer, taggingOption);
+    }
+
+    protected void taggedDecode(LimitedByteBuffer content,
+                                TaggingOption taggingOption) throws IOException {
+        int taggingTag = readTag(content);
+        int taggingTagNo = readTagNo(content, taggingTag);
+        int taggingLength = readLength(content);
+        LimitedByteBuffer newContent = new LimitedByteBuffer(content, taggingLength);
+
+        int tmpTagFlags = taggingTag & 0xe0;
+        taggedDecode(tmpTagFlags, taggingTagNo, newContent, taggingOption);
+    }
+
+    protected void taggedDecode(int taggingTagFlags, int taggingTagNo,
+                                LimitedByteBuffer content,
+                                TaggingOption taggingOption) throws IOException {
+        int expectedTaggingTagFlags = taggingOption.tagFlags(!isPrimitive());
+        if (expectedTaggingTagFlags != taggingTagFlags) {
+            throw new IOException("Unexpected tag flags " + taggingTagFlags
+                    + ", expecting " + expectedTaggingTagFlags);
+        }
+        if (taggingOption.getTagNo() != taggingTagNo) {
+            throw new IOException("Unexpected tagNo " + taggingTagNo + ", "
+                    + "expecting " + taggingOption.getTagNo());
+        }
+
+        if (taggingOption.isImplicit()) {
+            decodeBody(content);
+        } else {
+            decode(content);
+        }
+    }
+
+    public static Asn1Item decodeOne(LimitedByteBuffer content) throws IOException {
+        int tag = readTag(content);
+        int tagNo = readTagNo(content, tag);
+        int length = readLength(content);
+        if (length < 0) {
+            throw new IOException("Unexpected length");
+        }
+        LimitedByteBuffer valueContent = new LimitedByteBuffer(content, length);
+        content.skip(length);
+
+        Asn1Item result = new Asn1Item(tag, tagNo, valueContent);
+        if (result.isSimple()) {
+            result.decodeValueAsSimple();
+        }
+        return result;
+    }
+
+    public static void skipOne(LimitedByteBuffer content) throws IOException {
+        int tag = readTag(content);
+        readTagNo(content, tag);
+        int length = readLength(content);
+        if (length < 0) {
+            throw new IOException("Unexpected length");
+        }
+        content.skip(length);
+    }
+
+    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, int flags, int 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 int readTag(LimitedByteBuffer buffer) throws IOException {
+        int tag = buffer.readByte() & 0xff;
+        if (tag == 0) {
+            throw new IOException("Bad tag 0 found");
+        }
+        return tag;
+    }
+
+    public static int readTagNo(LimitedByteBuffer buffer, int tag) throws IOException {
+        int tagNo = tag & 0x1f;
+
+        if (tagNo == 0x1f) {
+            tagNo = 0;
+
+            int b = buffer.readByte() & 0xff;
+            if ((b & 0x7f) == 0) {
+                throw new IOException("Invalid high tag number found");
+            }
+
+            while (b >= 0 && (b & 0x80) != 0) {
+                tagNo |= b & 0x7f;
+                tagNo <<= 7;
+                b = buffer.readByte();
+            }
+
+            tagNo |= b & 0x7f;
+        }
+
+        return tagNo;
+    }
+
+    public static int readLength(LimitedByteBuffer buffer) throws IOException {
+        int bodyLength = buffer.readByte() & 0xff;
+
+        if (bodyLength > 127) {
+            int length = bodyLength & 0x7f;
+            if (length > 4) {
+                throw new IOException("Bad bodyLength of more than 4 bytes: " + length);
+            }
+
+            bodyLength = 0;
+            int tmp;
+            for (int i = 0; i < length; i++) {
+                tmp = buffer.readByte() & 0xff;
+                bodyLength = (bodyLength << 8) + tmp;
+            }
+
+            if (bodyLength < 0) {
+                throw new IOException("Invalid bodyLength " + bodyLength);
+            }
+            if (bodyLength > buffer.hasLeft()) {
+                throw new IOException("Corrupt stream - less data "
+                        + buffer.hasLeft() + " than expected " + bodyLength);
+            }
+        }
+
+        return bodyLength;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
index 23e6130..afc11c2 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/CheckSumUtil.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.common;
 
-import org.apache.kerby.asn1.type.AbstractAsn1Type;
+import org.apache.kerby.asn1.type.Asn1Object;
 import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.crypto.CheckSumHandler;
 import org.apache.kerby.kerberos.kerb.crypto.EncTypeHandler;
@@ -50,14 +50,14 @@ public class CheckSumUtil {
         return CheckSumHandler.checksumWithKey(checkSumType, input, key.getKeyData(), usage);
     }
 
-    public static CheckSum seal(AbstractAsn1Type<?> asn1Object,
+    public static CheckSum seal(Asn1Object asn1Object,
                                 CheckSumType checkSumType) throws KrbException {
         byte[] encoded = asn1Object.encode();
         CheckSum checksum = makeCheckSum(checkSumType, encoded);
         return checksum;
     }
 
-    public static CheckSum seal(AbstractAsn1Type<?> asn1Object, CheckSumType checkSumType,
+    public static CheckSum seal(Asn1Object asn1Object, CheckSumType checkSumType,
                                      EncryptionKey key, KeyUsage usage) throws KrbException {
         byte[] encoded = asn1Object.encode();
         CheckSum checksum = makeCheckSumWithKey(checkSumType, encoded, key, usage);

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
index 332c96f..0c246aa 100644
--- a/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
+++ b/kerby-kerb/kerb-common/src/main/java/org/apache/kerby/kerberos/kerb/common/EncryptionUtil.java
@@ -19,7 +19,7 @@
  */
 package org.apache.kerby.kerberos.kerb.common;
 
-import org.apache.kerby.asn1.type.AbstractAsn1Type;
+import org.apache.kerby.asn1.type.Asn1Object;
 import org.apache.kerby.asn1.type.Asn1Type;
 import org.apache.kerby.kerberos.kerb.KrbCodec;
 import org.apache.kerby.kerberos.kerb.KrbException;
@@ -124,7 +124,7 @@ public class EncryptionUtil {
         return null;
     }
 
-    public static EncryptedData seal(AbstractAsn1Type<?> asn1Type,
+    public static EncryptedData seal(Asn1Object asn1Type,
                                      EncryptionKey key, KeyUsage usage) throws KrbException {
         byte[] encoded = asn1Type.encode();
         EncryptedData encrypted = EncryptionHandler.encrypt(encoded, key, usage);

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9601a5a8/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/KrbCodec.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/KrbCodec.java b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/KrbCodec.java
index 4827961..5ef027e 100644
--- a/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/KrbCodec.java
+++ b/kerby-kerb/kerb-core/src/main/java/org/apache/kerby/kerberos/kerb/KrbCodec.java
@@ -20,7 +20,7 @@
 package org.apache.kerby.kerberos.kerb;
 
 import org.apache.kerby.asn1.LimitedByteBuffer;
-import org.apache.kerby.asn1.type.AbstractAsn1Type;
+import org.apache.kerby.asn1.type.Asn1Object;
 import org.apache.kerby.asn1.type.Asn1Type;
 import org.apache.kerby.kerberos.kerb.spec.ap.ApReq;
 import org.apache.kerby.kerberos.kerb.spec.base.KrbError;
@@ -65,10 +65,10 @@ public class KrbCodec {
 
     public static KrbMessage decodeMessage(ByteBuffer byteBuffer) throws IOException {
         LimitedByteBuffer limitedBuffer = new LimitedByteBuffer(byteBuffer);
-        int tag = AbstractAsn1Type.readTag(limitedBuffer);
-        int tagNo = AbstractAsn1Type.readTagNo(limitedBuffer, tag);
+        int tag = Asn1Object.readTag(limitedBuffer);
+        int tagNo = Asn1Object.readTagNo(limitedBuffer, tag);
         int tagFlags = tag & 0xe0;
-        int length = AbstractAsn1Type.readLength(limitedBuffer);
+        int length = Asn1Object.readLength(limitedBuffer);
         LimitedByteBuffer valueBuffer = new LimitedByteBuffer(limitedBuffer, length);
 
         KrbMessage msg;