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.List;
027:
028: import org.apache.harmony.security.asn1.ASN1Boolean;
029: import org.apache.harmony.security.asn1.ASN1Exception;
030: import org.apache.harmony.security.asn1.ASN1Integer;
031: import org.apache.harmony.security.asn1.ASN1Sequence;
032: import org.apache.harmony.security.asn1.ASN1SequenceOf;
033: import org.apache.harmony.security.asn1.ASN1Type;
034: import org.apache.harmony.security.asn1.BerInputStream;
035: import org.apache.harmony.security.asn1.DerInputStream;
036: import org.apache.harmony.security.asn1.DerOutputStream;
037:
038: import junit.framework.TestCase;
039:
040: /**
041: * ASN.1 DER test for Sequence type
042: *
043: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
044: */
045:
046: public class SequenceTest extends TestCase {
047:
048: public static void main(String[] args) {
049: junit.textui.TestRunner.run(SequenceTest.class);
050: }
051:
052: private static ASN1SequenceOf sequenceOf = new ASN1SequenceOf(
053: ASN1Boolean.getInstance());
054:
055: private static ArrayList defaultList;
056:
057: private static ASN1Sequence sequence;
058:
059: private static Object[][] testcases;
060:
061: protected void setUp() throws Exception {
062: super .setUp();
063:
064: //
065: // sequence ::= SEQUENCE {
066: // boolean BOOLEAN, DEFAULT true
067: // list SEQUENCE OF BOOLEAN, DEFAULT list(false)
068: // }
069: //
070:
071: defaultList = new ArrayList();
072: defaultList.add(Boolean.FALSE);
073:
074: sequence = new ASN1Sequence(new ASN1Type[] {
075: ASN1Boolean.getInstance(), sequenceOf }) {
076: {
077: setDefault(Boolean.TRUE, 0);
078: setDefault(defaultList, 1);
079: }
080:
081: protected Object getDecodedObject(BerInputStream in)
082: throws IOException {
083: Object[] values = (Object[]) in.content;
084: return new AppClass((Boolean) values[0],
085: (List) values[1]);
086: }
087:
088: protected void getValues(Object object, Object[] values) {
089: AppClass obj = (AppClass) object;
090:
091: values[0] = obj.ok;
092: values[1] = obj.list;
093: }
094: };
095:
096: //
097: // Test Cases
098: //
099:
100: testcases = new Object[][] {
101: // format: object to encode / byte array
102:
103: // sequence : all values are default
104: { new AppClass(Boolean.TRUE, defaultList),
105: new byte[] { 0x30, 0x00 } },
106:
107: // sequence : true, default
108: { new AppClass(Boolean.FALSE, defaultList),
109: new byte[] { 0x30, 0x03, 0x01, 0x01, 0x00 } },
110:
111: // sequence = default, empty sequence
112: { new AppClass(Boolean.TRUE, new ArrayList()),
113: new byte[] { 0x30, 0x02, 0x30, 0x00 } },
114:
115: // sequence = false, empty sequence
116: {
117: new AppClass(Boolean.FALSE, new ArrayList()),
118: new byte[] { 0x30, 0x05, 0x01, 0x01, 0x00,
119: 0x30, 0x00 } },
120:
121: //TODO add testcase for another ASN.1 type`
122:
123: };
124: }
125:
126: //
127: // Application class
128: //
129:
130: public static class AppClass {
131:
132: public Boolean ok;
133:
134: public List list;
135:
136: public AppClass(Boolean ok, List list) {
137: this .ok = ok;
138: this .list = list;
139: }
140:
141: public boolean equals(Object o) {
142: if (o instanceof AppClass) {
143: AppClass obj = (AppClass) o;
144: return ok.equals(obj.ok) && list.equals(obj.list);
145: }
146: return false;
147: }
148: }
149:
150: public void testDecode_Valid() throws IOException {
151:
152: for (int i = 0; i < testcases.length; i++) {
153: try {
154: DerInputStream in = new DerInputStream(
155: (byte[]) testcases[i][1]);
156: assertEquals("Test case: " + i, testcases[i][0],
157: sequence.decode(in));
158: } catch (ASN1Exception e) {
159: fail("Test case: " + i + "\n" + e.getMessage());
160: }
161: }
162: }
163:
164: //FIXME need testcase for decoding invalid encodings
165:
166: public void testEncode() throws IOException {
167:
168: for (int i = 0; i < testcases.length; i++) {
169: DerOutputStream out = new DerOutputStream(sequence,
170: testcases[i][0]);
171: assertTrue("Test case: " + i, Arrays.equals(
172: (byte[]) testcases[i][1], out.encoded));
173: }
174: }
175:
176: public void testVerify() throws IOException {
177:
178: ASN1Sequence seqVerify = new ASN1Sequence(new ASN1Type[] {
179: ASN1Boolean.getInstance(), sequenceOf }) {
180: {
181: setDefault(Boolean.TRUE, 0);
182: setDefault(defaultList, 1);
183: }
184:
185: protected Object getDecodedObject(BerInputStream in)
186: throws IOException {
187: throw new IOException(
188: "Method getDecodedObject MUST not be invoked");
189: }
190: };
191:
192: for (int i = 0; i < testcases.length; i++) {
193: DerInputStream in = new DerInputStream(
194: (byte[]) testcases[i][1]);
195: in.setVerify();
196: seqVerify.decode(in);
197: }
198: }
199:
200: /**
201: * Tests encoding default fields
202: */
203: public void testEncodeDefault() throws IOException {
204:
205: //
206: // Boolean as default
207: //
208: ASN1Sequence s = new ASN1Sequence(new ASN1Type[] { ASN1Boolean
209: .getInstance() }) {
210: {
211: setDefault(Boolean.TRUE, 0);
212: }
213:
214: protected void getValues(Object object, Object[] values) {
215: values = (Object[]) object;
216: }
217: };
218:
219: byte[] expectedArray = new byte[] { 0x30, 0x00 };
220:
221: byte[] encoded = s.encode(new Object[] { Boolean.TRUE });
222: assertTrue("Encoded boolean:", Arrays.equals(expectedArray,
223: encoded));
224:
225: //
226: // Integer as default
227: //
228: s = new ASN1Sequence(
229: new ASN1Type[] { ASN1Integer.getInstance() }) {
230: {
231: setDefault(new byte[] { 0x01 }, 0);
232: }
233:
234: protected void getValues(Object object, Object[] values) {
235: values = (Object[]) object;
236: }
237: };
238:
239: encoded = s.encode(new Object[] { new byte[] { 0x01 } });
240: assertTrue("Encoded integer:", Arrays.equals(expectedArray,
241: encoded));
242: }
243:
244: /**
245: * Tests encoding optional fields
246: */
247: public void testEncodeOptional() throws IOException {
248:
249: //
250: // Test not optional
251: //
252: ASN1Sequence s = new ASN1Sequence(new ASN1Type[] { ASN1Boolean
253: .getInstance() }) {
254:
255: protected void getValues(Object object, Object[] values) {
256: values[0] = ((Object[]) object)[0];
257: }
258: };
259:
260: try {
261: s.encode(new Object[] { null });
262: fail("No expected RuntimeException");
263: } catch (RuntimeException e) {
264: }
265:
266: //
267: // Test optional
268: //
269: s = new ASN1Sequence(
270: new ASN1Type[] { ASN1Boolean.getInstance() }) {
271: {
272: setOptional(0);
273: }
274:
275: protected void getValues(Object object, Object[] values) {
276: values[0] = ((Object[]) object)[0];
277: }
278: };
279:
280: byte[] expectedArray = new byte[] { 0x30, 0x00 };
281:
282: byte[] encoded = s.encode(new Object[] { null });
283: assertTrue("Encoded boolean:", Arrays.equals(expectedArray,
284: encoded));
285: }
286: }
|