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.ByteArrayInputStream;
     25 import java.io.IOException;
     26 import java.util.Arrays;
     27 
     28 import junit.framework.TestCase;
     29 
     30 import org.apache.harmony.security.asn1.ASN1BitString;
     31 import org.apache.harmony.security.asn1.ASN1Exception;
     32 import org.apache.harmony.security.asn1.BitString;
     33 import org.apache.harmony.security.asn1.DerInputStream;
     34 import org.apache.harmony.security.asn1.DerOutputStream;
     35 import org.apache.harmony.security.asn1.ASN1BitString.ASN1NamedBitList;
     36 
     37 /**
     38  * ASN.1 DER test for Bitstring type
     39  *
     40  * @see http://asn1.elibel.tm.fr/en/standards/index.htm
     41  */
     42 
     43 public class BitStringTest extends TestCase {
     44 
     45     private static Object[][] validBitstring = new Object[][] {
     46             //bitstring array format: bitstring object/ byte array
     47             //
     48             { new BitString(new byte[] { }, 0), // object
     49                     new byte[] { 0x03, 0x01, 0x00 } },
     50             //
     51             { new BitString(new byte[] { 0x05 }, 0), // object
     52                     new byte[] { 0x03, 0x02, 0x00, 0x05 } },
     53             //
     54             { new BitString(new byte[] { (byte) 0x80 }, 7), // object
     55                     new byte[] { 0x03, 0x02, 0x07, (byte) 0x80 } } };
     56 
     57     public void testDecode_Encode() throws IOException {
     58 
     59         // decoder/encoder for testing
     60         ASN1BitString asn1 = ASN1BitString.getInstance();
     61 
     62         // decode from byte array
     63         for (int i = 0; i < validBitstring.length; i++) {
     64             DerInputStream in = new DerInputStream(
     65                     (byte[]) validBitstring[i][1]);
     66 
     67             BitString expected = (BitString) validBitstring[i][0];
     68             BitString decoded = (BitString) asn1.decode(in);
     69 
     70             assertEquals("Testcase: " + i, expected.unusedBits,
     71                     decoded.unusedBits);
     72 
     73             assertTrue("Testcase: " + i, Arrays.equals(expected.bytes,
     74                     decoded.bytes));
     75         }
     76 
     77         // decode from input stream
     78         for (int i = 0; i < validBitstring.length; i++) {
     79             DerInputStream in = new DerInputStream(new ByteArrayInputStream(
     80                     (byte[]) validBitstring[i][1]));
     81 
     82             BitString expected = (BitString) validBitstring[i][0];
     83             BitString decoded = (BitString) asn1.decode(in);
     84 
     85             assertEquals("Testcase: " + i, expected.unusedBits,
     86                     decoded.unusedBits);
     87 
     88             assertTrue("Testcase: " + i, Arrays.equals(expected.bytes,
     89                     decoded.bytes));
     90         }
     91 
     92         // encoding
     93         for (int i = 0; i < validBitstring.length; i++) {
     94             DerOutputStream out = new DerOutputStream(asn1,
     95                     validBitstring[i][0]);
     96             assertTrue("Testcase: " + i, Arrays.equals(
     97                     (byte[]) validBitstring[i][1], out.encoded));
     98         }
     99     }
    100 
    101     public void testDecode_Invalid() throws IOException {
    102         byte[][] invalid = new byte[][] {
    103                 // wrong tag: tag is not 0x03
    104                 new byte[] { 0x02, 0x01, 0x00 },
    105                 // wrong length: length is 0
    106                 new byte[] { 0x03, 0x00 },
    107                 // wrong content: unused bits value > 7
    108                 new byte[] { 0x03, 0x03, 0x09, 0x0F, 0x0F },
    109                 // wrong content: not 0 unused bits for empty string
    110                 new byte[] { 0x03, 0x01, 0x01 },
    111                 // wrong content: unused bits in final octet are not 0
    112                 new byte[] { 0x03, 0x02, 0x01, 0x01 },
    113                 // wrong content: constructed encoding
    114                 new byte[] { 0x23, 0x03, 0x03, 0x01, 0x00 } };
    115 
    116         for (int i = 0; i < invalid.length; i++) {
    117             try {
    118                 DerInputStream in = new DerInputStream(invalid[i]);
    119                 ASN1BitString.getInstance().decode(in);
    120                 fail("No expected ASN1Exception for: " + i);
    121             } catch (ASN1Exception e) {
    122             }
    123         }
    124     }
    125 
    126     //
    127     //
    128     // Named Bit List
    129     //
    130     //
    131 
    132     public void testDecodeNamedBitList() throws IOException {
    133 
    134         Object[][] testcaseBoolean = new Object[][] {
    135                 // bitstring array format: bitstring object/ byte array
    136                 //
    137                 { new boolean[] { }, // object
    138                         new byte[] { 0x03, 0x01, 0x00 } },
    139                 //
    140                 { new boolean[] { true }, // object
    141                         new byte[] { 0x03, 0x02, 0x07, (byte) 0x80 } },
    142                 //
    143                 { new boolean[] { true, false, true }, // object
    144                         new byte[] { 0x03, 0x02, 0x05, (byte) 0xA0 } },
    145                 //
    146                 {
    147                         new boolean[] { true, true, true, true, true, true,
    148                                 true, true }, // object
    149                         new byte[] { 0x03, 0x02, 0x00, (byte) 0xFF } },
    150                 //
    151                 {
    152                         new boolean[] { false, false, false, false, false,
    153                                 false, false, false, true }, // object
    154                         new byte[] { 0x03, 0x03, 0x07, 0x00, (byte) 0x80 } } };
    155 
    156         ASN1NamedBitList decoder = new ASN1NamedBitList();
    157 
    158         for (int i = 0; i < testcaseBoolean.length; i++) {
    159             DerInputStream in = new DerInputStream(
    160                     (byte[]) testcaseBoolean[i][1]);
    161 
    162             assertTrue("Testcase: " + i, Arrays.equals(
    163                     (boolean[]) testcaseBoolean[i][0], (boolean[]) decoder
    164                     .decode(in)));
    165         }
    166     }
    167 
    168     public void testDecodeNamedBitList_SizeConstraints() throws IOException {
    169 
    170         Object[][] testcaseBoolean = new Object[][] {
    171                 //bitstring array format: bitstring object/ byte array
    172                 //
    173                 {
    174                         new boolean[] { false, false, false, false, false,
    175                                 false, false, false }, // object
    176                         new byte[] { 0x03, 0x01, 0x00 } },
    177                 //
    178                 {
    179                         new boolean[] { true, false, false, false, false,
    180                                 false, false, false }, // object
    181                         new byte[] { 0x03, 0x02, 0x07, (byte) 0x80 } },
    182                 //
    183                 {
    184                         new boolean[] { true, false, true, false, false, false,
    185                                 false, false }, // object
    186                         new byte[] { 0x03, 0x02, 0x05, (byte) 0xA0 } },
    187                 //
    188                 {
    189                         new boolean[] { true, true, true, true, true, true,
    190                                 true, true }, // object
    191                         new byte[] { 0x03, 0x02, 0x00, (byte) 0xFF } },
    192                 //
    193                 {
    194                         new boolean[] { false, false, false, false, false,
    195                                 false, false, false, true }, // object
    196                         new byte[] { 0x03, 0x03, 0x07, 0x00, (byte) 0x80 } } };
    197 
    198         ASN1NamedBitList decoder = new ASN1NamedBitList(8);
    199 
    200         for (int i = 0; i < testcaseBoolean.length; i++) {
    201             DerInputStream in = new DerInputStream(
    202                     (byte[]) testcaseBoolean[i][1]);
    203 
    204             assertTrue("Testcase: " + i, Arrays.equals(
    205                     (boolean[]) testcaseBoolean[i][0], (boolean[]) decoder
    206                     .decode(in)));
    207         }
    208     }
    209 
    210     public void testEncodeNamedBitList() throws IOException {
    211 
    212         Object[][] testcaseBoolean = new Object[][] {
    213                 //bitstring array format: bitstring object/ byte array
    214                 //
    215                 { new boolean[] { }, // object
    216                         new byte[] { 0x03, 0x01, 0x00 } },
    217                 //
    218                 { new boolean[] { false }, // object
    219                         new byte[] { 0x03, 0x01, 0x00 } },
    220                 //
    221                 { new boolean[] { true }, // object
    222                         new byte[] { 0x03, 0x02, 0x07, (byte) 0x80 } },
    223                 //
    224                 { new boolean[] { true, false, true }, // object
    225                         new byte[] { 0x03, 0x02, 0x05, (byte) 0xA0 } },
    226                 //
    227                 {
    228                         new boolean[] { true, true, true, true, true, true,
    229                                 true, true }, // object
    230                         new byte[] { 0x03, 0x02, 0x00, (byte) 0xFF } },
    231                 //
    232                 {
    233                         new boolean[] { false, false, false, false, false,
    234                                 false, false, false, true }, // object
    235                         new byte[] { 0x03, 0x03, 0x07, 0x00, (byte) 0x80 } } };
    236 
    237         ASN1NamedBitList encoder = new ASN1NamedBitList();
    238 
    239         for (int i = 0; i < testcaseBoolean.length; i++) {
    240             DerOutputStream out = new DerOutputStream(encoder,
    241                     testcaseBoolean[i][0]);
    242             assertTrue("Testcase: " + i, Arrays.equals(
    243                     (byte[]) testcaseBoolean[i][1], out.encoded));
    244         }
    245     }
    246 }
    247