| /* |
| * 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) { |
| } |
| } |
| } |