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 Alexander V. Esin
020: * @version $Revision$
021: */package org.ietf.jgss;
022:
023: import java.io.ByteArrayInputStream;
024: import java.util.Arrays;
025:
026: import junit.framework.TestCase;
027:
028: /**
029: * Tests Oid class
030: *
031: * ASN.1 encodings and string values are base on X.690 specification.
032: *
033: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
034: */
035: public class OidTest extends TestCase {
036:
037: /**
038: * Testing: Constructors, toString(), equals(), getDER()
039: */
040: public void testValidOid() {
041: Object[][] testcase = new Object[][] {
042: //
043: new Object[] { "0.0.3",
044: new byte[] { 0x06, 0x02, 0x00, 0x03 } },
045: //
046: new Object[] { "0.1.3",
047: new byte[] { 0x06, 0x02, 0x01, 0x03 } },
048: //
049: new Object[] { "0.39.3",
050: new byte[] { 0x06, 0x02, 0x27, 0x03 } },
051: //
052: new Object[] { "1.0.3",
053: new byte[] { 0x06, 0x02, 0x28, 0x03 } },
054: //
055: new Object[] {
056: "1.2.1.2.1",
057: new byte[] { 0x06, 0x04, 0x2A, 0x01, 0x02, 0x01 } },
058: //
059: new Object[] { "1.39.3",
060: new byte[] { 0x06, 0x02, 0x4F, 0x03 } },
061: //
062: new Object[] { "2.0.3",
063: new byte[] { 0x06, 0x02, 0x50, 0x03 } },
064: //
065: new Object[] { "2.5.4.3",
066: new byte[] { 0x06, 0x03, 0x55, 0x04, 0x03 } },
067: //
068: new Object[] { "2.39.3",
069: new byte[] { 0x06, 0x02, 0x77, 0x03 } },
070: //
071: //FIXME new Object[]{"2.40.3", new byte[]{0x06, 0x02, 0x78, 0x03}},
072: //
073: //FIXME new Object[]{"2.100.3", new byte[]{0x06, 0x03, (byte)0x81, 0x34,0x03}},
074: //
075: new Object[] {
076: "1.2.840.113554.1.2.2",
077: new byte[] { 0x06, 0x09, 0x2A, (byte) 0x86,
078: 0x48, (byte) 0x86, (byte) 0xF7, 0x12,
079: 0x01, 0x02, 0x02 } } };
080:
081: for (int i = 0; i < testcase.length; i++) {
082:
083: String strOid = (String) testcase[i][0];
084: byte[] enc = (byte[]) testcase[i][1];
085:
086: try {
087: Oid oid1 = new Oid(strOid);
088: Oid oid2 = new Oid(enc);
089: Oid oid3 = new Oid(new ByteArrayInputStream(enc));
090:
091: // test equals
092: assertEquals(oid1, oid2);
093: assertEquals(oid1, oid3);
094: assertEquals(oid2, oid3);
095:
096: // test toString()
097: assertEquals(oid1.toString(), strOid);
098: assertEquals(oid2.toString(), strOid);
099: assertEquals(oid3.toString(), strOid);
100:
101: // test getDer
102: assertTrue(Arrays.equals(enc, oid1.getDER()));
103: assertTrue(Arrays.equals(enc, oid2.getDER()));
104: assertTrue(Arrays.equals(enc, oid3.getDER()));
105:
106: } catch (GSSException e) {
107: fail("Testcase: " + i + "\nUnexpected exception: " + e);
108: }
109: }
110: }
111:
112: /**
113: * @tests org.ieft.jgss.Oid#containedIn(org.ieft.jgss.Oid[])
114: */
115: public void testContainedIn() throws Exception {
116: Oid oid = new Oid("1.2.1.2.1");
117: Oid[] oidArr = new Oid[] { new Oid("1.1.1.2.1"),
118: new Oid("1.2.2.2.1"), new Oid("1.2.1.2.1"), //right
119: new Oid("1.2.1.2.5") };
120: assertTrue(oid.containedIn(oidArr));
121:
122: try {
123: oid.containedIn(null);
124: fail("No expected NullPointerException");
125: } catch (NullPointerException e) {
126: }
127: }
128:
129: /**
130: * Oid constructor Oid(String oid) is tested in case when
131: * string oid contains a subidentifier with leading zero
132: */
133: public void testLeadingZero() throws Exception {
134: Oid oid1 = new Oid("1.0.0.0.1");
135: Oid oid2 = new Oid("01.0.0.0.1"); // subidentifier has leading 0
136: Oid oid3 = new Oid("1.0.0.0.01"); // subidentifier has leading 0
137:
138: // testing equality
139: assertEquals(oid1, oid2);
140: assertEquals(oid1, oid3);
141:
142: // testing hash code
143: assertEquals(oid1.hashCode(), oid2.hashCode());
144: assertEquals(oid1.hashCode(), oid3.hashCode());
145: }
146:
147: /**
148: * Oid constructor Oid(String oid) is tested in case when
149: * an invalid oid string is passed as a parameter
150: */
151: public void testInvalidOIDString() {
152:
153: String[] testcase = new String[] { "", // empty string
154: "1", // only one subidentifier
155: "SOME WRONG DATA", // char string
156: "0.40.3", // second subidentifier > 40 when first subidentifier = 0
157: "1.40.3", // second subidentifier > 40 when first subidentifier = 1
158: "3.2.1", // first subidentifier > 2
159: "2.2,1", // ',' is a delimiter
160: "2..2.1", // double dot
161: "2.2..1", // double dot
162: ".2.2", // leading dot
163: "2.2.", // trailing dot
164: "A.2.1", // leading char 'A'
165: "2.2.A", // trailing char 'A'
166: "OID.2.2.1", // OID prefix
167: "oid.2.2.1", // oid prefix
168: "-2.2.1", // negative first subidentifier
169: "2.-2.1", // negative second subidentifier
170: "2.2.-1", // negative third subidentifier
171: };
172:
173: for (int i = 0; i < testcase.length; i++) {
174: try {
175: new Oid(testcase[i]);
176: fail("No expected GSSException for oid string: "
177: + testcase[i]);
178: } catch (GSSException e) {
179: assertEquals(GSSException.FAILURE, e.getMajor());
180: assertEquals(0, e.getMinor());
181: }
182: }
183: }
184:
185: /**
186: * Oid constructors Oid(byte[] oid) and Oid(InputStream oid)
187: * are tested in case when an invalid oid encoding is passed as a parameter
188: */
189: public void testInvalidOIDEncodings() {
190:
191: byte[][] testcase = new byte[][] {
192: // incorrect tag: MUST be 0x06
193: new byte[] { 0x05, 0x03, 0x55, 0x04, 0x03 },
194: // incorrect length: MUST be 0x03
195: new byte[] { 0x06, 0x07, 0x55, 0x04, 0x03 },
196: // incorrect length=0
197: // FIXME new byte[] { 0x06, 0x00 },
198: // incorrect last subidentifier(last octet): 8th bit is not 0
199: new byte[] { 0x06, 0x03, 0x55, 0x04, (byte) 0x83 } };
200:
201: // Testing: Oid(byte[] oid)
202: for (int i = 0; i < testcase.length; i++) {
203: try {
204: new Oid(testcase[i]);
205: fail("Byte array: no expected GSSException for testcase: "
206: + i);
207: } catch (GSSException e) {
208: assertEquals(GSSException.FAILURE, e.getMajor());
209: assertEquals(0, e.getMinor());
210: }
211: }
212:
213: // Testing: Oid(InputStream oid)
214: for (int i = 0; i < testcase.length; i++) {
215: try {
216: ByteArrayInputStream in = new ByteArrayInputStream(
217: testcase[i]);
218: new Oid(in);
219: fail("Input stream: no expected GSSException for testcase: "
220: + i);
221: } catch (GSSException e) {
222: assertEquals(GSSException.FAILURE, e.getMajor());
223: assertEquals(0, e.getMinor());
224: }
225: }
226: }
227:
228: /**
229: * Tests 2 cases of Encoding Rules violation.
230: * Both cases should be in testInvalidOIDEncodings().
231: */
232: public void testEncodingRulesViolation() throws Exception {
233:
234: // incorrect last subidentifier: leading octet have value 0x80
235: byte[] case1 = new byte[] { 0x06, 0x04, 0x55, 0x04,
236: (byte) 0x80, 0x03 };
237: // incorrect length: encoded not in minimum number of octets
238: byte[] case2 = new byte[] { 0x06, (byte) 0x84, 0x00, 0x00,
239: 0x00, 0x03, 0x55, 0x04, 0x03 };
240:
241: assertEquals("2.5.4.3", new Oid(case1).toString());
242: assertEquals("2.5.4.3", new Oid(case2).toString());
243: }
244:
245: public void testImmutability() throws Exception {
246:
247: byte[] encoding = new byte[] { 0x06, 0x03, 0x55, 0x04, 0x03 };
248:
249: Oid oid = new Oid(encoding);
250:
251: byte[] enc1 = oid.getDER();
252: byte[] enc2 = oid.getDER();
253:
254: assertTrue(enc1 != encoding);
255: assertTrue(enc1 != enc2);
256: }
257:
258: /**
259: * Oid encoding contains 2 extra bytes.
260: * Two Oid constructors are verified:
261: * - Oid(byte[] oid): GSSException is thrown
262: * - Oid(InputStream oid): oid object is created,
263: * input stream contains extra bytes
264: */
265: public void testExtraBytes() throws Exception {
266: byte[] encoding = new byte[] { 0x06, 0x01, 0x55, 0x04, 0x03 };
267:
268: try {
269: new Oid(encoding);
270: fail("No expected GSSException");
271: } catch (GSSException e) {
272: assertEquals(GSSException.FAILURE, e.getMajor());
273: assertEquals(0, e.getMinor());
274: }
275:
276: ByteArrayInputStream in = new ByteArrayInputStream(encoding);
277: Oid oid = new Oid(in);
278:
279: assertEquals("2.5", oid.toString());
280:
281: assertEquals(0x04, in.read());
282: assertEquals(0x03, in.read());
283: assertEquals(0, in.available());
284: }
285:
286: /**
287: * @tests org.ieft.jgss.Oid#Oid(byte[])
288: */
289: public final void test_ConstructorLbyte_array() throws GSSException {
290:
291: try {
292: new Oid((byte[]) null);
293: fail("No expected NullPointerException");
294: } catch (NullPointerException e) {
295: }
296: }
297:
298: /**
299: * @tests org.ieft.jgss.Oid#Oid(java.io.InputStream)
300: */
301: public final void test_ConstructorLjava_io_InputStream()
302: throws GSSException {
303:
304: try {
305: new Oid((java.io.InputStream) null);
306: fail("No expected NullPointerException");
307: } catch (NullPointerException e) {
308: }
309: }
310:
311: /**
312: * @tests org.ieft.jgss.Oid#Oid(java.lang.String)
313: */
314: public final void test_ConstructorLjava_lang_String() {
315:
316: try {
317: new Oid((java.lang.String) null);
318: fail("No expected GSSException");
319: } catch (GSSException e) {
320: }
321: }
322:
323: public void test_KerberosV5() throws Exception {
324: Oid oid = new Oid("1.2.840.113554.1.2.2");
325: byte[] expectedDer = new byte[] { 6, 9, 42, -122, 72, -122, -9,
326: 18, 1, 2, 2 };
327: assertTrue(Arrays.equals(expectedDer, oid.getDER()));
328: }
329: }
|