1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.uicc.euicc.asn1; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertTrue; 23 import static org.junit.Assert.fail; 24 25 import android.test.suitebuilder.annotation.SmallTest; 26 27 import com.android.internal.telephony.uicc.IccUtils; 28 import com.android.internal.telephony.uicc.asn1.Asn1Decoder; 29 import com.android.internal.telephony.uicc.asn1.Asn1Node; 30 import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException; 31 import com.android.internal.telephony.uicc.asn1.TagNotFoundException; 32 33 import org.junit.Test; 34 35 public class Asn1NodeTest { 36 37 @SmallTest 38 @Test 39 public void testCreateConstructedNodeWithShortTag() { 40 Asn1Node node = Asn1Node.newBuilder(0x65).build(); 41 assertEquals(0x65, node.getTag()); 42 assertTrue(node.isConstructed()); 43 assertEquals(2, node.getEncodedLength()); 44 assertEquals(0, node.getDataLength()); 45 assertArrayEquals(new byte[] {0x65, 0x00}, node.toBytes()); 46 } 47 48 @SmallTest 49 @Test 50 public void testCreateConstructedNodeWithLongTag() { 51 Asn1Node node = Asn1Node.newBuilder(0x3F34).build(); 52 assertEquals(0x3F34, node.getTag()); 53 assertTrue(node.isConstructed()); 54 assertEquals(3, node.getEncodedLength()); 55 assertEquals(0, node.getDataLength()); 56 assertArrayEquals(new byte[] {0x3F, 0x34, 0x00}, node.toBytes()); 57 } 58 59 @SmallTest 60 @Test 61 public void testChildren() throws TagNotFoundException, InvalidAsn1DataException { 62 Asn1Node node = 63 Asn1Node.newBuilder(0x3F34) 64 .addChild(Asn1Node.newBuilder(0x35).addChild(Asn1Node.newBuilder(0x36))) 65 .addChild(Asn1Node.newBuilder(0x35)) 66 .addChild(Asn1Node.newBuilder(0x37)) 67 .build(); 68 69 assertEquals(0x3F34, node.getTag()); 70 assertEquals(3, node.getChildren().size()); 71 assertEquals(0x35, node.getChildren().get(0).getTag()); 72 assertEquals(0x35, node.getChildren().get(1).getTag()); 73 assertEquals(0x37, node.getChildren().get(2).getTag()); 74 assertEquals(2, node.getChildren(0x35).size()); 75 assertEquals(0x35, node.getChildren(0x35).get(0).getTag()); 76 assertEquals(0x35, node.getChildren(0x35).get(1).getTag()); 77 assertEquals(1, node.getChild(0x35).getChildren().size()); 78 assertEquals(0, node.getChildren().get(1).getChildren().size()); 79 assertEquals(0x36, node.getChild(0x35).getChildren().get(0).getTag()); 80 81 assertTrue(node.hasChild(0x35, 0x36)); 82 assertFalse(node.hasChild(0x38, 0x39)); 83 assertTrue(node.getChild(0x35).hasChild(0x36)); 84 assertFalse(node.getChild(0x35).hasChild(0x39)); 85 } 86 87 @SmallTest 88 @Test 89 public void testNonExitingChildren() throws TagNotFoundException, InvalidAsn1DataException { 90 Asn1Node node = 91 Asn1Node.newBuilder(0x3F34) 92 .addChild(Asn1Node.newBuilder(0x34)) 93 .addChild(Asn1Node.newBuilder(0x35).addChild(Asn1Node.newBuilder(0x36))) 94 .addChildAsInteger(0x11, 123) 95 .build(); 96 97 assertEquals(0, node.getChild(0x34).getChildren(0x37).size()); 98 assertEquals(0, node.getChildren(0x37).size()); 99 assertEquals(0, node.getChild(0x11).getChildren(0x37).size()); 100 assertEquals(0, node.getChild(0x11).getChildren().size()); 101 try { 102 node.getChild(0x35).getChild(0x37); 103 fail("0x37 should not exist."); 104 } catch (TagNotFoundException e) { 105 assertEquals(0x37, e.getTag()); 106 } 107 try { 108 node.getChild(0x35, 0x37); 109 fail("0x37 should not exist."); 110 } catch (TagNotFoundException e) { 111 assertEquals(0x37, e.getTag()); 112 } 113 try { 114 node.getChild(0x11).getChild(0x37); 115 fail("0x37 should not exist."); 116 } catch (TagNotFoundException e) { 117 assertEquals(0x37, e.getTag()); 118 } 119 } 120 121 @SmallTest 122 @Test 123 public void testBuilderAndGetters() throws TagNotFoundException, InvalidAsn1DataException { 124 Asn1Node node = 125 Asn1Node.newBuilder(0x30) 126 .addChildAsInteger(0x11, 1234567) 127 .addChildAsString(0x12, "This is a test.") 128 .addChild( 129 Asn1Node.newBuilder(0x31) 130 .addChildAsBits(0x13, 0xF2344) 131 .addChildAsBytes(0x14, new byte[] {-1, 0, -1})) 132 .addChildAsBoolean(0x15, true) 133 .addChildAsBoolean(0x16, false) 134 .addChildren(IccUtils.hexStringToBytes("13040422C4F01403FF00FF")) 135 .build(); 136 137 assertEquals(54, node.getEncodedLength()); 138 assertEquals(52, node.getDataLength()); 139 140 final String nodeHex = 141 "3034110312D687120F54686973206973206120746573742E310B13040422C4F0" 142 + "1403FF00FF1501FF16010013040422C4F01403FF00FF"; 143 assertEquals(nodeHex, node.toHex()); 144 assertEquals("3034", node.getHeadAsHex()); 145 assertEquals(1234567, node.getChild(0x11).asInteger()); 146 assertEquals("This is a test.", node.getChild(0x12).asString()); 147 assertEquals(0xF2344, node.getChild(0x31).getChild(0x13).asBits()); 148 assertArrayEquals(new byte[] {-1, 0, -1}, node.getChild(0x31).getChild(0x14).asBytes()); 149 assertTrue(node.getChild(0x15).asBoolean()); 150 assertFalse(node.getChild(0x16).asBoolean()); 151 assertEquals(0xF2344, node.getChild(0x13).asBits()); 152 assertArrayEquals(new byte[] {-1, 0, -1}, node.getChild(0x14).asBytes()); 153 } 154 155 @SmallTest 156 @Test 157 public void testGettersInvalidData() throws TagNotFoundException, InvalidAsn1DataException { 158 Asn1Node node = Asn1Node.newBuilder(0x30).addChildAsString(0x12, "string").build(); 159 try { 160 node.getChild(0x12).asInteger(); 161 fail("Should not be parsed."); 162 } catch (InvalidAsn1DataException e) { 163 assertEquals(0x12, e.getTag()); 164 } 165 try { 166 node.getChild(0x12).asBits(); 167 fail("Should not be parsed."); 168 } catch (InvalidAsn1DataException e) { 169 assertEquals(0x12, e.getTag()); 170 } 171 try { 172 node.getChild(0x12).asBoolean(); 173 fail("Should not be parsed."); 174 } catch (InvalidAsn1DataException e) { 175 assertEquals(0x12, e.getTag()); 176 } 177 } 178 179 @SmallTest 180 @Test 181 public void testWriteToBytes() throws InvalidAsn1DataException { 182 final String nodeHex = 183 "3031110312D687120F54686973206973206120746573742E310B13040422C4F0" 184 + "1403FF00FF1501FF13040422C4F01403FF00FF"; 185 186 Asn1Node node = new Asn1Decoder(nodeHex).nextNode(); 187 // Writes the bytes before children accessed. 188 assertEquals(nodeHex, node.toHex()); 189 // Writes the bytes after children accessed. 190 node.getChildren(); 191 assertEquals(nodeHex, node.toHex()); 192 } 193 194 @SmallTest 195 @Test 196 public void testLongFormLength() throws TagNotFoundException, InvalidAsn1DataException { 197 Asn1Node node = Asn1Node.newBuilder(0xBF37).addChildAsBytes(0x5A, new byte[257]).build(); 198 assertEquals(266, node.getEncodedLength()); 199 assertEquals(261, node.getDataLength()); 200 assertEquals(257, node.getChild(0x5A).getDataLength()); 201 assertEquals("BF37820105", node.getHeadAsHex()); 202 203 byte[] expected = new byte[266]; 204 System.arraycopy(IccUtils.hexStringToBytes("BF378201055A820101"), 0, expected, 0, 9); 205 byte[] actual = new byte[266]; 206 node.writeToBytes(actual, 0); 207 assertArrayEquals(expected, actual); 208 } 209 210 @SmallTest 211 @Test(expected = IllegalArgumentException.class) 212 public void testBuilder_NonConstructedTag() { 213 Asn1Node.newBuilder(0x87); 214 } 215 216 @SmallTest 217 @Test(expected = IllegalStateException.class) 218 public void testBuilderAddChildAsInteger_ConstructedTag() { 219 Asn1Node.newBuilder(0xBF37).addChildAsInteger(0xBF37, 1); 220 } 221 222 @SmallTest 223 @Test(expected = IllegalStateException.class) 224 public void testBuilderAddChildAsString_ConstructedTag() { 225 Asn1Node.newBuilder(0xBF37).addChildAsString(0xBF37, ""); 226 } 227 228 @SmallTest 229 @Test(expected = IllegalStateException.class) 230 public void testBuilderAddChildAsBytes_ConstructedTag() { 231 Asn1Node.newBuilder(0xBF37).addChildAsBytesFromHex(0xBF37, "00"); 232 } 233 234 @SmallTest 235 @Test(expected = IllegalStateException.class) 236 public void testBuilderAddChildAsBits_ConstructedTag() { 237 Asn1Node.newBuilder(0xBF37).addChildAsBits(0xBF37, 1); 238 } 239 240 @SmallTest 241 @Test(expected = IllegalStateException.class) 242 public void testBuilderAddChildAsBoolean_ConstructedTag() { 243 Asn1Node.newBuilder(0xBF37).addChildAsBoolean(0xBF37, true); 244 } 245 246 @SmallTest 247 @Test(expected = IllegalStateException.class) 248 public void testAsInteger_ConstructedTag() throws InvalidAsn1DataException { 249 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 250 node.asInteger(); 251 } 252 253 @SmallTest 254 @Test(expected = IllegalStateException.class) 255 public void testAsLong_ConstructedTag() throws InvalidAsn1DataException { 256 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 257 node.asRawLong(); 258 } 259 260 @SmallTest 261 @Test(expected = IllegalStateException.class) 262 public void testAsString_ConstructedTag() throws InvalidAsn1DataException { 263 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 264 node.asString(); 265 } 266 267 @SmallTest 268 @Test(expected = IllegalStateException.class) 269 public void testAsBytes_ConstructedTag() throws InvalidAsn1DataException { 270 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 271 node.asBytes(); 272 } 273 274 @SmallTest 275 @Test(expected = IllegalStateException.class) 276 public void testAsBits_ConstructedTag() throws InvalidAsn1DataException { 277 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 278 node.asBits(); 279 } 280 281 @SmallTest 282 @Test(expected = IllegalStateException.class) 283 public void testAsBoolean_ConstructedTag() throws InvalidAsn1DataException { 284 Asn1Node node = Asn1Node.newBuilder(0xBF37).build(); 285 node.asBoolean(); 286 } 287 288 @SmallTest 289 @Test(expected = InvalidAsn1DataException.class) 290 public void testAsBoolean_InvalidData() throws TagNotFoundException, InvalidAsn1DataException { 291 Asn1Node node = Asn1Node.newBuilder(0xBF37).addChildAsString(1, "1").build(); 292 node.getChild(1).asBoolean(); 293 } 294 295 @SmallTest 296 @Test(expected = IndexOutOfBoundsException.class) 297 public void testWriteToBytes_IndexOutOfBounds() 298 throws TagNotFoundException, InvalidAsn1DataException { 299 Asn1Node node = Asn1Node.newBuilder(0xBF37).addChildAsString(1, "1").build(); 300 byte[] bytes = new byte[1]; 301 node.writeToBytes(bytes, 0); 302 } 303 } 304