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