Home | History | Annotate | Download | only in jgss
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 /**
     19 * @author Alexander V. Esin
     20 */
     21 package org.ietf.jgss;
     22 
     23 import java.io.ByteArrayInputStream;
     24 import java.util.Arrays;
     25 
     26 import junit.framework.TestCase;
     27 
     28 /**
     29  * Tests Oid class
     30  *
     31  * ASN.1 encodings and string values are base on X.690 specification.
     32  *
     33  * @see http://asn1.elibel.tm.fr/en/standards/index.htm
     34  */
     35 public class OidTest extends TestCase {
     36 
     37     /**
     38      * Testing: Constructors, toString(), equals(), getDER()
     39      */
     40     public void testValidOid() {
     41         Object[][] testcase = new Object[][] {
     42                 //
     43                 new Object[] { "0.0.3", new byte[] { 0x06, 0x02, 0x00, 0x03 } },
     44                 //
     45                 new Object[] { "0.1.3", new byte[] { 0x06, 0x02, 0x01, 0x03 } },
     46                 //
     47                 new Object[] { "0.39.3", new byte[] { 0x06, 0x02, 0x27, 0x03 } },
     48                 //
     49                 new Object[] { "1.0.3", new byte[] { 0x06, 0x02, 0x28, 0x03 } },
     50                 //
     51                 new Object[] { "1.2.1.2.1",
     52                         new byte[] { 0x06, 0x04, 0x2A, 0x01, 0x02, 0x01 } },
     53                 //
     54                 new Object[] { "1.39.3", new byte[] { 0x06, 0x02, 0x4F, 0x03 } },
     55                 //
     56                 new Object[] { "2.0.3", new byte[] { 0x06, 0x02, 0x50, 0x03 } },
     57                 //
     58                 new Object[] { "2.5.4.3",
     59                         new byte[] { 0x06, 0x03, 0x55, 0x04, 0x03 } },
     60                 //
     61                 new Object[] { "2.39.3", new byte[] { 0x06, 0x02, 0x77, 0x03 } },
     62                 //
     63                 //FIXME new Object[]{"2.40.3", new byte[]{0x06, 0x02, 0x78, 0x03}},
     64                 //
     65                 //FIXME new Object[]{"2.100.3", new byte[]{0x06, 0x03, (byte)0x81, 0x34,0x03}},
     66                 //
     67                 new Object[] {
     68                         "1.2.840.113554.1.2.2",
     69                         new byte[] { 0x06, 0x09, 0x2A, (byte) 0x86, 0x48,
     70                                 (byte) 0x86, (byte) 0xF7, 0x12, 0x01, 0x02,
     71                                 0x02 } } };
     72 
     73         for (int i = 0; i < testcase.length; i++) {
     74 
     75             String strOid = (String) testcase[i][0];
     76             byte[] enc = (byte[]) testcase[i][1];
     77 
     78             try {
     79                 Oid oid1 = new Oid(strOid);
     80                 Oid oid2 = new Oid(enc);
     81                 Oid oid3 = new Oid(new ByteArrayInputStream(enc));
     82 
     83                 // test equals
     84                 assertEquals(oid1, oid2);
     85                 assertEquals(oid1, oid3);
     86                 assertEquals(oid2, oid3);
     87 
     88                 // test toString()
     89                 assertEquals(oid1.toString(), strOid);
     90                 assertEquals(oid2.toString(), strOid);
     91                 assertEquals(oid3.toString(), strOid);
     92 
     93                 // test getDer
     94                 assertTrue(Arrays.equals(enc, oid1.getDER()));
     95                 assertTrue(Arrays.equals(enc, oid2.getDER()));
     96                 assertTrue(Arrays.equals(enc, oid3.getDER()));
     97 
     98             } catch (GSSException e) {
     99                 fail("Testcase: " + i + "\nUnexpected exception: " + e);
    100             }
    101         }
    102     }
    103 
    104     /**
    105      * @tests org.ieft.jgss.Oid#containedIn(org.ieft.jgss.Oid[])
    106      */
    107     public void testContainedIn() throws Exception {
    108         Oid oid= new Oid("1.2.1.2.1");
    109         Oid [] oidArr= new Oid [] {
    110                 new Oid("1.1.1.2.1"),
    111                 new Oid("1.2.2.2.1"),
    112                 new Oid("1.2.1.2.1"), //right
    113                 new Oid("1.2.1.2.5")
    114                 };
    115         assertTrue(oid.containedIn(oidArr) );
    116 
    117         try {
    118             oid.containedIn(null);
    119             fail("No expected NullPointerException");
    120         } catch (NullPointerException e) {
    121         }
    122     }
    123 
    124     /**
    125      * Oid constructor Oid(String oid) is tested in case when
    126      * string oid contains a subidentifier with leading zero
    127      */
    128     public void testLeadingZero() throws Exception {
    129         Oid oid1 = new Oid("1.0.0.0.1");
    130         Oid oid2 = new Oid("01.0.0.0.1"); // subidentifier has leading 0
    131         Oid oid3 = new Oid("1.0.0.0.01"); // subidentifier has leading 0
    132 
    133         // testing equality
    134         assertEquals(oid1, oid2);
    135         assertEquals(oid1, oid3);
    136 
    137         // testing hash code
    138         assertEquals(oid1.hashCode(), oid2.hashCode());
    139         assertEquals(oid1.hashCode(), oid3.hashCode());
    140     }
    141 
    142     /**
    143      * Oid constructor Oid(String oid) is tested in case when
    144      * an invalid oid string is passed as a parameter
    145      */
    146     public void testInvalidOIDString() {
    147 
    148         String[] testcase = new String[] { "", // empty string
    149                 "1", // only one subidentifier
    150                 "SOME WRONG DATA", // char string
    151                 "0.40.3", // second subidentifier > 40 when first subidentifier = 0
    152                 "1.40.3", // second subidentifier > 40 when first subidentifier = 1
    153                 "3.2.1", // first subidentifier > 2
    154                 "2.2,1", // ',' is a delimiter
    155                 "2..2.1", // double dot
    156                 "2.2..1", // double dot
    157                 ".2.2", // leading dot
    158                 "2.2.", // trailing dot
    159                 "A.2.1", // leading char 'A'
    160                 "2.2.A", // trailing char 'A'
    161                 "OID.2.2.1", // OID prefix
    162                 "oid.2.2.1", // oid prefix
    163                 "-2.2.1", // negative first subidentifier
    164                 "2.-2.1", // negative second subidentifier
    165                 "2.2.-1", // negative third subidentifier
    166         };
    167 
    168         for (int i = 0; i < testcase.length; i++) {
    169             try {
    170                 new Oid(testcase[i]);
    171                 fail("No expected GSSException for oid string: " + testcase[i]);
    172             } catch (GSSException e) {
    173                 assertEquals(GSSException.FAILURE, e.getMajor());
    174                 assertEquals(0, e.getMinor());
    175             }
    176         }
    177     }
    178 
    179     /**
    180      * Oid constructors Oid(byte[] oid) and Oid(InputStream oid)
    181      * are tested in case when an invalid oid encoding is passed as a parameter
    182      */
    183     public void testInvalidOIDEncodings() {
    184 
    185         byte[][] testcase = new byte[][] {
    186         // incorrect tag: MUST be 0x06
    187                 new byte[] { 0x05, 0x03, 0x55, 0x04, 0x03 },
    188                 // incorrect length: MUST be 0x03
    189                 new byte[] { 0x06, 0x07, 0x55, 0x04, 0x03 },
    190                 // incorrect length=0
    191                 // FIXME new byte[] { 0x06, 0x00 },
    192                 // incorrect last subidentifier(last octet): 8th bit is not 0
    193                 new byte[] { 0x06, 0x03, 0x55, 0x04, (byte) 0x83 }
    194         };
    195 
    196         // Testing: Oid(byte[] oid)
    197         for (int i = 0; i < testcase.length; i++) {
    198             try {
    199                 new Oid(testcase[i]);
    200                 fail("Byte array: no expected GSSException for testcase: " + i);
    201             } catch (GSSException e) {
    202                 assertEquals(GSSException.FAILURE, e.getMajor());
    203                 assertEquals(0, e.getMinor());
    204             }
    205         }
    206 
    207         // Testing: Oid(InputStream oid)
    208         for (int i = 0; i < testcase.length; i++) {
    209             try {
    210                 ByteArrayInputStream in = new ByteArrayInputStream(testcase[i]);
    211                 new Oid(in);
    212                 fail("Input stream: no expected GSSException for testcase: "
    213                         + i);
    214             } catch (GSSException e) {
    215                 assertEquals(GSSException.FAILURE, e.getMajor());
    216                 assertEquals(0, e.getMinor());
    217             }
    218         }
    219     }
    220 
    221     /**
    222      * Tests 2 cases of Encoding Rules violation.
    223      * Both cases should be in testInvalidOIDEncodings().
    224      */
    225     public void testEncodingRulesViolation() throws Exception {
    226 
    227         // incorrect last subidentifier: leading octet have value 0x80
    228         byte[] case1 = new byte[] { 0x06, 0x04, 0x55, 0x04, (byte) 0x80, 0x03 };
    229         // incorrect length: encoded not in minimum number of octets
    230         byte[] case2 = new byte[] { 0x06, (byte) 0x84, 0x00, 0x00, 0x00, 0x03,
    231                 0x55, 0x04, 0x03 };
    232 
    233         assertEquals("2.5.4.3", new Oid(case1).toString());
    234         assertEquals("2.5.4.3", new Oid(case2).toString());
    235     }
    236 
    237     public void testImmutability() throws Exception {
    238 
    239         byte[] encoding = new byte[] { 0x06, 0x03, 0x55, 0x04, 0x03 };
    240 
    241         Oid oid = new Oid(encoding);
    242 
    243         byte[] enc1 = oid.getDER();
    244         byte[] enc2 = oid.getDER();
    245 
    246         assertTrue(enc1 != encoding);
    247         assertTrue(enc1 != enc2);
    248     }
    249 
    250 
    251     /**
    252      * Oid encoding contains 2 extra bytes.
    253      * Two Oid constructors are verified:
    254      *     - Oid(byte[] oid): GSSException is thrown
    255      *     - Oid(InputStream oid): oid object is created,
    256      *                             input stream contains extra bytes
    257      */
    258     public void testExtraBytes() throws Exception {
    259         byte[] encoding = new byte[] { 0x06, 0x01, 0x55, 0x04, 0x03 };
    260 
    261         try {
    262             new Oid(encoding);
    263             fail("No expected GSSException");
    264         } catch (GSSException e) {
    265             assertEquals(GSSException.FAILURE, e.getMajor());
    266             assertEquals(0, e.getMinor());
    267         }
    268 
    269         ByteArrayInputStream in = new ByteArrayInputStream(encoding);
    270         Oid oid = new Oid(in);
    271 
    272         assertEquals("2.5", oid.toString());
    273 
    274         assertEquals(0x04, in.read());
    275         assertEquals(0x03, in.read());
    276         assertEquals(0, in.available());
    277     }
    278 
    279     /**
    280      * @tests org.ieft.jgss.Oid#Oid(byte[])
    281      */
    282     public final void test_ConstructorLbyte_array() throws GSSException {
    283 
    284         try {
    285             new Oid((byte[]) null);
    286             fail("No expected NullPointerException");
    287         } catch (NullPointerException e) {
    288         }
    289     }
    290 
    291     /**
    292      * @tests org.ieft.jgss.Oid#Oid(java.io.InputStream)
    293      */
    294     public final void test_ConstructorLjava_io_InputStream()
    295             throws GSSException {
    296 
    297         try {
    298             new Oid((java.io.InputStream) null);
    299             fail("No expected NullPointerException");
    300         } catch (NullPointerException e) {
    301         }
    302     }
    303 
    304     /**
    305      * @tests org.ieft.jgss.Oid#Oid(java.lang.String)
    306      */
    307     public final void test_ConstructorLjava_lang_String() {
    308 
    309         try {
    310             new Oid((java.lang.String) null);
    311             fail("No expected GSSException");
    312         } catch (GSSException e) {
    313         }
    314     }
    315 
    316     public void test_KerberosV5() throws Exception {
    317         Oid oid = new Oid("1.2.840.113554.1.2.2");
    318         byte[] expectedDer = new byte[] { 6, 9, 42, -122, 72, -122, -9, 18, 1,
    319                 2, 2 };
    320         assertTrue(Arrays.equals(expectedDer, oid.getDER()));
    321     }
    322 }
    323