DIRKRB-490. Separate ASN1 parser
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1.java
index 17279b8..8ca411d 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1.java
@@ -19,9 +19,9 @@
*/
package org.apache.kerby.asn1;
-import org.apache.kerby.asn1.type.Asn1ParsingContainer;
+import org.apache.kerby.asn1.parse.Asn1Parser;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import org.apache.kerby.asn1.type.Asn1Type;
-import org.apache.kerby.asn1.util.Asn1Reader1;
import org.apache.kerby.asn1.util.HexUtil;
import java.io.IOException;
@@ -45,17 +45,21 @@
return value.encode();
}
- public static Asn1Header decodeHeader(ByteBuffer content) throws IOException {
- Asn1Reader1 reader = new Asn1Reader1(content);
- return reader.readHeader();
- }
-
public static Asn1Type decode(byte[] content) throws IOException {
return decode(ByteBuffer.wrap(content));
}
public static Asn1Type decode(ByteBuffer content) throws IOException {
- return Asn1ParsingContainer.decodeOne(content);
+ Asn1ParsingResult parsingResult = Asn1Parser.parse(content);
+ return DecodingUtil.decodeValue(parsingResult);
+ }
+
+ public static Asn1ParsingResult parse(byte[] content) throws IOException {
+ return parse(ByteBuffer.wrap(content));
+ }
+
+ public static Asn1ParsingResult parse(ByteBuffer content) throws IOException {
+ return Asn1Parser.parse(content);
}
public static void dump(Asn1Type value) {
@@ -72,36 +76,27 @@
System.out.println(output);
}
- public static void dump(String hexStr) throws IOException {
- System.out.println("Dumping data:");
- System.out.println(hexStr);
- Asn1Dumper dumper = new Asn1Dumper();
+ public static void dump(String hexStr,
+ boolean useRawFormat) throws IOException {
byte[] data = HexUtil.hex2bytes(hexStr);
- dumper.dump(data);
- String output = dumper.output();
- System.out.println(output);
+ dump(data, useRawFormat);
}
- public static void dump(byte[] content) throws IOException {
- String hexStr = HexUtil.bytesToHex(content);
- System.out.println("Dumping data:");
- int range = 100;
- int pos = range;
- while (pos < hexStr.length()) {
- System.out.println(hexStr.substring(pos - range, pos));
- pos = pos + range;
- }
- System.out.println(hexStr.substring(pos - range, hexStr.length()));
-
- Asn1Dumper dumper = new Asn1Dumper();
- dumper.dump(content);
- String output = dumper.output();
- System.out.println(output);
- }
-
- public static void dump(ByteBuffer content) throws IOException {
+ public static void dump(ByteBuffer content,
+ boolean useRawFormat) throws IOException {
byte[] bytes = new byte[content.remaining()];
content.get(bytes);
- dump(bytes);
+ dump(bytes, useRawFormat);
+ }
+
+ public static void dump(byte[] content,
+ boolean useRawFormat) throws IOException {
+ String hexStr = HexUtil.bytesToHex(content);
+ Asn1Dumper dumper = new Asn1Dumper();
+ System.out.println("Dumping data:");
+ dumper.dumpData(hexStr);
+ dumper.dump(content, useRawFormat);
+ String output = dumper.output();
+ System.out.println(output);
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Dumper.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Dumper.java
index d8354b0..f06eb5c 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Dumper.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Dumper.java
@@ -19,10 +19,13 @@
*/
package org.apache.kerby.asn1;
+import org.apache.kerby.asn1.parse.Asn1Parser;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
+import org.apache.kerby.asn1.parse.Asn1Item;
import org.apache.kerby.asn1.type.Asn1Any;
-import org.apache.kerby.asn1.type.Asn1ParsingItem;
import org.apache.kerby.asn1.type.Asn1Simple;
import org.apache.kerby.asn1.type.Asn1Type;
+import org.apache.kerby.asn1.util.HexUtil;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -47,17 +50,28 @@
return builder.toString();
}
- public void dump(byte[] content) throws IOException {
- dump(ByteBuffer.wrap(content));
+ public void dumpWithHex(byte[] content,
+ boolean useRawFormat) throws IOException {
+ String hexStr = HexUtil.bytesToHex(content);
+ append("Dumping data:").newLine();
+ dumpData(hexStr);
+ dump(content, useRawFormat);
}
- public void dump(ByteBuffer content) throws IOException {
- Asn1Type value = Asn1.decode(content);
- if (value == null) {
- return;
- }
+ public void dump(byte[] content,
+ boolean useRawFormat) throws IOException {
+ dump(ByteBuffer.wrap(content), useRawFormat);
+ }
- dumpType(0, value);
+ public void dump(ByteBuffer content,
+ boolean useRawFormat) throws IOException {
+ if (useRawFormat) {
+ Asn1ParsingResult parsingResult = Asn1Parser.parse(content);
+ dumpParseResult(0, parsingResult);
+ } else {
+ Asn1Type value = Asn1.decode(content);
+ dumpType(0, value);
+ }
}
public void dumpType(Asn1Type value) {
@@ -69,7 +83,7 @@
indent(indents).append("Null");
} else if (value instanceof Asn1Simple) {
indent(indents).append(value.toString());
- } else if (value instanceof Asn1ParsingItem) {
+ } else if (value instanceof Asn1Item) {
indent(indents).append(value.toString());
} else if (value instanceof Asn1Dumpable) {
Asn1Dumpable dumpable = (Asn1Dumpable) value;
@@ -83,6 +97,21 @@
return this;
}
+ public Asn1Dumper dumpParseResult(int indents, Asn1ParsingResult value) {
+ if (value == null) {
+ indent(indents).append("Null");
+ } else if (value instanceof Asn1Item) {
+ indent(indents).append(value.toString());
+ } else if (value instanceof Asn1Dumpable) {
+ Asn1Dumpable dumpable = (Asn1Dumpable) value;
+ dumpable.dumpWith(this, indents);
+ } else {
+ indent(indents).append("<Unknown>");
+ }
+
+ return this;
+ }
+
public Asn1Dumper indent(int numSpaces) {
for (int i = 0; i < numSpaces; i++) {
builder.append(' ');
@@ -125,4 +154,17 @@
builder.append("\n");
return this;
}
+
+ public Asn1Dumper dumpData(String hexData) {
+ int range = 100;
+ int pos = range;
+
+ while (pos < hexData.length()) {
+ System.out.println(hexData.substring(pos - range, pos));
+ pos = pos + range;
+ }
+ System.out.println(hexData.substring(pos - range, hexData.length()));
+
+ return this;
+ }
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/DecodingUtil.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/DecodingUtil.java
new file mode 100644
index 0000000..ef39540
--- /dev/null
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/DecodingUtil.java
@@ -0,0 +1,88 @@
+/**
+ * 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.parse.Asn1ParsingResult;
+import org.apache.kerby.asn1.type.Asn1Collection;
+import org.apache.kerby.asn1.type.Asn1Constructed;
+import org.apache.kerby.asn1.type.Asn1Object;
+import org.apache.kerby.asn1.type.Asn1Simple;
+import org.apache.kerby.asn1.type.Asn1Type;
+
+import java.io.IOException;
+
+public class DecodingUtil {
+
+ public static Asn1Type decodeValue(Asn1ParsingResult parsingResult) throws IOException {
+ if (Asn1Simple.isSimple(parsingResult.tag())) {
+ return DecodingUtil.decodeValueAsSimple(parsingResult);
+ } else if (Asn1Collection.isCollection(parsingResult.tag())) {
+ return DecodingUtil.decodeValueAsCollection(parsingResult);
+ } else if (!parsingResult.tag().isPrimitive()) {
+ Asn1Object tmpValue = new Asn1Constructed(parsingResult.tag());
+ tmpValue.decode(parsingResult);
+ return tmpValue;
+ } else {
+ throw new IOException("Unknow type of tag=" + parsingResult.tag());
+ }
+ }
+
+ public static Asn1Type decodeValueAsSimple(Asn1ParsingResult parsingResult) throws IOException {
+ Asn1Object value = (Asn1Object) Asn1Simple.createSimple(parsingResult.tagNo());
+ value.useDefinitiveLength(parsingResult.isDefinitiveLength());
+ decodeValueWith(parsingResult, value);
+ return value;
+ }
+
+ public static Asn1Type decodeValueAsCollection(Asn1ParsingResult parsingResult) throws IOException {
+ Asn1Collection value = Asn1Collection.createCollection(parsingResult.tag());
+ value.useDefinitiveLength(parsingResult.isDefinitiveLength());
+ value.setLazy(true);
+ decodeValueWith(parsingResult, value);
+ return value;
+ }
+
+ public static Asn1Type decodeValueAs(Asn1ParsingResult parsingResult,
+ Class<? extends Asn1Type> type) throws IOException {
+ Asn1Type value;
+ try {
+ value = type.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("Invalid type: "
+ + type.getCanonicalName(), e);
+ }
+ decodeValueWith(parsingResult, value);
+ return value;
+ }
+
+ public static void decodeValueWith(Asn1ParsingResult parsingResult, Asn1Type value) throws IOException {
+ value.useDefinitiveLength(parsingResult.isDefinitiveLength());
+ ((Asn1Object) value).decode(parsingResult);
+ }
+
+ public static void decodeValueWith(Asn1ParsingResult parsingResult,
+ Asn1Type value, TaggingOption taggingOption) throws IOException {
+ if (!parsingResult.isTagSpecific()) {
+ throw new IllegalArgumentException(
+ "Attempting to decode non-tagged value using tagging way");
+ }
+ ((Asn1Object) value).taggedDecode(parsingResult, taggingOption);
+ }
+}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Container.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Container.java
new file mode 100644
index 0000000..1e796ec
--- /dev/null
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Container.java
@@ -0,0 +1,81 @@
+/**
+ * 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.parse;
+
+import org.apache.kerby.asn1.Asn1Dumpable;
+import org.apache.kerby.asn1.Asn1Dumper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ASN1 constructed types, mainly structured ones, but also some primitive ones.
+ */
+public class Asn1Container
+ extends Asn1ParsingResult implements Asn1Dumpable {
+
+ private List<Asn1ParsingResult> children = new ArrayList<>();
+
+ public Asn1Container(Asn1Header header) {
+ super(header);
+ }
+
+ public Asn1Container(Asn1ParsingResult parsingResult) {
+ super(parsingResult.header);
+ }
+
+ public List<Asn1ParsingResult> getChildren() {
+ return children;
+ }
+
+ public void addItem(Asn1ParsingResult value) {
+ children.add(value);
+ }
+
+ public void clear() {
+ children.clear();
+ }
+
+ @Override
+ public void dumpWith(Asn1Dumper dumper, int indents) {
+ dumper.indent(indents).append(toString()).newLine();
+
+ for (Asn1ParsingResult aObj : children) {
+ dumper.dumpParseResult(indents + 4, aObj).newLine();
+ }
+ }
+
+ @Override
+ public String toString() {
+ String typeStr;
+ if (tag().isUniversal()) {
+ typeStr = tag().universalTag().toStr();
+ } else if (tag().isAppSpecific()) {
+ typeStr = "application " + tagNo();
+ } else {
+ typeStr = "[" + tagNo() + "]";
+ }
+ return typeStr + " ["
+ + "off=" + getOffset()
+ + ", len=" + getHeaderLength() + "+" + getBodyLength()
+ + (isDefinitiveLength() ? "" : "(undefined)")
+ + "]";
+ }
+}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Header.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Header.java
similarity index 90%
rename from kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Header.java
rename to kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Header.java
index 1284039..bf3177b 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/Asn1Header.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Header.java
@@ -17,7 +17,9 @@
* under the License.
*
*/
-package org.apache.kerby.asn1;
+package org.apache.kerby.asn1.parse;
+
+import org.apache.kerby.asn1.Tag;
import java.nio.ByteBuffer;
@@ -91,10 +93,7 @@
return length != -1;
}
- public byte[] readBodyBytes() {
- ByteBuffer bodyBuffer = getBodyBuffer();
- byte[] result = new byte[bodyBuffer.remaining()];
- bodyBuffer.get(result);
- return result;
+ public boolean checkBodyFinished(int pos) {
+ return getBodyEnd() != -1 && pos >= getBodyEnd();
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingItem.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Item.java
similarity index 66%
rename from kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingItem.java
rename to kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Item.java
index e7cffa3..b1f0ef9 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingItem.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Item.java
@@ -17,21 +17,11 @@
* under the License.
*
*/
-package org.apache.kerby.asn1.type;
+package org.apache.kerby.asn1.parse;
-import org.apache.kerby.asn1.Asn1Header;
+public class Asn1Item extends Asn1ParsingResult {
-/**
- * Asn1Item serves two purposes:
- * 1. Wrapping an existing Asn1Type value for Asn1Collection;
- * 2. Wrapping a half decoded value whose body content is left to be decoded
- * later when appropriate.
- * Why not fully decoded at once? Lazy and decode on demand for collection, or
- * impossible due to lacking key parameters.
- */
-public class Asn1ParsingItem extends Asn1ParsingResult {
-
- public Asn1ParsingItem(Asn1Header header) {
+ public Asn1Item(Asn1Header header) {
super(header);
}
@@ -42,7 +32,7 @@
: tag().tagClass().name().toLowerCase();
return typeStr + " ["
+ "off=" + getOffset()
- + ", len=" + encodingHeaderLength() + "+" + encodingBodyLength()
+ + ", len=" + getHeaderLength() + "+" + getBodyLength()
+ "] "
+ valueStr;
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Parser.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Parser.java
new file mode 100644
index 0000000..9c79768
--- /dev/null
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Parser.java
@@ -0,0 +1,88 @@
+/**
+ * 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.parse;
+
+import org.apache.kerby.asn1.Tag;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * ASN1 parser.
+ */
+public class Asn1Parser {
+
+ public static void parse(Asn1Container container) throws IOException {
+ parse(container.header, container);
+ }
+
+ public static void parse(Asn1Header header,
+ Asn1Container parent) throws IOException {
+ Asn1Reader reader = new Asn1Reader(header.getBuffer());
+ int pos = header.getBodyStart();
+ while (true) {
+ reader.setPosition(pos);
+ Asn1ParsingResult asn1Obj = parse(reader);
+ if (asn1Obj == null) {
+ break;
+ }
+
+ if (parent != null) {
+ parent.addItem(asn1Obj);
+ }
+
+ pos += asn1Obj.getAllLength();
+ if (asn1Obj.isEOC()) {
+ break;
+ }
+
+ if (header.checkBodyFinished(pos)) {
+ break;
+ }
+ }
+
+ header.setBodyEnd(pos);
+ }
+
+ public static Asn1ParsingResult parse(ByteBuffer content) throws IOException {
+ Asn1Reader reader = new Asn1Reader(content);
+ return parse(reader);
+ }
+
+ public static Asn1ParsingResult parse(Asn1Reader reader) throws IOException {
+ if (!reader.available()) {
+ return null;
+ }
+
+ Asn1Header header = reader.readHeader();
+ Tag tmpTag = header.getTag();
+ Asn1ParsingResult parsingResult;
+
+ if (tmpTag.isPrimitive()) {
+ parsingResult = new Asn1Item(header);
+ } else {
+ Asn1Container container = new Asn1Container(header);
+ parse(container);
+ parsingResult = container;
+ }
+
+ return parsingResult;
+ }
+}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1ParsingResult.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1ParsingResult.java
new file mode 100644
index 0000000..7be817f
--- /dev/null
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1ParsingResult.java
@@ -0,0 +1,100 @@
+/**
+ * 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.parse;
+
+import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.util.Asn1Util;
+
+import java.nio.ByteBuffer;
+
+public abstract class Asn1ParsingResult {
+ protected Asn1Header header;
+
+ public Asn1ParsingResult(Asn1Header header) {
+ this.header = header;
+ }
+
+ public Tag tag() {
+ return header.getTag();
+ }
+
+ public int tagNo() {
+ return tag().tagNo();
+ }
+
+ public boolean isPrimitive() {
+ return tag().isPrimitive();
+ }
+
+ public boolean isUniversal() {
+ return tag().isUniversal();
+ }
+
+ public boolean isAppSpecific() {
+ return tag().isAppSpecific();
+ }
+
+ public boolean isContextSpecific() {
+ return tag().isContextSpecific();
+ }
+
+ public boolean isTagSpecific() {
+ return tag().isSpecific();
+ }
+
+ public boolean isEOC() {
+ return header.isEOC();
+ }
+
+ public Asn1Header getHeader() {
+ return header;
+ }
+
+ public boolean isDefinitiveLength() {
+ return header.isDefinitiveLength();
+ }
+
+ public int getAllLength() {
+ return getHeaderLength() + getBodyLength();
+ }
+
+ public int getHeaderLength() {
+ int bodyLen = getBodyLength();
+ int headerLen = Asn1Util.lengthOfTagLength(header.getTag().tagNo());
+ headerLen += (header.isDefinitiveLength()
+ ? Asn1Util.lengthOfBodyLength(bodyLen) : 1);
+ return headerLen;
+ }
+
+ public int getBodyLength() {
+ return header.getActualBodyLength();
+ }
+
+ protected int getOffset() {
+ return header.getBodyStart() - getHeaderLength();
+ }
+
+ public byte[] readBodyBytes() {
+ ByteBuffer bodyBuffer = header.getBodyBuffer();
+ byte[] result = new byte[bodyBuffer.remaining()];
+ bodyBuffer.get(result);
+ return result;
+ }
+}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Reader.java
similarity index 82%
rename from kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader.java
rename to kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Reader.java
index 2590a48..555d7a8 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/parse/Asn1Reader.java
@@ -6,34 +6,30 @@
* 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;
+package org.apache.kerby.asn1.parse;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.Tag;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
- * ASN1 reader from a byte buffer.
+ * ASN1 reader for positional reading.
*/
-public abstract class Asn1Reader {
- protected ByteBuffer buffer;
-
- public Asn1Reader(ByteBuffer buffer) {
- this.buffer = buffer;
- }
+public final class Asn1Reader {
+ private ByteBuffer buffer;
+ private int position;
public ByteBuffer getBuffer() {
return buffer;
@@ -48,15 +44,30 @@
return header;
}
- public abstract void setPosition(int position);
+ public Asn1Reader(ByteBuffer buffer) {
+ this.buffer = buffer;
+ this.position = buffer.position();
+ }
- public abstract int getPosition();
+ public int getPosition() {
+ return position;
+ }
- public abstract boolean available();
+ public void setPosition(int position) {
+ this.position = position;
+ }
- public abstract ByteBuffer getValueBuffer(int valueLength);
+ public boolean available() {
+ return position < buffer.limit();
+ }
- protected abstract byte readByte() throws IOException;
+ public ByteBuffer getValueBuffer(int valueLength) {
+ return buffer;
+ }
+
+ protected byte readByte() throws IOException {
+ return buffer.get(position++);
+ }
private Tag readTag() throws IOException {
int tagFlags = readTagFlags();
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Any.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Any.java
index 7ad58f9..f63481f 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Any.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Any.java
@@ -20,8 +20,9 @@
package org.apache.kerby.asn1.type;
import org.apache.kerby.asn1.Asn1FieldInfo;
-import org.apache.kerby.asn1.Asn1Header;
+import org.apache.kerby.asn1.DecodingUtil;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -31,7 +32,7 @@
*/
public class Asn1Any extends AbstractAsn1Type<Asn1Type> {
private Asn1FieldInfo fieldInfo;
- private Asn1Item field;
+ private Asn1ParsingResult field;
public Asn1Any() {
super(UniversalTag.ANY);
@@ -42,7 +43,7 @@
setValue(anyValue);
}
- public void setField(Asn1Item field) {
+ public void setField(Asn1ParsingResult field) {
this.field = field;
}
@@ -50,7 +51,7 @@
this.fieldInfo = fieldInfo;
}
- public Asn1Type getField() {
+ public Asn1ParsingResult getField() {
return field;
}
@@ -60,8 +61,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- ((Asn1Object) getValue()).decodeBody(header);
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ ((Asn1Object) getValue()).decodeBody(parsingResult);
}
@Override
@@ -84,10 +85,10 @@
try {
if (field.isContextSpecific()) {
- field.decodeValueWith(result,
+ DecodingUtil.decodeValueWith(field, result,
fieldInfo.getTaggingOption());
} else {
- field.decodeValueWith(result);
+ DecodingUtil.decodeValueWith(field, result);
}
} catch (IOException e) {
throw new RuntimeException("Fully decoding failed", e);
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1BmpString.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1BmpString.java
index 7c3d920..929b989 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1BmpString.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1BmpString.java
@@ -19,8 +19,8 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
@@ -61,10 +61,10 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- if (header.getLength() % 2 != 0) {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ if (parsingResult.getBodyLength() % 2 != 0) {
throw new IOException("Bad stream, BMP string expecting multiple of 2 bytes");
}
- super.decodeBody(header);
+ super.decodeBody(parsingResult);
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Boolean.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Boolean.java
index 61b8ef2..af2cc4e 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Boolean.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Boolean.java
@@ -19,8 +19,8 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
@@ -55,11 +55,11 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- if (header.getLength() != 1) {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ if (parsingResult.getBodyLength() != 1) {
throw new IOException("More than 1 byte found for Boolean");
}
- super.decodeBody(header);
+ super.decodeBody(parsingResult);
}
@Override
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Choice.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Choice.java
index dd6d873..260c426 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Choice.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Choice.java
@@ -19,12 +19,11 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1;
import org.apache.kerby.asn1.Asn1FieldInfo;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.EnumType;
import org.apache.kerby.asn1.TaggingOption;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -75,6 +74,7 @@
@Override
public void decode(ByteBuffer content) throws IOException {
+ /*
int foundPos = -1;
Asn1Item item = (Asn1Item) Asn1.decode(content);
for (int i = 0; i < fieldInfos.length; ++i) {
@@ -107,24 +107,22 @@
}
}
fields[foundPos] = item.getValue();
+ */
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
}
- protected void decodeBody(ByteBuffer content) throws IOException {
- // Not used
- }
-
+ /*
private void initField(int idx) {
try {
fields[idx] = fieldInfos[idx].getType().newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Bad field info specified at index of " + idx, e);
}
- }
+ }*/
protected <T extends Asn1Type> T getFieldAs(EnumType index, Class<T> t) {
Asn1Type value = fields[index.getValue()];
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Collection.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Collection.java
index 9cbf89a..982c29e 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Collection.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Collection.java
@@ -23,7 +23,7 @@
import org.apache.kerby.asn1.UniversalTag;
/**
- * ASN1 complex type, may be better named.
+ * ASN1 complex type of multiple ASN1 objects.
*/
public class Asn1Collection extends Asn1Constructed {
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionOf.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionOf.java
index 5e4bd70..08eb317 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionOf.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionOf.java
@@ -20,47 +20,36 @@
package org.apache.kerby.asn1.type;
import org.apache.kerby.asn1.Asn1Dumper;
-import org.apache.kerby.asn1.Asn1Header;
+import org.apache.kerby.asn1.DecodingUtil;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
import java.util.List;
public abstract class Asn1CollectionOf<T extends Asn1Type>
extends Asn1Collection {
- private List<T> elements = new ArrayList<>();
-
public Asn1CollectionOf(UniversalTag universalTag) {
super(universalTag);
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- super.decodeBody(header);
-
- decodeElements();
- }
-
- private void decodeElements() throws IOException {
- List<Asn1Type> items = getValue();
- for (Asn1Type itemObj : items) {
- if (itemObj instanceof Asn1Item) {
- Asn1Item item = (Asn1Item) itemObj;
- if (!item.isFullyDecoded()) {
- Asn1Type tmpValue = createElement();
- item.decodeValueWith(tmpValue);
- }
- itemObj = item.getValue();
+ protected void decodeElements() throws IOException {
+ for (Asn1ParsingResult parsingItem : getContainer().getChildren()) {
+ if (parsingItem.isEOC()) {
+ continue;
}
- elements.add((T) itemObj);
+
+ Asn1Type tmpValue = createElement();
+ DecodingUtil.decodeValueWith(parsingItem, tmpValue);
+ addItem(tmpValue);
}
}
public List<T> getElements() {
- return elements;
+ return (List<T>) getValue();
}
public void setElements(List<T> elements) {
@@ -79,7 +68,6 @@
public void addElement(T element) {
super.addItem(element);
- this.elements.add(element);
}
private Class<T> getElementType() {
@@ -102,7 +90,7 @@
public void dumpWith(Asn1Dumper dumper, int indents) {
dumper.dumpTypeInfo(indents, getClass());
- for (Asn1Type aObj : elements) {
+ for (Asn1Type aObj : getValue()) {
dumper.dumpType(indents + 4, aObj).newLine();
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
index 81c00fc..2039b08 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1CollectionType.java
@@ -22,10 +22,12 @@
import org.apache.kerby.asn1.Asn1Dumpable;
import org.apache.kerby.asn1.Asn1Dumper;
import org.apache.kerby.asn1.Asn1FieldInfo;
-import org.apache.kerby.asn1.Asn1Header;
+import org.apache.kerby.asn1.DecodingUtil;
import org.apache.kerby.asn1.EnumType;
import org.apache.kerby.asn1.TaggingOption;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1Container;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -82,45 +84,47 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
checkAndInitFields();
- Asn1Collection coll = createCollection();
- coll.setLazy(true);
- coll.decodeBody(header);
+ Asn1Container container = (Asn1Container) parsingResult;
+ List<Asn1ParsingResult> parsingResults = container.getChildren();
int lastPos = -1, foundPos = -1;
- List<Asn1Type> decodedItems = coll.getValue();
- for (Asn1Type itemObj : decodedItems) {
+
+ for (Asn1ParsingResult parsingItem : parsingResults) {
+ if (parsingItem.isEOC()) {
+ continue;
+ }
+
foundPos = -1;
- Asn1Item item = (Asn1Item) itemObj;
for (int i = lastPos + 1; i < fieldInfos.length; ++i) {
- if (item.isContextSpecific()) {
- if (fieldInfos[i].getTagNo() == item.tagNo()) {
+ if (parsingItem.isContextSpecific()) {
+ if (fieldInfos[i].getTagNo() == parsingItem.tagNo()) {
foundPos = i;
break;
}
- } else if (fields[i].tag().equals(item.tag())) {
+ } else if (fields[i].tag().equals(parsingItem.tag())) {
foundPos = i;
break;
}
}
if (foundPos == -1) {
- throw new IOException("Unexpected item with tag: " + item.tag());
+ throw new IOException("Unexpected item with tag: " + parsingItem.tag());
}
lastPos = foundPos;
AbstractAsn1Type<?> fieldValue = (AbstractAsn1Type<?>) fields[foundPos];
if (fieldValue instanceof Asn1Any) {
Asn1Any any = (Asn1Any) fieldValue;
- any.setField(item);
+ any.setField(parsingItem);
any.setFieldInfo(fieldInfos[foundPos]);
} else {
- if (item.isContextSpecific()) {
- item.decodeValueWith(fieldValue,
+ if (parsingItem.isContextSpecific()) {
+ DecodingUtil.decodeValueWith(parsingItem, fieldValue,
fieldInfos[foundPos].getTaggingOption());
} else {
- item.decodeValueWith(fieldValue);
+ DecodingUtil.decodeValueWith(parsingItem, fieldValue);
}
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Constructed.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Constructed.java
index dcb51fc..605b445 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Constructed.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Constructed.java
@@ -21,8 +21,10 @@
import org.apache.kerby.asn1.Asn1Dumpable;
import org.apache.kerby.asn1.Asn1Dumper;
-import org.apache.kerby.asn1.Asn1Header;
+import org.apache.kerby.asn1.DecodingUtil;
import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1Container;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -35,6 +37,8 @@
public class Asn1Constructed
extends AbstractAsn1Type<List<Asn1Type>> implements Asn1Dumpable {
+ protected Asn1Container container;
+
private boolean lazy = false;
public Asn1Constructed(Tag tag) {
@@ -43,6 +47,11 @@
usePrimitive(false);
}
+
+ public Asn1Container getContainer() {
+ return container;
+ }
+
public void setLazy(boolean lazy) {
this.lazy = lazy;
}
@@ -82,20 +91,23 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- Asn1ParsingContainer container = new Asn1ParsingContainer(tag());
- container.decode(header);
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ Asn1Container container = (Asn1Container) parsingResult;
+ this.container = container;
- for (Asn1ParsingResult result : container.getParsingResults()) {
- if (!result.isEOC()) {
- Asn1Item item = new Asn1Item(result);
- if (item.isSimple() && !isLazy()) {
- item.decodeValueAsSimple();
- addItem(item.getValue());
- } else {
- addItem(item);
- }
+ if (!isLazy()) {
+ decodeElements();
+ }
+ }
+
+ protected void decodeElements() throws IOException {
+ for (Asn1ParsingResult parsingItem : getContainer().getChildren()) {
+ if (parsingItem.isEOC()) {
+ continue;
}
+
+ Asn1Type tmpValue = DecodingUtil.decodeValue(parsingItem);
+ addItem(tmpValue);
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Eoc.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Eoc.java
index f8610ea..ec8c280 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Eoc.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Eoc.java
@@ -19,8 +19,8 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
@@ -46,8 +46,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- if (header.getLength() != 0) {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ if (parsingResult.getBodyLength() != 0) {
throw new IOException("Unexpected bytes found for EOC");
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Item.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Item.java
deleted file mode 100644
index b3994ff..0000000
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Item.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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.Asn1Factory;
-import org.apache.kerby.asn1.Asn1Header;
-import org.apache.kerby.asn1.Tag;
-import org.apache.kerby.asn1.TaggingOption;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * Asn1Item serves two purposes:
- * 1. Wrapping an existing Asn1Type value for Asn1Collection;
- * 2. Wrapping a half decoded value whose body content is left to be decoded
- * later when appropriate.
- * Why not fully decoded at once? Lazy and decode on demand for collection, or
- * impossible due to lacking key parameters, like implicit encoded value for
- * tagged value.
- *
- * For not fully decoded value, you tell your case using isSimple/isCollection/
- * isSpecific/isContextSpecific etc., then call decodeValueAsSimple/
- * decodeValueAsCollection/decodeValueAsImplicitTagged/decodeValueAsExplicitTagged etc.
- * to decode it fully. Or if you have already derived the value holder or
- * the holder type, you can use decodeValueWith or decodeValueAs with your
- * holder or hodler type.
- */
-public class Asn1Item extends AbstractAsn1Type<Asn1Type> {
- private final Asn1ParsingResult parsingResult;
-
- public Asn1Item(Asn1ParsingResult parsingResult) {
- super(parsingResult.tag());
- this.parsingResult = parsingResult;
- }
-
- public Asn1Item(Tag tag, Asn1ParsingResult parsingResult) {
- super(tag);
- this.parsingResult = parsingResult;
- }
-
- public Asn1ParsingResult getParsingResult() {
- return parsingResult;
- }
-
- @Override
- protected int encodingBodyLength() {
- if (getValue() != null) {
- return ((AbstractAsn1Type<?>) getValue()).encodingBodyLength();
- }
- return parsingResult.encodingBodyLength();
- }
-
- @Override
- protected void encodeBody(ByteBuffer buffer) {
- if (getValue() != null) {
- ((Asn1Object) getValue()).encodeBody(buffer);
- }
- }
-
- @Override
- protected void decodeBody(Asn1Header header) throws IOException {
- this.parsingResult.decodeBody(header);
- }
-
- public boolean isFullyDecoded() {
- return getValue() != null;
- }
-
- public void decodeValueAsSimple() throws IOException {
- if (getValue() != null) {
- return;
- }
- if (!isSimple()) {
- throw new IllegalArgumentException(
- "Attempting to decode non-simple value as simple");
- }
-
- Asn1Object value = (Asn1Object) Asn1Factory.create(tagNo());
- value.useDefinitiveLength(isDefinitiveLength());
- decodeValueWith(value);
- }
-
- public void decodeValueAsCollection() throws IOException {
- if (getValue() != null) {
- return;
- }
- if (!isCollection()) {
- throw new IllegalArgumentException(
- "Attempting to decode non-collection value as collection");
- }
-
- Asn1Type value = Asn1Factory.create(tagNo());
- value.useDefinitiveLength(isDefinitiveLength());
- decodeValueWith(value);
- }
-
- public void decodeValueAs(Class<? extends Asn1Type> type) throws IOException {
- Asn1Type value;
- try {
- value = type.newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Invalid type: "
- + type.getCanonicalName(), e);
- }
- decodeValueWith(value);
- }
-
- public void decodeValueWith(Asn1Type value) throws IOException {
- setValue(value);
- value.useDefinitiveLength(isDefinitiveLength());
- ((Asn1Object) value).decode(parsingResult.getHeader());
- }
-
- public void decodeValueWith(Asn1Type value, TaggingOption taggingOption) throws IOException {
- if (!isTagSpecific()) {
- throw new IllegalArgumentException(
- "Attempting to decode non-tagged value using tagging way");
- }
- ((Asn1Object) value).taggedDecode(parsingResult.getHeader(), taggingOption);
- setValue(value);
- }
-}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Null.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Null.java
index 6affb95..87a80b8 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Null.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Null.java
@@ -19,8 +19,8 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
@@ -46,8 +46,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- if (header.getLength() != 0) {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ if (parsingResult.getHeader().getLength() != 0) {
throw new IOException("Unexpected bytes found for NULL");
}
}
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
index 6b4a20c..5bb9854 100644
--- 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
@@ -19,12 +19,12 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.Tag;
import org.apache.kerby.asn1.TaggingOption;
import org.apache.kerby.asn1.UniversalTag;
-import org.apache.kerby.asn1.util.Asn1Reader;
-import org.apache.kerby.asn1.util.Asn1Reader2;
+import org.apache.kerby.asn1.parse.Asn1Container;
+import org.apache.kerby.asn1.parse.Asn1Parser;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import org.apache.kerby.asn1.util.Asn1Util;
import java.io.IOException;
@@ -199,7 +199,7 @@
return tag.isSpecific();
}
- protected boolean isEOC() {
+ public boolean isEOC() {
return tag().isEOC();
}
@@ -215,23 +215,20 @@
@Override
public void decode(ByteBuffer content) throws IOException {
- Asn1Reader reader = new Asn1Reader2(content);
- Asn1Header header = reader.readHeader();
-
- useDefinitiveLength(header.isDefinitiveLength());
- decode(header);
+ Asn1ParsingResult parsingResult = Asn1Parser.parse(content);
+ decode(parsingResult);
}
- public void decode(Asn1Header header) throws IOException {
- if (!tag().equals(header.getTag())) {
- throw new IOException("Unexpected tag " + header.getTag()
+ public void decode(Asn1ParsingResult parsingResult) throws IOException {
+ if (!tag().equals(parsingResult.tag())) {
+ throw new IOException("Unexpected tag " + parsingResult.tag()
+ ", expecting " + tag());
}
- decodeBody(header);
+ decodeBody(parsingResult);
}
- protected abstract void decodeBody(Asn1Header header) throws IOException;
+ protected abstract void decodeBody(Asn1ParsingResult parsingResult) throws IOException;
protected int taggedEncodingLength(TaggingOption taggingOption) {
int taggingTagNo = taggingOption.getTagNo();
@@ -242,8 +239,10 @@
return taggingEncodingLen;
}
+ @Override
public byte[] taggedEncode(TaggingOption taggingOption) {
- ByteBuffer byteBuffer = ByteBuffer.allocate(taggedEncodingLength(taggingOption));
+ int len = taggedEncodingLength(taggingOption);
+ ByteBuffer byteBuffer = ByteBuffer.allocate(len);
taggedEncode(byteBuffer, taggingOption);
byteBuffer.flip();
return byteBuffer.array();
@@ -263,6 +262,7 @@
}
}
+ @Override
public void taggedDecode(byte[] content,
TaggingOption taggingOption) throws IOException {
taggedDecode(ByteBuffer.wrap(content), taggingOption);
@@ -271,25 +271,24 @@
@Override
public void taggedDecode(ByteBuffer content,
TaggingOption taggingOption) throws IOException {
- Asn1Reader reader = new Asn1Reader2(content);
- Asn1Header header = reader.readHeader();
-
- useDefinitiveLength(header.isDefinitiveLength());
- taggedDecode(header, taggingOption);
+ Asn1ParsingResult parsingResult = Asn1Parser.parse(content);
+ taggedDecode(parsingResult, taggingOption);
}
- protected void taggedDecode(Asn1Header header,
+ public void taggedDecode(Asn1ParsingResult parsingResult,
TaggingOption taggingOption) throws IOException {
Tag expectedTaggingTagFlags = taggingOption.getTag(!isPrimitive());
- if (!expectedTaggingTagFlags.equals(header.getTag())) {
- throw new IOException("Unexpected tag " + header.getTag()
+ if (!expectedTaggingTagFlags.equals(parsingResult.tag())) {
+ throw new IOException("Unexpected tag " + parsingResult.tag()
+ ", expecting " + expectedTaggingTagFlags);
}
if (taggingOption.isImplicit()) {
- decodeBody(header);
+ decodeBody(parsingResult);
} else {
- decode(header.getBodyBuffer());
+ Asn1Container container = (Asn1Container) parsingResult;
+ Asn1ParsingResult body = container.getChildren().get(0);
+ decode(body);
}
}
}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1OctetString.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1OctetString.java
index 88c4f46..3b91459 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1OctetString.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1OctetString.java
@@ -19,8 +19,8 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
@@ -44,8 +44,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- setValue(header.readBodyBytes());
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ setValue(parsingResult.readBodyBytes());
}
@Override
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingContainer.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingContainer.java
deleted file mode 100644
index 3bd5a7f..0000000
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingContainer.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * 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.Asn1Header;
-import org.apache.kerby.asn1.Tag;
-import org.apache.kerby.asn1.util.Asn1Reader;
-import org.apache.kerby.asn1.util.Asn1Reader2;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * ASN1 constructed types, mainly structured ones, but also some primitive ones.
- */
-public class Asn1ParsingContainer
- extends Asn1ParsingResult implements Asn1Dumpable {
-
- private List<Asn1ParsingResult> parsingResults = new ArrayList<>();
-
- public Asn1ParsingContainer(Tag tag) {
- super(tag);
- }
-
- public Asn1ParsingContainer(Asn1Header header) {
- super(header);
- usePrimitive(false);
- }
-
- public List<Asn1ParsingResult> getParsingResults() {
- return parsingResults;
- }
-
- public void addItem(Asn1ParsingResult value) {
- parsingResults.add(value);
- }
-
- public void clear() {
- parsingResults.clear();
- }
-
- @Override
- public void decode(ByteBuffer content) throws IOException {
- Asn1Reader2 reader = new Asn1Reader2(content);
- Asn1Header header = reader.readHeader();
- Tag tmpTag = header.getTag();
- useDefinitiveLength(header.isDefinitiveLength());
-
- if (!tag().equals(tmpTag)) {
- throw new IOException("Unexpected tag " + tmpTag
- + ", expecting " + tag());
- }
-
- decode(header);
- }
-
- @Override
- public void decode(Asn1Header header) throws IOException {
- this.header = header;
-
- Asn1Reader reader = new Asn1Reader2(header.getBuffer());
- int pos = header.getBodyStart();
- while (true) {
- reader.setPosition(pos);
- Asn1ParsingResult asn1Obj = decodeOne(reader);
- if (asn1Obj == null) {
- break;
- }
-
- pos += asn1Obj.encodingLength();
- if (asn1Obj.isEOC()) {
- break;
- }
-
- if (header.getBodyEnd() != -1 && pos >= header.getBodyEnd()) {
- break;
- }
- }
-
- header.setBodyEnd(pos);
- }
-
- private Asn1ParsingResult decodeOne(Asn1Reader reader) throws IOException {
- return decodeOne(reader, this);
- }
-
- public static Asn1ParsingResult decodeOne(ByteBuffer content) throws IOException {
- Asn1Reader reader = new Asn1Reader2(content);
- return Asn1ParsingContainer.decodeOne(reader, null);
- }
-
- public static Asn1ParsingResult decodeOne(Asn1Reader reader,
- Asn1ParsingContainer parent) throws IOException {
- if (!reader.available()) {
- return null;
- }
-
- Asn1Header header = reader.readHeader();
- Tag tmpTag = header.getTag();
- Asn1ParsingResult parsingResult;
-
- if (tmpTag.isPrimitive()) {
- parsingResult = new Asn1ParsingItem(header);
- parsingResult.useDefinitiveLength(header.isDefinitiveLength());
- } else {
- Asn1ParsingContainer container = new Asn1ParsingContainer(tmpTag);
- container.useDefinitiveLength(header.isDefinitiveLength());
- container.decode(header);
- parsingResult = container;
- }
-
- if (parsingResult != null && parent != null) {
- parent.addItem(parsingResult);
- }
-
- return parsingResult;
- }
-
- @Override
- public void dumpWith(Asn1Dumper dumper, int indents) {
- dumper.indent(indents).append(toString()).newLine();
-
- for (Asn1ParsingResult aObj : parsingResults) {
- dumper.dumpType(indents + 4, aObj).newLine();
- }
- }
-
- @Override
- public String toString() {
- String typeStr;
- if (tag().isUniversal()) {
- typeStr = tag().universalTag().toStr();
- } else if (tag().isAppSpecific()) {
- typeStr = "application " + tagNo();
- } else {
- typeStr = "[" + tagNo() + "]";
- }
- return typeStr + " ["
- + "off=" + getOffset()
- + ", len=" + encodingHeaderLength() + "+" + encodingBodyLength()
- + (isDefinitiveLength() ? "" : "(undefined)")
- + "]";
- }
-}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingResult.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingResult.java
deleted file mode 100644
index 004fd02..0000000
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1ParsingResult.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * 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.Asn1Header;
-import org.apache.kerby.asn1.Tag;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-public abstract class Asn1ParsingResult extends AbstractAsn1Type<Asn1Type> {
- protected Asn1Header header;
-
- public Asn1ParsingResult(Tag tag) {
- super(tag);
- setValue(this);
- }
-
- public Asn1ParsingResult(Asn1Header header) {
- super(header.getTag());
- setValue(this);
- this.header = header;
- }
-
- protected ByteBuffer getBodyBuffer() {
- return header.getBodyBuffer();
- }
-
- protected Asn1Header getHeader() {
- return header;
- }
-
- @Override
- protected int encodingBodyLength() {
- return header.getActualBodyLength();
- }
-
- @Override
- protected void encodeBody(ByteBuffer buffer) {
- buffer.put(header.getBodyBuffer());
- }
-
- protected int getOffset() {
- return header.getBodyStart() - encodingHeaderLength();
- }
-
- @Override
- protected void decodeBody(Asn1Header header) throws IOException {
- // NOT USED FOR NOW SINCE WE DON'T DECODE THE BODY.
- }
-
- @Override
- public String toString() {
- String valueStr = "undecoded";
- if (getValue() != null) {
- Asn1Type val = getValue();
- valueStr = (val != null ? val.toString() : "null");
- }
- String typeStr = tag().isUniversal() ? tag().universalTag().toStr()
- : tag().tagClass().name().toLowerCase();
- return typeStr + " ["
- + "off=" + getOffset()
- + ", len=" + encodingHeaderLength() + "+" + encodingBodyLength()
- + "] "
- + valueStr;
- }
-}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
index 6d08f70..1472bc6 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Simple.java
@@ -19,9 +19,9 @@
*/
package org.apache.kerby.asn1.type;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.Tag;
import org.apache.kerby.asn1.UniversalTag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import org.apache.kerby.asn1.util.Asn1Util;
import java.io.IOException;
@@ -93,8 +93,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- byte[] leftBytes = header.readBodyBytes();
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ byte[] leftBytes = parsingResult.readBodyBytes();
if (leftBytes.length > 0) {
setBytes(leftBytes);
toValue();
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
index 8a8ee3b..4a5bddd 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1Tagging.java
@@ -21,8 +21,9 @@
import org.apache.kerby.asn1.Asn1Dumpable;
import org.apache.kerby.asn1.Asn1Dumper;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1Container;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
@@ -81,19 +82,21 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
Asn1Object value = (Asn1Object) getValue();
if (isImplicit()) {
- value.decodeBody(header);
+ value.decodeBody(parsingResult);
} else {
- value.decode(header.getBodyBuffer());
+ Asn1Container container = (Asn1Container) parsingResult;
+ Asn1ParsingResult body = container.getChildren().get(0);
+ value.decode(body);
}
}
private void initValue() {
Class<? extends Asn1Type> valueType = (Class<T>) ((ParameterizedType)
getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- AbstractAsn1Type<?> value = null;
+ AbstractAsn1Type<?> value;
try {
value = (AbstractAsn1Type<?>) valueType.newInstance();
} catch (Exception e) {
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
index 4d3cbe2..27e0898 100644
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
+++ b/kerby-asn1/src/main/java/org/apache/kerby/asn1/type/Asn1TaggingCollection.java
@@ -22,9 +22,9 @@
import org.apache.kerby.asn1.Asn1Dumpable;
import org.apache.kerby.asn1.Asn1Dumper;
import org.apache.kerby.asn1.Asn1FieldInfo;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.EnumType;
import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -141,8 +141,8 @@
}
@Override
- protected void decodeBody(Asn1Header header) throws IOException {
- tagging.decodeBody(header);
+ protected void decodeBody(Asn1ParsingResult parsingResult) throws IOException {
+ tagging.decodeBody(parsingResult);
}
protected <T extends Asn1Type> T getFieldAs(EnumType index, Class<T> t) {
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader1.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader1.java
deleted file mode 100644
index 503507f..0000000
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader1.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 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.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * ASN1 reader for stateful reading.
- */
-public final class Asn1Reader1 extends Asn1Reader {
-
- public Asn1Reader1(ByteBuffer buffer) {
- super(buffer);
- }
-
- @Override
- public void setPosition(int position) {
- buffer.position(position);
- }
-
- @Override
- public int getPosition() {
- return buffer.position();
- }
-
- @Override
- public boolean available() {
- return buffer.remaining() > 0;
- }
-
- @Override
- protected byte readByte() throws IOException {
- return buffer.get();
- }
-
- @Override
- public ByteBuffer getValueBuffer(int valueLength) {
- ByteBuffer result = buffer.duplicate();
- result.limit(buffer.position() + valueLength);
- buffer.position(buffer.position() + valueLength);
-
- return result;
- }
-}
diff --git a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader2.java b/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader2.java
deleted file mode 100644
index 0136db4..0000000
--- a/kerby-asn1/src/main/java/org/apache/kerby/asn1/util/Asn1Reader2.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * ASN1 reader for positional reading.
- */
-public final class Asn1Reader2 extends Asn1Reader {
- private int position;
-
- public Asn1Reader2(ByteBuffer buffer, int position) {
- super(buffer);
- this.position = position;
- }
-
- public Asn1Reader2(ByteBuffer buffer) {
- super(buffer);
- this.position = buffer.position();
- }
-
- @Override
- public int getPosition() {
- return position;
- }
-
- @Override
- public void setPosition(int position) {
- this.position = position;
- }
-
- @Override
- public boolean available() {
- return position < buffer.limit();
- }
-
- @Override
- public ByteBuffer getValueBuffer(int valueLength) {
- return buffer;
- }
-
- @Override
- protected byte readByte() throws IOException {
- return buffer.get(position++);
- }
-}
diff --git a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1ConstructedOctetString.java b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1ConstructedOctetString.java
new file mode 100644
index 0000000..3d66cb8
--- /dev/null
+++ b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1ConstructedOctetString.java
@@ -0,0 +1,35 @@
+/**
+ * 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 java.io.IOException;
+
+public class TestAsn1ConstructedOctetString {
+
+ //@Test
+ public void testDecoding() throws IOException {
+ byte[] data = TestUtil.readBytesFromTxtFile("/constructed-octet-string.txt");
+ Asn1OctetString octetString = new Asn1OctetString();
+ octetString.decode(data);
+ Asn1.dump(octetString);
+ }
+}
diff --git a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1Dump.java b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1Dump.java
index d564e1b..bbaed2a 100644
--- a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1Dump.java
+++ b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestAsn1Dump.java
@@ -19,12 +19,10 @@
*/
package org.apache.kerby.asn1;
-import org.apache.kerby.asn1.util.IOUtil;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
-import java.io.InputStream;
public class TestAsn1Dump {
@@ -35,7 +33,8 @@
Asn1.dump(pr);
byte[] data = TestData.createSammplePersonnelEncodingData();
- Asn1.dump(data);
+ Asn1.dump(data, true);
+ //Asn1.dump(data, false);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
@@ -44,9 +43,10 @@
@Test
public void testDump1WithCompressedData() throws IOException {
- String hexStr = readTxtFile("/compressed-data.txt");
+ String hexStr = TestUtil.readStringFromTxtFile("/compressed-data.txt");
try {
- Asn1.dump(hexStr);
+ Asn1.dump(hexStr, true);
+ //Asn1.dump(hexStr, false);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
@@ -55,9 +55,10 @@
@Test
public void testDump1WithSignedData() throws IOException {
- String hexStr = readTxtFile("/signed-data.txt");
+ String hexStr = TestUtil.readStringFromTxtFile("/signed-data.txt");
try {
- Asn1.dump(hexStr);
+ Asn1.dump(hexStr, true);
+ //Asn1.dump(hexStr, false);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
@@ -66,22 +67,13 @@
@Test
public void testDump1WithDerData() throws IOException {
- byte[] data = readBinFile("/der-data.dat");
+ byte[] data = TestUtil.readBytesFromBinFile("/der-data.dat");
try {
- Asn1.dump(data);
+ Asn1.dump(data, true);
+ //Asn1.dump(data, false);
} catch (Exception e) {
e.printStackTrace();
Assert.fail();
}
}
-
- static String readTxtFile(String resource) throws IOException {
- InputStream is = TestAsn1Dump.class.getResourceAsStream(resource);
- return IOUtil.readInput(is);
- }
-
- static byte[] readBinFile(String resource) throws IOException {
- InputStream is = TestAsn1Dump.class.getResourceAsStream(resource);
- return IOUtil.readInputStream(is);
- }
}
diff --git a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestPersonnelRecord.java b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestPersonnelRecord.java
index c7f4fde..a8948d4 100644
--- a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestPersonnelRecord.java
+++ b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestPersonnelRecord.java
@@ -76,8 +76,8 @@
public void testDecoding() throws IOException {
PersonnelRecord expected = TestData.createSamplePersonnel();
byte[] data = TestData.createSammplePersonnelEncodingData();
+ Asn1.dump(data, true);
PersonnelRecord decoded = new PersonnelRecord();
- Asn1.dump(data);
decoded.decode(data);
Asn1.dump(decoded);
diff --git a/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestUtil.java b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestUtil.java
new file mode 100644
index 0000000..619af7b
--- /dev/null
+++ b/kerby-asn1/src/test/java/org/apache/kerby/asn1/TestUtil.java
@@ -0,0 +1,47 @@
+/**
+ * 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.util.HexUtil;
+import org.apache.kerby.asn1.util.IOUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public final class TestUtil {
+ private TestUtil() {
+
+ }
+
+ static byte[] readBytesFromTxtFile(String resource) throws IOException {
+ String hexStr = readStringFromTxtFile(resource);
+ return HexUtil.hex2bytes(hexStr);
+ }
+
+ static String readStringFromTxtFile(String resource) throws IOException {
+ InputStream is = TestUtil.class.getResourceAsStream(resource);
+ return IOUtil.readInput(is);
+ }
+
+ static byte[] readBytesFromBinFile(String resource) throws IOException {
+ InputStream is = TestUtil.class.getResourceAsStream(resource);
+ return IOUtil.readInputStream(is);
+ }
+}
diff --git a/kerby-asn1/src/test/resources/constructed-octet-string.txt b/kerby-asn1/src/test/resources/constructed-octet-string.txt
new file mode 100644
index 0000000..66f28f1
--- /dev/null
+++ b/kerby-asn1/src/test/resources/constructed-octet-string.txt
@@ -0,0 +1 @@
+24800482021E789CED945D6FDA301486EF2BF93FE4FA9560F15718AD76618C9BA15140492A75BD0B591A22D1002644E3DFD71E8516ED2FF4B573FC11FBB17D4E62BD69DAB2697BD9715BDE06F976BBAE8BBCAD37CD37339EF49E28BB0B9AFCB5FC11DBCD61CBFA7F292337FA3CC7E6CDFEA5B43DD3149B3F7553DD06CBBAC9EDF163C8B8DE6F37FBDA036F83BA59D74D7917BCD4EBF23F28B999A40A6188FD45BE652FC2F333F46F3D9DCF4CF02EDFB550493633C9A56B18D1301C808594E3D111988384EFA2089101244EB19823A5570909BD4A57A43341E0C9D57928439266F82E4F6CE1D9646462BFE39101CB2138678271D149C9F805C5DB427447263AB6E29DCFFE041333453844629C25FA3101A5C8921964242344D29511260FF78E1DBD834862EE1129BF88A505B75CB85C704ED9AE68AB420A24A58B4BD91465303BBC2E4B4B16268152F8E92216C487D605077A01DAE78CB987F78513BC6C5589B2EA442B48A69E20DAAA5DB6A2B52E239EA25A552B9C154393FBF908D9025AE1D1C78F613C7F80D66E07D5619DDB60BA397D4FFB605BDA202BEDEB9E6837616CA09D3B85E460D2F90FE32152E709C61915CE8A93FF9CF34C0AC198F075922A0D85911FAF0CB814125CB8176178F6DC201A60E04D24C9624E5D17EDE5790E7A0A20548A61D8F7711A43FDC2BF2564C72517BBE8C5179DF056F26EC7779CE1438AE2D8DAD517F58BFA4575FF70064A5277D9B14F77606C403F2E4B3231EA539B923773F797340000
\ No newline at end of file
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 43d4540..4693d05 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,8 +20,8 @@
package org.apache.kerby.kerberos.kerb;
import org.apache.kerby.asn1.Asn1;
-import org.apache.kerby.asn1.Asn1Header;
import org.apache.kerby.asn1.Tag;
+import org.apache.kerby.asn1.parse.Asn1ParsingResult;
import org.apache.kerby.asn1.type.Asn1Type;
import org.apache.kerby.kerberos.kerb.type.ap.ApReq;
import org.apache.kerby.kerberos.kerb.type.base.KrbError;
@@ -65,8 +65,8 @@
}
public static KrbMessage decodeMessage(ByteBuffer buffer) throws IOException {
- Asn1Header header = Asn1.decodeHeader(buffer);
- Tag tag = header.getTag();
+ Asn1ParsingResult parsingResult = Asn1.parse(buffer);
+ Tag tag = parsingResult.tag();
KrbMessage msg;
KrbMessageType msgType = KrbMessageType.fromValue(tag.tagNo());
@@ -88,7 +88,7 @@
throw new IOException("To be supported krb message type with tag: " + tag);
}
- msg.decode(header);
+ msg.decode(parsingResult);
return msg;
}
diff --git a/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralName.java b/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralName.java
index 65c1143..6bae5f4 100644
--- a/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralName.java
+++ b/kerby-pkix/src/main/java/org/apache/kerby/x509/type/GeneralName.java
@@ -19,15 +19,16 @@
*/
package org.apache.kerby.x509.type;
-import org.apache.kerby.asn1.EnumType;
-import org.apache.kerby.asn1.type.Asn1Choice;
import org.apache.kerby.asn1.Asn1FieldInfo;
+import org.apache.kerby.asn1.EnumType;
+import org.apache.kerby.asn1.ExplicitField;
+import org.apache.kerby.asn1.type.Asn1Any;
+import org.apache.kerby.asn1.type.Asn1Choice;
import org.apache.kerby.asn1.type.Asn1IA5String;
-import org.apache.kerby.asn1.type.Asn1Item;
import org.apache.kerby.asn1.type.Asn1ObjectIdentifier;
import org.apache.kerby.asn1.type.Asn1OctetString;
-import org.apache.kerby.asn1.ExplicitField;
import org.apache.kerby.x500.type.Name;
+
import static org.apache.kerby.x509.type.GeneralName.MyEnum.*;
/**
@@ -74,7 +75,7 @@
new ExplicitField(RFC822_NAME, Asn1IA5String.class),
new ExplicitField(DNS_NAME, Asn1IA5String.class),
// ORAddress is to be defined.
- new ExplicitField(X400_ADDRESS, Asn1Item.class),
+ new ExplicitField(X400_ADDRESS, Asn1Any.class),
new ExplicitField(DIRECTORY_NAME, Name.class),
new ExplicitField(EDI_PARTY_NAME, EDIPartyName.class),
new ExplicitField(UNIFORM_RESOURCE_IDENTIFIER, Asn1IA5String.class),
@@ -110,11 +111,11 @@
setFieldAs(DNS_NAME, dnsName);
}
- public Asn1Item getX400Address() {
- return getFieldAs(X400_ADDRESS, Asn1Item.class);
+ public Asn1Any getX400Address() {
+ return getFieldAs(X400_ADDRESS, Asn1Any.class);
}
- public void setX400Address(Asn1Item x400Address) {
+ public void setX400Address(Asn1Any x400Address) {
setFieldAs(X400_ADDRESS, x400Address);
}
diff --git a/kerby-pkix/src/test/java/org/apache/kerby/cms/TestCompressedData.java b/kerby-pkix/src/test/java/org/apache/kerby/cms/TestCompressedData.java
index a662182..5331380 100644
--- a/kerby-pkix/src/test/java/org/apache/kerby/cms/TestCompressedData.java
+++ b/kerby-pkix/src/test/java/org/apache/kerby/cms/TestCompressedData.java
@@ -32,7 +32,7 @@
public void testDump1WithCompressedData() throws IOException {
byte[] data = readDataFile("/compressed-data.txt");
try {
- Asn1.dump(data);
+ Asn1.dump(data, true);
ContentInfo contentInfo = new ContentInfo();
contentInfo.decode(data);
diff --git a/kerby-pkix/src/test/java/org/apache/kerby/cms/TestSignedData.java b/kerby-pkix/src/test/java/org/apache/kerby/cms/TestSignedData.java
index 92b7d13..d4e1a75 100644
--- a/kerby-pkix/src/test/java/org/apache/kerby/cms/TestSignedData.java
+++ b/kerby-pkix/src/test/java/org/apache/kerby/cms/TestSignedData.java
@@ -32,7 +32,7 @@
public void testDump1WithSignedData() throws IOException {
byte[] data = readDataFile("/signed-data.txt");
try {
- Asn1.dump(data);
+ Asn1.dump(data, true);
ContentInfo contentInfo = new ContentInfo();
contentInfo.decode(data);