You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sm...@apache.org on 2006/05/30 11:34:25 UTC
svn commit: r410233 - in
/incubator/harmony/enhanced/classlib/trunk/modules/security/src:
main/java/common/org/apache/harmony/security/asn1/
test/java/common/org/apache/harmony/security/asn1/der/
Author: smishura
Date: Tue May 30 02:34:24 2006
New Revision: 410233
URL: http://svn.apache.org/viewvc?rev=410233&view=rev
Log:
Improved verification of provided identifiers for choice type. Adding regression tests.
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Choice.java
incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Set.java
incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Type.java
incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java (contents, props changed)
Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Choice.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Choice.java?rev=410233&r1=410232&r2=410233&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Choice.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Choice.java Tue May 30 02:34:24 2006
@@ -21,6 +21,10 @@
package org.apache.harmony.security.asn1;
import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.TreeMap;
/**
@@ -206,11 +210,18 @@
public final ASN1Type[] type;
+ // identifiers table: [2][number of distinct identifiers]
+ // identifiers[0]: stores identifiers (includes nested choices)
+ // identifiers[1]: stores identifiers' indexes in array of types
+ private final int[][] identifiers;
+
/**
* Constructs ASN.1 choice type.
*
- * @param type - an array of one or more ASN.1 type alternatives.
- * @throws IllegalArgumentException - type parameter is invalid
+ * @param type -
+ * an array of one or more ASN.1 type alternatives.
+ * @throws IllegalArgumentException -
+ * type parameter is invalid
*/
public ASN1Choice(ASN1Type[] type) {
super(TAG_CHOICE); // has not tag number
@@ -221,15 +232,61 @@
+ " MUST have at least one alternative");
}
- if (!hasDistinctTags(type)) {
- throw new RuntimeException("ASN.1 choice type: "
- + getClass().getName()
- + " MUST have alternatives with distinct tags");
+ // create map of all identifiers
+ TreeMap map = new TreeMap();
+ for (int index = 0; index < type.length; index++) {
+
+ ASN1Type t = type[index];
+
+ if (t instanceof ASN1Any) {
+ // ASN.1 ANY is not allowed,
+ // even it is a single component (not good for nested choices)
+ throw new IllegalArgumentException("ASN.1 choice type: "
+ + getClass().getName() // FIXME name
+ + " MUST have alternatives with distinct tags");
+ } else if (t instanceof ASN1Choice) {
+
+ // add all choice's identifiers
+ int[][] choiceToAdd = ((ASN1Choice) t).identifiers;
+ for (int j = 0; j < choiceToAdd[0].length; j++) {
+ addIdentifier(map, choiceToAdd[0][j], index);
+ }
+ continue;
+ }
+
+ // add primitive identifier
+ if (t.checkTag(t.id)) {
+ addIdentifier(map, t.id, index);
+ }
+
+ // add constructed identifier
+ if (t.checkTag(t.constrId)) {
+ addIdentifier(map, t.constrId, index);
+ }
+ }
+
+ // fill identifiers array
+ int size = map.size();
+ identifiers = new int[2][size];
+ Iterator it = map.keySet().iterator();
+ for (int i = 0; i < size; i++) {
+ BigInteger identifier = (BigInteger) it.next();
+
+ identifiers[0][i] = identifier.intValue();
+ identifiers[1][i] = ((BigInteger) map.get(identifier)).intValue();
}
this.type = type;
}
+ private void addIdentifier(TreeMap map, int identifier, int index){
+ if (map.put(BigInteger.valueOf(identifier), BigInteger.valueOf(index)) != null) {
+ throw new IllegalArgumentException("ASN.1 choice type: "
+ + getClass().getName() // FIXME name
+ + " MUST have alternatives with distinct tags");
+ }
+ }
+
//
//
// DECODE
@@ -238,40 +295,43 @@
/**
* Tests whether one of choice alternatives has the same identifier or not.
- *
- * @param identifier - ASN.1 identifier to be verified
+ *
+ * @param identifier -
+ * ASN.1 identifier to be verified
* @return - true if one of choice alternatives has the same identifier,
- * otherwise false;
+ * otherwise false;
*/
public final boolean checkTag(int identifier) {
- for (int i = 0; i < type.length; i++) {
- if (type[i].checkTag(identifier)) {
- return true;
- }
- }
- return false;
+ return Arrays.binarySearch(identifiers[0], identifier) >= 0;
}
public Object decode(BerInputStream in) throws IOException {
-
- for (int index = 0; index < type.length; index++) {
- if (type[index].checkTag(in.tag)) {
- in.content = type[index].decode(in);
+ int index = Arrays.binarySearch(identifiers[0], in.tag);
+ if (index < 0) {
+ throw new ASN1Exception("Failed to decode ASN.1 choice type. " // FIXME
+ // message
+ + " No alternatives were found for " + getClass().getName());
+ }
- // set index for getDecodedObject method
- in.choiceIndex = index;
+ index = identifiers[1][index];
- return getDecodedObject(in);
- }
+ in.content = type[index].decode(in);
+
+ // set index for getDecodedObject method
+ in.choiceIndex = index;
+
+ if (in.isVerify) {
+ return null;
}
- throw new ASN1Exception("Failed to decode ASN.1 choice type. "
- + " No alternatives were found for " + getClass().getName());
+ return getDecodedObject(in);
}
+
/**
* Extracts chosen object from BER input stream.
- *
- * @param in - decoding input stream
+ *
+ * @param in -
+ * decoding input stream
* @return object that represents this choice
*/
public Object getDecodedObject(BerInputStream in) throws IOException {
Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Set.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Set.java?rev=410233&r1=410232&r2=410233&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Set.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Set.java Tue May 30 02:34:24 2006
@@ -35,10 +35,11 @@
public ASN1Set(ASN1Type[] type) {
super(TAG_SET, type);
- if (!hasDistinctTags(type)) {
- throw new RuntimeException("ASN1 set type: " + getClass().getName()
- + " MUST have alternatives with distinct tags");
- }
+ //FIXME implement check for distinct tags
+ //if (!hasDistinctTags(type)) {
+ // throw new RuntimeException("ASN1 set type: " + getClass().getName()
+ // + " MUST have alternatives with distinct tags");
+ //}
}
//
Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Type.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Type.java?rev=410233&r1=410232&r2=410233&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Type.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/main/java/common/org/apache/harmony/security/asn1/ASN1Type.java Tue May 30 02:34:24 2006
@@ -85,41 +85,6 @@
this.constrId = this.id + PC_CONSTRUCTED;
}
- /**
- * Tests whether ASN.1 type alternatives in
- * provided array have distinct tags ot not
- *
- * @param type - an array of ASN.1 types
- * @return - true if alternatives have distinct tags, otherwise false
- */
- public static boolean hasDistinctTags(ASN1Type[] type) {
-
- for (int i = 0; i < type.length; i++) {
-
- if ((type[i] instanceof ASN1Choice) || (type[i] instanceof ASN1Any)) {
- return false;
- }
-
- int curTag = type[i].id;
- for (int j = i + 1; j < type.length; j++) {
- if (type[j].checkTag(curTag)) {
- return false;
- }
- }
- }
-
- if (type[0] instanceof ASN1StringType) {
- int curTag = type[0].constrId;
- for (int j = 1; j < type.length; j++) {
- if (type[j].checkTag(curTag)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
//
//
// Stubs for DER
Modified: incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java?rev=410233&r1=410232&r2=410233&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java Tue May 30 02:34:24 2006
@@ -27,17 +27,21 @@
import java.util.Collection;
import java.util.List;
+import junit.framework.TestCase;
+
+import org.apache.harmony.security.asn1.ASN1Any;
+import org.apache.harmony.security.asn1.ASN1BitString;
import org.apache.harmony.security.asn1.ASN1Boolean;
import org.apache.harmony.security.asn1.ASN1Choice;
import org.apache.harmony.security.asn1.ASN1Explicit;
import org.apache.harmony.security.asn1.ASN1Integer;
+import org.apache.harmony.security.asn1.ASN1Oid;
import org.apache.harmony.security.asn1.ASN1SequenceOf;
import org.apache.harmony.security.asn1.ASN1Type;
+import org.apache.harmony.security.asn1.BerInputStream;
import org.apache.harmony.security.asn1.DerInputStream;
import org.apache.harmony.security.asn1.DerOutputStream;
-import junit.framework.TestCase;
-
/**
* ASN.1 DER test for Choice type
@@ -84,17 +88,17 @@
// Test Cases
//
- private static Object[][] testcases = new Object[][] {
+ private static Object[][] testcases = {
// format: object to encode / byte array
// choice = Boolean (false)
- new Object[] { Boolean.FALSE, new byte[] { 0x01, 0x01, 0x00 } },
+ { Boolean.FALSE, new byte[] { 0x01, 0x01, 0x00 } },
// choice = Boolean (true)
- new Object[] { Boolean.TRUE, new byte[] { 0x01, 0x01, (byte) 0xFF } },
+ { Boolean.TRUE, new byte[] { 0x01, 0x01, (byte) 0xFF } },
// choice = SequenceOf (empty)
- new Object[] { new ArrayList(), new byte[] { 0x30, 0x00 } },
+ { new ArrayList(), new byte[] { 0x30, 0x00 } },
//TODO add testcase for another ASN.1 type`
@@ -190,5 +194,144 @@
encoded[4] = (byte) 0xFF;
assertEquals("True: ", Boolean.TRUE, explicit.decode(encoded));
+ }
+
+ /**
+ * TODO Put method description here
+ */
+ public void testChoiceOfChoice() throws Exception {
+
+ ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] {
+ ASN1Oid.getInstance(), // first
+ ASN1Boolean.getInstance(),// second: decoded component
+ ASN1Integer.getInstance() // third
+ }) {
+
+ public Object getDecodedObject(BerInputStream in)
+ throws IOException {
+
+ assertEquals("choice1", 1, in.choiceIndex);
+
+ return in.content;
+ }
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+
+ ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] { choice1, // first: decoded component
+ ASN1BitString.getInstance() // second
+ }) {
+
+ public Object getDecodedObject(BerInputStream in)
+ throws IOException {
+
+ assertEquals("choice2", 0, in.choiceIndex);
+
+ return in.content;
+ }
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+
+ Boolean b = (Boolean) choice2.decode(new byte[] { 0x01, 0x01, 0x00 });
+
+ assertTrue(b == Boolean.FALSE);
+ }
+
+ /**
+ * TODO Put method description here
+ */
+ public void testDistinctTags() throws Exception {
+
+ ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] {
+ ASN1Boolean.getInstance(),// component to be checked
+ ASN1Oid.getInstance(), ASN1Integer.getInstance() }) {
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+
+ // two ASN.1 booleans
+ try {
+ new ASN1Choice(new ASN1Type[] { choice1, //
+ ASN1Boolean.getInstance() // component to be checked
+ }) {
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+ fail("No expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // ASN.1 ANY
+ try {
+ new ASN1Choice(new ASN1Type[] { choice1,//
+ ASN1Any.getInstance() // component to be checked
+ }) {
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+ fail("No expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ // two choices
+ ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] {
+ ASN1BitString.getInstance(), //
+ ASN1Boolean.getInstance() //component to be checked
+ }) {
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+
+ try {
+ new ASN1Choice(new ASN1Type[] { choice1, choice2 }) {
+
+ public Object getObjectToEncode(Object obj) {
+ return obj;
+ }
+
+ public int getIndex(Object obj) {
+ return 0;
+ }
+ };
+ fail("No expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
}
}
Propchange: incubator/harmony/enhanced/classlib/trunk/modules/security/src/test/java/common/org/apache/harmony/security/asn1/der/ChoiceTest.java
------------------------------------------------------------------------------
svn:eol-style = native