Home | History | Annotate | Download | only in der
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 /**
     19 * @author Stepan M. Mishura
     20 */
     21 
     22 package org.apache.harmony.security.tests.asn1.der;
     23 
     24 import java.io.IOException;
     25 import java.util.ArrayList;
     26 import java.util.Arrays;
     27 import java.util.List;
     28 
     29 import org.apache.harmony.security.asn1.ASN1Boolean;
     30 import org.apache.harmony.security.asn1.ASN1Exception;
     31 import org.apache.harmony.security.asn1.ASN1Integer;
     32 import org.apache.harmony.security.asn1.ASN1Sequence;
     33 import org.apache.harmony.security.asn1.ASN1SequenceOf;
     34 import org.apache.harmony.security.asn1.ASN1Type;
     35 import org.apache.harmony.security.asn1.BerInputStream;
     36 import org.apache.harmony.security.asn1.DerInputStream;
     37 import org.apache.harmony.security.asn1.DerOutputStream;
     38 
     39 import junit.framework.TestCase;
     40 
     41 
     42 /**
     43  * ASN.1 DER test for Sequence type
     44  *
     45  * @see http://asn1.elibel.tm.fr/en/standards/index.htm
     46  */
     47 
     48 public class SequenceTest extends TestCase {
     49 
     50     private static ASN1SequenceOf sequenceOf = new ASN1SequenceOf(ASN1Boolean
     51             .getInstance());
     52 
     53     private static ArrayList defaultList;
     54 
     55     private static ASN1Sequence sequence;
     56 
     57     private static Object[][] testcases;
     58 
     59     protected void setUp() throws Exception {
     60         super.setUp();
     61 
     62         //
     63         // sequence ::= SEQUENCE {
     64         //     boolean BOOLEAN, DEFAULT true
     65         //     list SEQUENCE OF BOOLEAN, DEFAULT list(false)
     66         // }
     67         //
     68 
     69         defaultList = new ArrayList();
     70         defaultList.add(Boolean.FALSE);
     71 
     72         sequence = new ASN1Sequence(new ASN1Type[] { ASN1Boolean.getInstance(),
     73                 sequenceOf }) {
     74             {
     75                 setDefault(Boolean.TRUE, 0);
     76                 setDefault(defaultList, 1);
     77             }
     78 
     79             protected Object getDecodedObject(BerInputStream in)
     80                     throws IOException {
     81                 Object[] values = (Object[]) in.content;
     82                 return new AppClass((Boolean) values[0], (List) values[1]);
     83             }
     84 
     85             protected void getValues(Object object, Object[] values) {
     86                 AppClass obj = (AppClass) object;
     87 
     88                 values[0] = obj.ok;
     89                 values[1] = obj.list;
     90             }
     91         };
     92 
     93         //
     94         // Test Cases
     95         //
     96 
     97         testcases = new Object[][] {
     98                 // format: object to encode / byte array
     99 
    100                 // sequence : all values are default
    101                 { new AppClass(Boolean.TRUE, defaultList),
    102                         new byte[] { 0x30, 0x00 } },
    103 
    104                 // sequence : true, default
    105                 { new AppClass(Boolean.FALSE, defaultList),
    106                         new byte[] { 0x30, 0x03, 0x01, 0x01, 0x00 } },
    107 
    108                 // sequence = default, empty sequence
    109                 { new AppClass(Boolean.TRUE, new ArrayList()),
    110                         new byte[] { 0x30, 0x02, 0x30, 0x00 } },
    111 
    112                 // sequence = false, empty sequence
    113                 { new AppClass(Boolean.FALSE, new ArrayList()),
    114                         new byte[] { 0x30, 0x05, 0x01, 0x01, 0x00, 0x30, 0x00 } },
    115 
    116         //TODO add testcase for another ASN.1 type`
    117 
    118         };
    119     }
    120 
    121     //
    122     // Application class
    123     //
    124 
    125     public static class AppClass {
    126 
    127         public Boolean ok;
    128 
    129         public List list;
    130 
    131         public AppClass(Boolean ok, List list) {
    132             this.ok = ok;
    133             this.list = list;
    134         }
    135 
    136         public boolean equals(Object o) {
    137             if (o instanceof AppClass) {
    138                 AppClass obj = (AppClass) o;
    139                 return ok.equals(obj.ok) && list.equals(obj.list);
    140             }
    141             return false;
    142         }
    143     }
    144 
    145     public void testDecode_Valid() throws IOException {
    146 
    147         for (int i = 0; i < testcases.length; i++) {
    148             try {
    149                 DerInputStream in = new DerInputStream((byte[]) testcases[i][1]);
    150                 assertEquals("Test case: " + i, testcases[i][0], sequence
    151                         .decode(in));
    152             } catch (ASN1Exception e) {
    153                 fail("Test case: " + i + "\n" + e.getMessage());
    154             }
    155         }
    156     }
    157 
    158     //FIXME need testcase for decoding invalid encodings
    159 
    160     public void testEncode() throws IOException {
    161 
    162         for (int i = 0; i < testcases.length; i++) {
    163             DerOutputStream out = new DerOutputStream(sequence, testcases[i][0]);
    164             assertTrue("Test case: " + i, Arrays.equals(
    165                     (byte[]) testcases[i][1], out.encoded));
    166         }
    167     }
    168 
    169     public void testVerify() throws IOException {
    170 
    171         ASN1Sequence seqVerify = new ASN1Sequence(new ASN1Type[] {
    172                 ASN1Boolean.getInstance(), sequenceOf }) {
    173             {
    174                 setDefault(Boolean.TRUE, 0);
    175                 setDefault(defaultList, 1);
    176             }
    177 
    178             protected Object getDecodedObject(BerInputStream in)
    179                     throws IOException {
    180                 throw new IOException(
    181                         "Method getDecodedObject MUST not be invoked");
    182             }
    183         };
    184 
    185         for (int i = 0; i < testcases.length; i++) {
    186             DerInputStream in = new DerInputStream((byte[]) testcases[i][1]);
    187             in.setVerify();
    188             seqVerify.decode(in);
    189         }
    190     }
    191 
    192     /**
    193      * Tests encoding default fields
    194      */
    195     public void testEncodeDefault() throws IOException {
    196 
    197         //
    198         // Boolean as default
    199         //
    200         ASN1Sequence s = new ASN1Sequence(new ASN1Type[] { ASN1Boolean
    201                 .getInstance() }) {
    202             {
    203                 setDefault(Boolean.TRUE, 0);
    204             }
    205 
    206             protected void getValues(Object object, Object[] values) {
    207                 values = (Object[]) object;
    208             }
    209         };
    210 
    211         byte[] expectedArray = new byte[] { 0x30, 0x00 };
    212 
    213         byte[] encoded = s.encode(new Object[] { Boolean.TRUE });
    214         assertTrue("Encoded boolean:", Arrays.equals(expectedArray, encoded));
    215 
    216         //
    217         // Integer as default
    218         //
    219         s = new ASN1Sequence(new ASN1Type[] { ASN1Integer.getInstance() }) {
    220             {
    221                 setDefault(new byte[] { 0x01 }, 0);
    222             }
    223 
    224             protected void getValues(Object object, Object[] values) {
    225                 values = (Object[]) object;
    226             }
    227         };
    228 
    229         encoded = s.encode(new Object[] { new byte[] { 0x01 } });
    230         assertTrue("Encoded integer:", Arrays.equals(expectedArray, encoded));
    231     }
    232 
    233     /**
    234      * Tests encoding optional fields
    235      */
    236     public void testEncodeOptional() throws IOException {
    237 
    238         //
    239         // Test not optional
    240         //
    241         ASN1Sequence s = new ASN1Sequence(new ASN1Type[] { ASN1Boolean
    242                 .getInstance() }) {
    243 
    244             protected void getValues(Object object, Object[] values) {
    245                 values[0] = ((Object[]) object)[0];
    246             }
    247         };
    248 
    249         try {
    250             s.encode(new Object[] { null });
    251             fail("No expected RuntimeException");
    252         } catch (RuntimeException e) {
    253         }
    254 
    255         //
    256         // Test optional
    257         //
    258         s = new ASN1Sequence(new ASN1Type[] { ASN1Boolean.getInstance() }) {
    259             {
    260                 setOptional(0);
    261             }
    262 
    263             protected void getValues(Object object, Object[] values) {
    264                 values[0] = ((Object[]) object)[0];
    265             }
    266         };
    267 
    268         byte[] expectedArray = new byte[] { 0x30, 0x00 };
    269 
    270         byte[] encoded = s.encode(new Object[] { null });
    271         assertTrue("Encoded boolean:", Arrays.equals(expectedArray, encoded));
    272     }
    273 }
    274