ChoiceTest.java revision e98fbf8686c5289bf03fe5c3de7ff82d3a77104d
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 22package org.apache.harmony.security.tests.asn1.der; 23 24import java.io.IOException; 25import java.util.ArrayList; 26import java.util.Arrays; 27import java.util.Collection; 28import java.util.List; 29 30import junit.framework.TestCase; 31 32import org.apache.harmony.security.asn1.ASN1Any; 33import org.apache.harmony.security.asn1.ASN1BitString; 34import org.apache.harmony.security.asn1.ASN1Boolean; 35import org.apache.harmony.security.asn1.ASN1Choice; 36import org.apache.harmony.security.asn1.ASN1Explicit; 37import org.apache.harmony.security.asn1.ASN1Integer; 38import org.apache.harmony.security.asn1.ASN1Oid; 39import org.apache.harmony.security.asn1.ASN1SequenceOf; 40import org.apache.harmony.security.asn1.ASN1Type; 41import org.apache.harmony.security.asn1.BerInputStream; 42import org.apache.harmony.security.asn1.DerInputStream; 43import org.apache.harmony.security.asn1.DerOutputStream; 44 45 46/** 47 * ASN.1 DER test for Choice type 48 * 49 * @see http://asn1.elibel.tm.fr/en/standards/index.htm 50 */ 51 52public class ChoiceTest extends TestCase { 53 54 private static ASN1SequenceOf sequence = new ASN1SequenceOf(ASN1Boolean 55 .getInstance()); 56 57 // 58 // choice ::= CHOICE { 59 // boolean BOOLEAN, 60 // sequenceof SEQUENCE OF BOOLEAN, 61 // int INTEGER 62 // } 63 // 64 65 private static ASN1Choice choice = new ASN1Choice(new ASN1Type[] { 66 ASN1Boolean.getInstance(), sequence, ASN1Integer.getInstance() }) { 67 68 public int getIndex(Object object) { 69 if (object instanceof Boolean) { 70 return 0; // ASN1Boolean 71 } else if (object instanceof Collection) { 72 return 1; // ASN1SequenceOf 73 } else { 74 return 2; // ASN1Integer 75 } 76 } 77 78 public Object getObjectToEncode(Object object) { 79 return object; 80 } 81 }; 82 83 // 84 // Test Cases 85 // 86 87 private static Object[][] testcases = { 88 // format: object to encode / byte array 89 90 // choice = Boolean (false) 91 { Boolean.FALSE, new byte[] { 0x01, 0x01, 0x00 } }, 92 93 // choice = Boolean (true) 94 { Boolean.TRUE, new byte[] { 0x01, 0x01, (byte) 0xFF } }, 95 96 // choice = SequenceOf (empty) 97 { new ArrayList(), new byte[] { 0x30, 0x00 } }, 98 99 //TODO add testcase for another ASN.1 type` 100 101 }; 102 103 public void testDecode_Valid() throws IOException { 104 105 for (int i = 0; i < testcases.length; i++) { 106 DerInputStream in = new DerInputStream((byte[]) testcases[i][1]); 107 assertEquals("Test case: " + i, testcases[i][0], choice.decode(in)); 108 } 109 } 110 111 //FIXME need testcase for decoding invalid encodings 112 113 public void testEncode() throws IOException { 114 115 for (int i = 0; i < testcases.length; i++) { 116 DerOutputStream out = new DerOutputStream(choice, testcases[i][0]); 117 assertTrue("Test case: " + i, Arrays.equals( 118 (byte[]) testcases[i][1], out.encoded)); 119 } 120 } 121 122 public void testChoiceInSequenceOf() throws IOException { 123 124 ASN1Choice choice = new ASN1Choice(new ASN1Type[] { 125 ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) { 126 127 public int getIndex(Object object) { 128 if (object instanceof Boolean) { 129 return 0; // ASN1Boolean 130 } else { 131 return 1; // ASN1Integer 132 } 133 } 134 135 public Object getObjectToEncode(Object object) { 136 return object; 137 } 138 }; 139 140 ASN1SequenceOf sequenceOf = new ASN1SequenceOf(choice); 141 142 ArrayList list = new ArrayList(); 143 list.add(Boolean.FALSE); 144 list.add(new byte[] { 0x09 }); 145 146 byte[] encoded = new byte[] { 147 // Sequence Of 148 0x30, 0x06, 149 // Boolean 150 0x01, 0x01, 0x00, 151 // Integer 152 0x02, 0x01, 0x09 }; 153 154 assertTrue("Encoded: ", Arrays.equals(encoded, sequenceOf.encode(list))); 155 156 List values = (List) sequenceOf.decode(encoded); 157 158 assertEquals("Size: ", 2, values.size()); 159 assertEquals("First: ", Boolean.FALSE, values.get(0)); 160 assertTrue("Second: ", Arrays.equals(new byte[] { 0x09 }, 161 (byte[]) values.get(1))); 162 } 163 164 // 165 // 166 // 167 // 168 // 169 170 public void test_ExplicitChoice() throws IOException { 171 172 ASN1Choice choice = new ASN1Choice(new ASN1Type[] { ASN1Boolean 173 .getInstance() }) { 174 175 public Object getObjectToEncode(Object obj) { 176 return obj; 177 } 178 179 public int getIndex(Object obj) { 180 return 0; 181 } 182 }; 183 184 ASN1Explicit explicit = new ASN1Explicit(0, choice); 185 186 byte[] encoded = new byte[] { (byte) 0xA0, 0x03, 0x01, 0x01, 0x00 }; 187 188 assertEquals("False: ", Boolean.FALSE, explicit.decode(encoded)); 189 190 encoded[4] = (byte) 0xFF; 191 192 assertEquals("True: ", Boolean.TRUE, explicit.decode(encoded)); 193 } 194 195 /** 196 * TODO Put method description here 197 */ 198 public void testChoiceOfChoice() throws Exception { 199 200 ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] { 201 ASN1Oid.getInstance(), // first 202 ASN1Boolean.getInstance(),// second: decoded component 203 ASN1Integer.getInstance() // third 204 }) { 205 206 public Object getDecodedObject(BerInputStream in) 207 throws IOException { 208 209 assertEquals("choice1", 1, in.choiceIndex); 210 211 return in.content; 212 } 213 214 public Object getObjectToEncode(Object obj) { 215 return obj; 216 } 217 218 public int getIndex(Object obj) { 219 return 0; 220 } 221 }; 222 223 ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] { choice1, // first: decoded component 224 ASN1BitString.getInstance() // second 225 }) { 226 227 public Object getDecodedObject(BerInputStream in) 228 throws IOException { 229 230 assertEquals("choice2", 0, in.choiceIndex); 231 232 return in.content; 233 } 234 235 public Object getObjectToEncode(Object obj) { 236 return obj; 237 } 238 239 public int getIndex(Object obj) { 240 return 0; 241 } 242 }; 243 244 Boolean b = (Boolean) choice2.decode(new byte[] { 0x01, 0x01, 0x00 }); 245 246 assertTrue(b == Boolean.FALSE); 247 } 248 249 /** 250 * TODO Put method description here 251 */ 252 public void testDistinctTags() throws Exception { 253 254 ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] { 255 ASN1Boolean.getInstance(),// component to be checked 256 ASN1Oid.getInstance(), ASN1Integer.getInstance() }) { 257 258 public Object getObjectToEncode(Object obj) { 259 return obj; 260 } 261 262 public int getIndex(Object obj) { 263 return 0; 264 } 265 }; 266 267 // two ASN.1 booleans 268 try { 269 new ASN1Choice(new ASN1Type[] { choice1, // 270 ASN1Boolean.getInstance() // component to be checked 271 }) { 272 273 public Object getObjectToEncode(Object obj) { 274 return obj; 275 } 276 277 public int getIndex(Object obj) { 278 return 0; 279 } 280 }; 281 fail("No expected IllegalArgumentException"); 282 } catch (IllegalArgumentException e) { 283 } 284 285 // ASN.1 ANY 286 try { 287 new ASN1Choice(new ASN1Type[] { choice1,// 288 ASN1Any.getInstance() // component to be checked 289 }) { 290 291 public Object getObjectToEncode(Object obj) { 292 return obj; 293 } 294 295 public int getIndex(Object obj) { 296 return 0; 297 } 298 }; 299 fail("No expected IllegalArgumentException"); 300 } catch (IllegalArgumentException e) { 301 } 302 303 // two choices 304 ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] { 305 ASN1BitString.getInstance(), // 306 ASN1Boolean.getInstance() //component to be checked 307 }) { 308 309 public Object getObjectToEncode(Object obj) { 310 return obj; 311 } 312 313 public int getIndex(Object obj) { 314 return 0; 315 } 316 }; 317 318 try { 319 new ASN1Choice(new ASN1Type[] { choice1, choice2 }) { 320 321 public Object getObjectToEncode(Object obj) { 322 return obj; 323 } 324 325 public int getIndex(Object obj) { 326 return 0; 327 } 328 }; 329 fail("No expected IllegalArgumentException"); 330 } catch (IllegalArgumentException e) { 331 } 332 } 333} 334