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:
027: import junit.framework.TestCase;
028:
029: import org.apache.harmony.security.asn1.ASN1Boolean;
030: import org.apache.harmony.security.asn1.ASN1Constants;
031: import org.apache.harmony.security.asn1.ASN1Exception;
032: import org.apache.harmony.security.asn1.ASN1Implicit;
033: import org.apache.harmony.security.asn1.ASN1OctetString;
034: import org.apache.harmony.security.asn1.ASN1SequenceOf;
035: import org.apache.harmony.security.asn1.ASN1Type;
036: import org.apache.harmony.security.asn1.DerInputStream;
037: import org.apache.harmony.security.asn1.DerOutputStream;
038:
039: /**
040: * ASN.1 DER test for Implicitly tagged type
041: *
042: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
043: */
044:
045: public class ImplicitTest extends TestCase {
046:
047: public static void main(String[] args) {
048: junit.textui.TestRunner.run(ImplicitTest.class);
049: }
050:
051: private static ASN1SequenceOf sequence = new ASN1SequenceOf(
052: ASN1Boolean.getInstance());
053:
054: private static Object[][] taggedType = {
055: // format: object to encode / ASN.1 tagged type / byte array
056:
057: //
058: // Boolean = false
059: //
060:
061: // [UNIVERSAL 5] Boolean
062: {
063: Boolean.FALSE,
064: new byte[] { 0x05, 0x01, 0x00 },
065: new ASN1Implicit(ASN1Constants.CLASS_UNIVERSAL, 5,
066: ASN1Boolean.getInstance()) },
067:
068: // [APPLICATION 5] Boolean
069: {
070: Boolean.FALSE,
071: new byte[] { 0x45, 0x01, 0x00 },
072: new ASN1Implicit(ASN1Constants.CLASS_APPLICATION,
073: 5, ASN1Boolean.getInstance()) },
074:
075: // [CONTEXT-SPECIFIC 5] Boolean
076: {
077: Boolean.FALSE,
078: new byte[] { (byte) 0x85, 0x01, 0x00 },
079: new ASN1Implicit(
080: ASN1Constants.CLASS_CONTEXTSPECIFIC, 5,
081: ASN1Boolean.getInstance()) },
082:
083: // [5] Boolean (default = CONTEXT-SPECIFIC)
084: { Boolean.FALSE, new byte[] { (byte) 0x85, 0x01, 0x00 },
085: new ASN1Implicit(5, ASN1Boolean.getInstance()) },
086:
087: // [PRIVATE 5] Boolean
088: {
089: Boolean.FALSE,
090: new byte[] { (byte) 0xC5, 0x01, 0x00 },
091: new ASN1Implicit(ASN1Constants.CLASS_PRIVATE, 5,
092: ASN1Boolean.getInstance()) },
093:
094: //
095: // Boolean = true
096: //
097:
098: // [UNIVERSAL 5] Boolean
099: {
100: Boolean.TRUE,
101: new byte[] { 0x05, 0x01, (byte) 0xFF },
102: new ASN1Implicit(ASN1Constants.CLASS_UNIVERSAL, 5,
103: ASN1Boolean.getInstance()) },
104:
105: // [APPLICATION 5] Boolean
106: {
107: Boolean.TRUE,
108: new byte[] { 0x45, 0x01, (byte) 0xFF },
109: new ASN1Implicit(ASN1Constants.CLASS_APPLICATION,
110: 5, ASN1Boolean.getInstance()) },
111:
112: // [CONTEXT-SPECIFIC 5] Boolean
113: {
114: Boolean.TRUE,
115: new byte[] { (byte) 0x85, 0x01, (byte) 0xFF },
116: new ASN1Implicit(
117: ASN1Constants.CLASS_CONTEXTSPECIFIC, 5,
118: ASN1Boolean.getInstance()) },
119:
120: // [5] Boolean (default = CONTEXT-SPECIFIC)
121: {
122: Boolean.TRUE,
123: new byte[] { (byte) 0x85, 0x01, (byte) 0xFF },
124: new ASN1Implicit(
125: ASN1Constants.CLASS_CONTEXTSPECIFIC, 5,
126: ASN1Boolean.getInstance()) },
127:
128: // [PRIVATE 5] Boolean
129: {
130: Boolean.TRUE,
131: new byte[] { (byte) 0xC5, 0x01, (byte) 0xFF },
132: new ASN1Implicit(ASN1Constants.CLASS_PRIVATE, 5,
133: ASN1Boolean.getInstance()) },
134: //
135: // SequenceOf - testing constructed ASN.1 type
136: //
137:
138: // [UNIVERSAL 5] SequenceOf
139: {
140: new ArrayList(),
141: new byte[] { 0x25, 0x00 },
142: new ASN1Implicit(ASN1Constants.CLASS_UNIVERSAL, 5,
143: sequence) },
144:
145: // [APPLICATION 5] SequenceOf
146: {
147: new ArrayList(),
148: new byte[] { 0x65, 0x00 },
149: new ASN1Implicit(ASN1Constants.CLASS_APPLICATION,
150: 5, sequence) },
151:
152: // [CONTEXT-SPECIFIC 5] SequenceOf
153: {
154: new ArrayList(),
155: new byte[] { (byte) 0xA5, 0x00 },
156: new ASN1Implicit(
157: ASN1Constants.CLASS_CONTEXTSPECIFIC, 5,
158: sequence) },
159:
160: // [5] SequenceOf (default = CONTEXT-SPECIFIC)
161: {
162: new ArrayList(),
163: new byte[] { (byte) 0xA5, 0x00 },
164: new ASN1Implicit(
165: ASN1Constants.CLASS_CONTEXTSPECIFIC, 5,
166: sequence) },
167:
168: // [PRIVATE 5] SequenceOf
169: {
170: new ArrayList(),
171: new byte[] { (byte) 0xE5, 0x00 },
172: new ASN1Implicit(ASN1Constants.CLASS_PRIVATE, 5,
173: sequence) } };
174:
175: public void testDecode_Valid() throws IOException {
176:
177: for (int i = 0; i < taggedType.length; i++) {
178: DerInputStream in = new DerInputStream(
179: (byte[]) taggedType[i][1]);
180: assertEquals("Test case: " + i, taggedType[i][0],
181: ((ASN1Type) taggedType[i][2]).decode(in));
182: }
183: }
184:
185: // FIXME need testcase for decoding invalid encodings
186:
187: public void testEncode() throws IOException {
188:
189: for (int i = 0; i < taggedType.length; i++) {
190: DerOutputStream out = new DerOutputStream(
191: (ASN1Type) taggedType[i][2], taggedType[i][0]);
192: assertTrue("Test case: " + i, Arrays.equals(
193: (byte[]) taggedType[i][1], out.encoded));
194: }
195: }
196:
197: /**
198: * Tests 2 consecutive implicit string type tagging
199: *
200: * TYPE1 = [1] IMPLICIT OCTET STRING
201: * TYPE2 = [2] IMPLICIT TYPE1
202: */
203: public void testConsecutiveStringTagging() throws Exception {
204: ASN1Implicit type1 = new ASN1Implicit(1, ASN1OctetString
205: .getInstance());
206:
207: ASN1Implicit type2 = new ASN1Implicit(2, type1);
208:
209: byte[] primitiveEncoding = new byte[] {
210: // tag: class(CONTEXT SPECIFIC) + number (2)
211: (byte) 0x82,
212: // length
213: 0x03,
214: // value
215: 0x00, 0x01, 0x02 };
216:
217: byte[] constructedEncoding = new byte[] {
218: // tag: class(CONTEXT SPECIFIC) + constructed +number (2)
219: (byte) 0xA2,
220: // length
221: 0x00 };
222:
223: byte[] array = new byte[] { 0x00, 0x01, 0x02 };
224:
225: // decode primitive
226: assertTrue(Arrays.equals(array, (byte[]) type2
227: .decode(primitiveEncoding)));
228:
229: // encode primitive
230: assertTrue(Arrays
231: .equals(primitiveEncoding, type2.encode(array)));
232:
233: // decode constructed
234: try {
235: type2.decode(constructedEncoding);
236: fail("No expected ASN1Exception");
237: } catch (ASN1Exception e) {
238: // FIXME any other check instead of comparing the message???
239: assertEquals(
240: "ASN.1 octetstring: constructed identifier at [0]. Not valid for DER.",
241: e.getMessage());
242: }
243: }
244: }
|