blob: 272ad3a4e1ab355bbe24252814e23937c2d1f118 [file] [log] [blame]
/*
* 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.
*/
/**
* @author Stepan M. Mishura
*/
package org.apache.harmony.security.tests.asn1.der;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
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;
/**
* ASN.1 DER test for Choice type
*
* @see http://asn1.elibel.tm.fr/en/standards/index.htm
*/
public class ChoiceTest extends TestCase {
private static ASN1SequenceOf sequence = new ASN1SequenceOf(ASN1Boolean
.getInstance());
//
// choice ::= CHOICE {
// boolean BOOLEAN,
// sequenceof SEQUENCE OF BOOLEAN,
// int INTEGER
// }
//
private static ASN1Choice choice = new ASN1Choice(new ASN1Type[] {
ASN1Boolean.getInstance(), sequence, ASN1Integer.getInstance() }) {
public int getIndex(Object object) {
if (object instanceof Boolean) {
return 0; // ASN1Boolean
} else if (object instanceof Collection) {
return 1; // ASN1SequenceOf
} else {
return 2; // ASN1Integer
}
}
public Object getObjectToEncode(Object object) {
return object;
}
};
//
// Test Cases
//
private static Object[][] testcases = {
// format: object to encode / byte array
// choice = Boolean (false)
{ Boolean.FALSE, new byte[] { 0x01, 0x01, 0x00 } },
// choice = Boolean (true)
{ Boolean.TRUE, new byte[] { 0x01, 0x01, (byte) 0xFF } },
// choice = SequenceOf (empty)
{ new ArrayList(), new byte[] { 0x30, 0x00 } },
//TODO add testcase for another ASN.1 type`
};
public void testDecode_Valid() throws IOException {
for (int i = 0; i < testcases.length; i++) {
DerInputStream in = new DerInputStream((byte[]) testcases[i][1]);
assertEquals("Test case: " + i, testcases[i][0], choice.decode(in));
}
}
//FIXME need testcase for decoding invalid encodings
public void testEncode() throws IOException {
for (int i = 0; i < testcases.length; i++) {
DerOutputStream out = new DerOutputStream(choice, testcases[i][0]);
assertTrue("Test case: " + i, Arrays.equals(
(byte[]) testcases[i][1], out.encoded));
}
}
public void testChoiceInSequenceOf() throws IOException {
ASN1Choice choice = new ASN1Choice(new ASN1Type[] {
ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) {
public int getIndex(Object object) {
if (object instanceof Boolean) {
return 0; // ASN1Boolean
} else {
return 1; // ASN1Integer
}
}
public Object getObjectToEncode(Object object) {
return object;
}
};
ASN1SequenceOf sequenceOf = new ASN1SequenceOf(choice);
ArrayList list = new ArrayList();
list.add(Boolean.FALSE);
list.add(new byte[] { 0x09 });
byte[] encoded = new byte[] {
// Sequence Of
0x30, 0x06,
// Boolean
0x01, 0x01, 0x00,
// Integer
0x02, 0x01, 0x09 };
assertTrue("Encoded: ", Arrays.equals(encoded, sequenceOf.encode(list)));
List values = (List) sequenceOf.decode(encoded);
assertEquals("Size: ", 2, values.size());
assertEquals("First: ", Boolean.FALSE, values.get(0));
assertTrue("Second: ", Arrays.equals(new byte[] { 0x09 },
(byte[]) values.get(1)));
}
//
//
//
//
//
public void test_ExplicitChoice() throws IOException {
ASN1Choice choice = new ASN1Choice(new ASN1Type[] { ASN1Boolean
.getInstance() }) {
public Object getObjectToEncode(Object obj) {
return obj;
}
public int getIndex(Object obj) {
return 0;
}
};
ASN1Explicit explicit = new ASN1Explicit(0, choice);
byte[] encoded = new byte[] { (byte) 0xA0, 0x03, 0x01, 0x01, 0x00 };
assertEquals("False: ", Boolean.FALSE, explicit.decode(encoded));
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) {
}
}
}