001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Stepan M. Mishura
020: * @version $Revision$
021: */package org.apache.harmony.security.tests.asn1.der;
022:
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Arrays;
026: import java.util.Collection;
027: import java.util.List;
028:
029: import junit.framework.TestCase;
030:
031: import org.apache.harmony.security.asn1.ASN1Any;
032: import org.apache.harmony.security.asn1.ASN1BitString;
033: import org.apache.harmony.security.asn1.ASN1Boolean;
034: import org.apache.harmony.security.asn1.ASN1Choice;
035: import org.apache.harmony.security.asn1.ASN1Explicit;
036: import org.apache.harmony.security.asn1.ASN1Integer;
037: import org.apache.harmony.security.asn1.ASN1Oid;
038: import org.apache.harmony.security.asn1.ASN1SequenceOf;
039: import org.apache.harmony.security.asn1.ASN1Type;
040: import org.apache.harmony.security.asn1.BerInputStream;
041: import org.apache.harmony.security.asn1.DerInputStream;
042: import org.apache.harmony.security.asn1.DerOutputStream;
043:
044: /**
045: * ASN.1 DER test for Choice type
046: *
047: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
048: */
049:
050: public class ChoiceTest extends TestCase {
051:
052: public static void main(String[] args) {
053: junit.textui.TestRunner.run(ChoiceTest.class);
054: }
055:
056: private static ASN1SequenceOf sequence = new ASN1SequenceOf(
057: ASN1Boolean.getInstance());
058:
059: //
060: // choice ::= CHOICE {
061: // boolean BOOLEAN,
062: // sequenceof SEQUENCE OF BOOLEAN,
063: // int INTEGER
064: // }
065: //
066:
067: private static ASN1Choice choice = new ASN1Choice(new ASN1Type[] {
068: ASN1Boolean.getInstance(), sequence,
069: ASN1Integer.getInstance() }) {
070:
071: public int getIndex(Object object) {
072: if (object instanceof Boolean) {
073: return 0; // ASN1Boolean
074: } else if (object instanceof Collection) {
075: return 1; // ASN1SequenceOf
076: } else {
077: return 2; // ASN1Integer
078: }
079: }
080:
081: public Object getObjectToEncode(Object object) {
082: return object;
083: }
084: };
085:
086: //
087: // Test Cases
088: //
089:
090: private static Object[][] testcases = {
091: // format: object to encode / byte array
092:
093: // choice = Boolean (false)
094: { Boolean.FALSE, new byte[] { 0x01, 0x01, 0x00 } },
095:
096: // choice = Boolean (true)
097: { Boolean.TRUE, new byte[] { 0x01, 0x01, (byte) 0xFF } },
098:
099: // choice = SequenceOf (empty)
100: { new ArrayList(), new byte[] { 0x30, 0x00 } },
101:
102: //TODO add testcase for another ASN.1 type`
103:
104: };
105:
106: public void testDecode_Valid() throws IOException {
107:
108: for (int i = 0; i < testcases.length; i++) {
109: DerInputStream in = new DerInputStream(
110: (byte[]) testcases[i][1]);
111: assertEquals("Test case: " + i, testcases[i][0], choice
112: .decode(in));
113: }
114: }
115:
116: //FIXME need testcase for decoding invalid encodings
117:
118: public void testEncode() throws IOException {
119:
120: for (int i = 0; i < testcases.length; i++) {
121: DerOutputStream out = new DerOutputStream(choice,
122: testcases[i][0]);
123: assertTrue("Test case: " + i, Arrays.equals(
124: (byte[]) testcases[i][1], out.encoded));
125: }
126: }
127:
128: public void testChoiceInSequenceOf() throws IOException {
129:
130: ASN1Choice choice = new ASN1Choice(new ASN1Type[] {
131: ASN1Boolean.getInstance(), ASN1Integer.getInstance() }) {
132:
133: public int getIndex(Object object) {
134: if (object instanceof Boolean) {
135: return 0; // ASN1Boolean
136: } else {
137: return 1; // ASN1Integer
138: }
139: }
140:
141: public Object getObjectToEncode(Object object) {
142: return object;
143: }
144: };
145:
146: ASN1SequenceOf sequenceOf = new ASN1SequenceOf(choice);
147:
148: ArrayList list = new ArrayList();
149: list.add(Boolean.FALSE);
150: list.add(new byte[] { 0x09 });
151:
152: byte[] encoded = new byte[] {
153: // Sequence Of
154: 0x30, 0x06,
155: // Boolean
156: 0x01, 0x01, 0x00,
157: // Integer
158: 0x02, 0x01, 0x09 };
159:
160: assertTrue("Encoded: ", Arrays.equals(encoded, sequenceOf
161: .encode(list)));
162:
163: List values = (List) sequenceOf.decode(encoded);
164:
165: assertEquals("Size: ", 2, values.size());
166: assertEquals("First: ", Boolean.FALSE, values.get(0));
167: assertTrue("Second: ", Arrays.equals(new byte[] { 0x09 },
168: (byte[]) values.get(1)));
169: }
170:
171: //
172: //
173: //
174: //
175: //
176:
177: public void test_ExplicitChoice() throws IOException {
178:
179: ASN1Choice choice = new ASN1Choice(new ASN1Type[] { ASN1Boolean
180: .getInstance() }) {
181:
182: public Object getObjectToEncode(Object obj) {
183: return obj;
184: }
185:
186: public int getIndex(Object obj) {
187: return 0;
188: }
189: };
190:
191: ASN1Explicit explicit = new ASN1Explicit(0, choice);
192:
193: byte[] encoded = new byte[] { (byte) 0xA0, 0x03, 0x01, 0x01,
194: 0x00 };
195:
196: assertEquals("False: ", Boolean.FALSE, explicit.decode(encoded));
197:
198: encoded[4] = (byte) 0xFF;
199:
200: assertEquals("True: ", Boolean.TRUE, explicit.decode(encoded));
201: }
202:
203: /**
204: * TODO Put method description here
205: */
206: public void testChoiceOfChoice() throws Exception {
207:
208: ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] {
209: ASN1Oid.getInstance(), // first
210: ASN1Boolean.getInstance(),// second: decoded component
211: ASN1Integer.getInstance() // third
212: }) {
213:
214: public Object getDecodedObject(BerInputStream in)
215: throws IOException {
216:
217: assertEquals("choice1", 1, in.choiceIndex);
218:
219: return in.content;
220: }
221:
222: public Object getObjectToEncode(Object obj) {
223: return obj;
224: }
225:
226: public int getIndex(Object obj) {
227: return 0;
228: }
229: };
230:
231: ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] { choice1, // first: decoded component
232: ASN1BitString.getInstance() // second
233: }) {
234:
235: public Object getDecodedObject(BerInputStream in)
236: throws IOException {
237:
238: assertEquals("choice2", 0, in.choiceIndex);
239:
240: return in.content;
241: }
242:
243: public Object getObjectToEncode(Object obj) {
244: return obj;
245: }
246:
247: public int getIndex(Object obj) {
248: return 0;
249: }
250: };
251:
252: Boolean b = (Boolean) choice2.decode(new byte[] { 0x01, 0x01,
253: 0x00 });
254:
255: assertTrue(b == Boolean.FALSE);
256: }
257:
258: /**
259: * TODO Put method description here
260: */
261: public void testDistinctTags() throws Exception {
262:
263: ASN1Choice choice1 = new ASN1Choice(new ASN1Type[] {
264: ASN1Boolean.getInstance(),// component to be checked
265: ASN1Oid.getInstance(), ASN1Integer.getInstance() }) {
266:
267: public Object getObjectToEncode(Object obj) {
268: return obj;
269: }
270:
271: public int getIndex(Object obj) {
272: return 0;
273: }
274: };
275:
276: // two ASN.1 booleans
277: try {
278: new ASN1Choice(new ASN1Type[] { choice1, //
279: ASN1Boolean.getInstance() // component to be checked
280: }) {
281:
282: public Object getObjectToEncode(Object obj) {
283: return obj;
284: }
285:
286: public int getIndex(Object obj) {
287: return 0;
288: }
289: };
290: fail("No expected IllegalArgumentException");
291: } catch (IllegalArgumentException e) {
292: }
293:
294: // ASN.1 ANY
295: try {
296: new ASN1Choice(new ASN1Type[] { choice1,//
297: ASN1Any.getInstance() // component to be checked
298: }) {
299:
300: public Object getObjectToEncode(Object obj) {
301: return obj;
302: }
303:
304: public int getIndex(Object obj) {
305: return 0;
306: }
307: };
308: fail("No expected IllegalArgumentException");
309: } catch (IllegalArgumentException e) {
310: }
311:
312: // two choices
313: ASN1Choice choice2 = new ASN1Choice(new ASN1Type[] {
314: ASN1BitString.getInstance(), //
315: ASN1Boolean.getInstance() //component to be checked
316: }) {
317:
318: public Object getObjectToEncode(Object obj) {
319: return obj;
320: }
321:
322: public int getIndex(Object obj) {
323: return 0;
324: }
325: };
326:
327: try {
328: new ASN1Choice(new ASN1Type[] { choice1, choice2 }) {
329:
330: public Object getObjectToEncode(Object obj) {
331: return obj;
332: }
333:
334: public int getIndex(Object obj) {
335: return 0;
336: }
337: };
338: fail("No expected IllegalArgumentException");
339: } catch (IllegalArgumentException e) {
340: }
341: }
342: }
|