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
22package javax.security.auth.x500;
23
24import java.io.ByteArrayInputStream;
25import java.io.InputStream;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.Locale;
29
30import junit.framework.TestCase;
31import tests.support.resource.Support_Resources;
32
33/**
34 * Tests X500Principal class
35 *
36 * Distinguished name(DN) strings follows
37 * BNF syntax specified in RFC 2253 and RFC 1779
38 *
39 * @see http://www.ietf.org/rfc/rfc2253.txt
40 * @see http://www.ietf.org/rfc/rfc1779.txt
41 * @see http://asn1.elibel.tm.fr/en/standards/index.htm
42 */
43
44public class X500PrincipalTest extends TestCase {
45
46    private boolean testing = false;
47
48    public void testStreamPosition() throws Exception {
49        //this encoding is read from the file
50        /*byte [] mess = {0x30, 0x30,
51         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
52         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
53         1, 2, 3//extra bytes
54         };
55         */
56
57        InputStream is = Support_Resources
58                .getResourceStream("X500PrincipalTest.0.dat");
59        X500Principal principal = new X500Principal(is);
60        String s = principal.toString();
61        assertEquals("CN=A, CN=B, CN=A, CN=B", s);
62        byte[] restBytes = new byte[] { 0, 0, 0 };
63        is.read(restBytes);
64        assertEquals(restBytes[0], 1);
65        assertEquals(restBytes[1], 2);
66        assertEquals(restBytes[2], 3);
67        is.close();
68    }
69
70    public void testStreamPosition_0() throws Exception {
71        //this encoding is read from the file
72        /*byte [] mess = {0x30, 0x30,
73         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
74         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
75         };
76         */
77
78        InputStream is = Support_Resources
79                .getResourceStream("X500PrincipalTest.1.dat");
80        X500Principal principal = new X500Principal(is);
81        String s = principal.toString();
82        assertEquals("CN=A, CN=B, CN=A, CN=B", s);
83        assertEquals(0, is.available());
84        is.close();
85    }
86
87    public void testStreamPosition_1() throws Exception {
88        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
89                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
90                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
91                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
92                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
93                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
94                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
95                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
96                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
97                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
98                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
99                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
100                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
101                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
102                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
103                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 2,
104                3, 4 };
105
106        ByteArrayInputStream is = new ByteArrayInputStream(mess);
107        X500Principal principal = new X500Principal(is);
108
109        String s = principal.getName(X500Principal.RFC1779);
110        assertEquals(
111                "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
112                s);
113        assertEquals(3, is.available());
114        assertEquals(2, is.read());
115        assertEquals(3, is.read());
116        assertEquals(4, is.read());
117    }
118
119    public void testStreamPosition_2() throws Exception {
120        byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
121                0x04, 0x03, 0x13, 0x01, 0x41, 2 };
122        ByteArrayInputStream is = new ByteArrayInputStream(mess);
123        X500Principal principal = new X500Principal(is);
124        String s = principal.getName(X500Principal.RFC1779);
125        assertEquals("CN=A", s);
126        assertEquals(1, is.available());
127        assertEquals(2, is.read());
128    }
129
130    public void testEncodingFromFile() throws Exception {
131        //this encoding is read from the file
132        /*byte [] mess = {0x30, 0x30,
133         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41,
134         0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41
135         };
136         */
137        InputStream is = Support_Resources
138                .getResourceStream("X500PrincipalTest.1.dat");
139        X500Principal principal = new X500Principal(is);
140        String s = principal.toString();
141        assertEquals("CN=A, CN=B, CN=A, CN=B", s);
142        is.close();
143    }
144
145    public void testEncodingFromEncoding() {
146        byte[] arr1 = new X500Principal("O=Org.").getEncoded();
147        byte[] arr2 = new X500Principal(new X500Principal("O=Org.")
148                .getEncoded()).getEncoded();
149        assertTrue(Arrays.equals(arr1, arr2));
150    }
151
152    /**
153     * tests if the encoding is backed
154     */
155    public void testSafeEncoding() {
156        byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
157                0x04, 0x03, 0x13, 0x01, 0x41 };
158        X500Principal principal = new X500Principal(mess);
159        mess[mess.length - 1] = (byte) 0xFF;
160        byte[] enc = principal.getEncoded();
161        assertEquals(enc[mess.length - 1], 0x41);
162    }
163
164    /**
165     * Inits X500Principal with byte array
166     * gets toString
167     * checks the result
168     */
169    public void testToString() throws Exception {
170        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
171                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
172                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
173        X500Principal principal = new X500Principal(mess);
174        String s = principal.toString();
175        assertNotNull(s);
176    }
177
178    /**
179     * Inits X500Principal with byte array
180     * gets hashCode
181     * compares with expected value
182     */
183    public void testHashCode() throws Exception {
184        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
185                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
186                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
187        X500Principal principal = new X500Principal(mess);
188        int hash = principal.hashCode();
189        assertEquals(principal.getName(X500Principal.CANONICAL).hashCode(),
190                hash);
191    }
192
193    /**
194     * Inits X500Principal with byte array
195     * Inits other X500Principal with equivalent string
196     * checks if <code>equals</code> returns true for first against second one
197     */
198    public void testEquals() throws Exception {
199        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
200                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
201                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
202        X500Principal principal = new X500Principal(mess);
203        X500Principal principal2 = new X500Principal("CN=A, CN=B");
204        assertTrue(principal.equals(principal2));
205    }
206
207    /**
208     * @tests javax.security.auth.x500.X500Principal#equals(Object)
209     */
210    public void test_equalsLjava_lang_Object() {
211        X500Principal xp1 = new X500Principal(
212                "C=US, ST=California, L=San Diego, O=Apache, OU=Project Harmony, CN=Test cert");
213        assertEquals(
214                "C=US,ST=California,L=San Diego,O=Apache,OU=Project Harmony,CN=Test cert",
215                xp1.getName());
216    }
217
218    /**
219     * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
220     * Value is given as hex value
221     * (extra spaces are given)
222     * gets Name in RFC1779 format
223     * compares with expected value of name
224     */
225    public void testKWAsOid_RFC1779() throws Exception {
226        String dn = "CN=A, OID.2.5.4.3  =    #130142";
227        X500Principal principal = new X500Principal(dn);
228
229        String s = principal.getName(X500Principal.RFC1779);
230        assertEquals("CN=A, CN=B", s);
231    }
232
233    /**
234     * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
235     * Value is given as hex value
236     * (extra spaces are given)
237     * gets Name in RFC2253 format
238     * compares with expected value of name
239     */
240    public void testKWAsOid_RFC2253() throws Exception {
241        String dn = "CN=A, OID.2.5.4.3 =  #130142";
242        X500Principal principal = new X500Principal(dn);
243
244        String s = principal.getName(X500Principal.RFC2253);
245        assertEquals("CN=A,CN=B", s);
246    }
247
248    /**
249     * Inits X500Principal with byte array, where Oid does fall into any keyword, but not given as a keyword
250     * Value is given as hex value
251     * (extra spaces are given)
252     * gets Name in CANONICAL format
253     * compares with expected value of name
254     */
255    public void testKWAsOid_CANONICAL() throws Exception {
256        String dn = "CN=A, OID.2.5.4.3 =  #130142";
257        X500Principal principal = new X500Principal(dn);
258
259        String s = principal.getName(X500Principal.CANONICAL);
260        assertEquals("cn=a,cn=b", s);
261    }
262
263    /**
264     * Inits X500Principal with byte array, where Oid does not fall into any keyword
265     * gets Name in RFC1779 format
266     * compares with expected value of name
267     */
268    public void testOid_RFC1779() throws Exception {
269        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
270                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
271                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
272        mess[8] = 0x60;
273        X500Principal principal = new X500Principal(mess);
274
275        String s = principal.getName(X500Principal.RFC1779);
276        assertEquals("CN=A, OID.2.16.4.3=B", s);
277    }
278
279    /**
280     * Inits X500Principal with byte array, where Oid does not fall into any keyword
281     * gets Name in RFC2253 format
282     * compares with expected value of name
283     */
284    public void testOid_RFC2253() throws Exception {
285        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
286                0x04, 0x03, 0x13, 0x01, 0x4F, 0x31, 0x0A, 0x30, 0x08, 0x06,
287                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
288        mess[8] = 0x60;
289        X500Principal principal = new X500Principal(mess);
290
291        String s = principal.getName(X500Principal.RFC2253);
292        assertEquals("CN=A,2.16.4.3=#13014f", s);
293    }
294
295    /**
296     * Inits X500Principal with byte array, where Oid does not fall into any keyword
297     * gets Name in CANONICAL format
298     * compares with expected value of name
299     */
300    public void testOid_CANONICAL() throws Exception {
301        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
302                0x04, 0x03, 0x13, 0x01, 0x4F, 0x31, 0x0A, 0x30, 0x08, 0x06,
303                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
304        mess[8] = 0x60;
305        X500Principal principal = new X500Principal(mess);
306
307        String s = principal.getName(X500Principal.CANONICAL);
308        assertEquals("cn=a,2.16.4.3=#13014f", s);
309    }
310
311    /**
312     * Inits X500Principal with a string
313     * gets encoded form
314     * compares with expected byte array
315     */
316    public void testNameGetEncoding() throws Exception {
317        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
318                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
319                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
320                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
321                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
322                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
323                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
324                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
325                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
326                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
327                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
328                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
329                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
330                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
331                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
332                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
333        String dn = "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z";
334        X500Principal principal = new X500Principal(dn);
335        byte[] s = principal.getEncoded();
336
337        assertTrue(Arrays.equals(mess, s));
338    }
339
340    /**
341     * Inits X500Principal with a string
342     * gets encoded form
343     * compares with expected byte array
344     */
345    public void testNameGetEncoding_01() throws Exception {
346        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
347                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
348                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
349        String dn = "CN=A,CN=B";
350        X500Principal principal = new X500Principal(dn);
351        byte[] s = principal.getEncoded();
352
353        assertTrue(Arrays.equals(mess, s));
354    }
355
356    /**
357     * Inits X500Principal with byte array
358     * gets Name in RFC1779 format
359     * compares with expected value of name
360     */
361    public void testGetName_RFC1779() throws Exception {
362        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
363                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
364                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
365                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
366                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
367                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
368                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
369                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
370                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
371                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
372                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
373                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
374                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
375                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
376                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
377                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
378        X500Principal principal = new X500Principal(mess);
379
380        String s = principal.getName(X500Principal.RFC1779);
381        assertEquals(
382                "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
383                s);
384
385    }
386
387    /**
388     * Inits X500Principal with byte array
389     * gets Name in RFC2253 format
390     * compares with expected value of name
391     */
392    public void testGetName_RFC2253() throws Exception {
393        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
394                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
395                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
396                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
397                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
398                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
399                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
400                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
401                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
402                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
403                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
404                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
405                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
406                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
407                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
408                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
409        X500Principal principal = new X500Principal(mess);
410
411        String s = principal.getName(X500Principal.RFC2253);
412        assertEquals(
413                "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z",
414                s);
415    }
416
417    /**
418     * Inits X500Principal with byte array
419     * gets Name in CANONICAL format
420     * compares with expected value of name
421     */
422    public void testGetName_CANONICAL() throws Exception {
423        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
424                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
425                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
426                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
427                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
428                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
429                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
430                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
431                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
432                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
433                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
434                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
435                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
436                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
437                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
438                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
439        X500Principal principal = new X500Principal(mess);
440
441        String s = principal.getName(X500Principal.CANONICAL);
442        assertEquals(
443                "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z"
444                        .toLowerCase(Locale.US), s);
445    }
446
447    /**
448     * Inits X500Principal with byte array
449     * gets Name in RFC1779 format
450     * compares with expected value of name
451     */
452    public void testStreamGetName_RFC1779() throws Exception {
453        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
454                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
455                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
456                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
457                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
458                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
459                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
460                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
461                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
462                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
463                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
464                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
465                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
466                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
467                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
468                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
469        ByteArrayInputStream is = new ByteArrayInputStream(mess);
470        X500Principal principal = new X500Principal(is);
471
472        String s = principal.getName(X500Principal.RFC1779);
473        assertEquals(
474                "CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=A + ST=CA, O=B, L=C, C=D, OU=E, CN=Z",
475                s);
476    }
477
478    /**
479     * Inits X500Principal with byte array
480     * gets Name in RFC2253 format
481     * compares with expected value of name
482     */
483    public void testStreamGetName_RFC2253() throws Exception {
484        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
485                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
486                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
487                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
488                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
489                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
490                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
491                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
492                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
493                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
494                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
495                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
496                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
497                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
498                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
499                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
500        ByteArrayInputStream is = new ByteArrayInputStream(mess);
501        X500Principal principal = new X500Principal(is);
502
503        String s = principal.getName(X500Principal.RFC2253);
504        assertEquals(
505                "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z",
506                s);
507    }
508
509    /**
510     * Inits X500Principal with byte array
511     * gets Name in CANONICAL format
512     * compares with expected value of name
513     */
514    public void testStreamGetName_CANONICAL() throws Exception {
515        byte[] mess = { 0x30, (byte) 0x81, (byte) 0x9A, 0x31, 0x0A, 0x30, 0x08,
516                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x5A, 0x31, 0x0A,
517                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01, 0x45,
518                0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
519                0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
520                0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
521                0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30, 0x08,
522                0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30, 0x09,
523                0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41, 0x31,
524                0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x01,
525                0x45, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x06,
526                0x13, 0x01, 0x44, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
527                0x04, 0x07, 0x13, 0x01, 0x43, 0x31, 0x0A, 0x30, 0x08, 0x06,
528                0x03, 0x55, 0x04, 0x0A, 0x13, 0x01, 0x42, 0x31, 0x15, 0x30,
529                0x08, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41, 0x30,
530                0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x43, 0x41 };
531        ByteArrayInputStream is = new ByteArrayInputStream(mess);
532        X500Principal principal = new X500Principal(is);
533
534        String s = principal.getName(X500Principal.CANONICAL);
535        assertEquals(
536                "CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=A+ST=CA,O=B,L=C,C=D,OU=E,CN=Z"
537                        .toLowerCase(Locale.US), s);
538    }
539
540    /**
541     * Inits X500Principal with a string, where OID does not fall into any keyword
542     * gets encoded form
543     * inits new X500Principal with the encoding
544     * gets string in RFC1779 format
545     * compares with expected value
546     */
547    public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_RFC1779()
548            throws Exception {
549        String dn = "OID.2.16.4.3=B; CN=A";
550        X500Principal principal = new X500Principal(dn);
551        byte[] enc = principal.getEncoded();
552        X500Principal principal2 = new X500Principal(enc);
553        String s = principal2.getName(X500Principal.RFC1779);
554        assertEquals("OID.2.16.4.3=B, CN=A", s);
555
556    }
557
558    /**
559     * Inits X500Principal with a string, where OID does not fall into any keyword
560     * gets encoded form
561     * inits new X500Principal with the encoding
562     * gets string in RFC2253 format
563     * compares with expected value
564     */
565    public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_RFC2253()
566            throws Exception {
567        String dn = "OID.2.16.4.3=B; CN=A";
568        X500Principal principal = new X500Principal(dn);
569        byte[] enc = principal.getEncoded();
570        X500Principal principal2 = new X500Principal(enc);
571        String s = principal2.getName(X500Principal.RFC2253);
572        assertEquals("2.16.4.3=#130142,CN=A", s);
573
574    }
575
576    /**
577     * Inits X500Principal with a string, where OID does not fall into any keyword
578     * gets encoded form
579     * inits new X500Principal with the encoding
580     * gets string in CANONICAL format
581     * compares with expected value
582     */
583    public void testGetName_EncodingWithWrongOidButGoodName_SeveralRDNs_CANONICAL()
584            throws Exception {
585        String dn = "OID.2.16.4.3=B; CN=A";
586        X500Principal principal = new X500Principal(dn);
587        byte[] enc = principal.getEncoded();
588        X500Principal principal2 = new X500Principal(enc);
589        String s = principal2.getName(X500Principal.CANONICAL);
590        assertEquals("2.16.4.3=#130142,cn=a", s);
591
592    }
593
594    /**
595     * Inits X500Principal with a string, where OID does not fall into any keyword
596     * gets string in RFC1779 format
597     * compares with expected value
598     */
599    public void testGetName_wrongOidButGoodName_RFC1779() throws Exception {
600        String dn = "OID.2.16.4.3=B + CN=A";
601        X500Principal principal = new X500Principal(dn);
602
603        String s = principal.getName(X500Principal.RFC1779);
604        assertEquals("OID.2.16.4.3=B + CN=A", s);
605    }
606
607    /**
608     * Inits X500Principal with a string, where OID does not fall into any keyword
609     * gets string in RFC2253 format
610     * compares with expected value
611     */
612    public void testGetName_wrongOidButGoodName_RFC2253() throws Exception {
613        String dn = "OID.2.16.4.3=B + CN=A";
614        X500Principal principal = new X500Principal(dn);
615
616        String s = principal.getName(X500Principal.RFC2253);
617        assertEquals("2.16.4.3=#130142+CN=A", s);
618    }
619
620    /**
621     * Inits X500Principal with a string, there are multiple AVAs
622     * gets string in CANONICAL format
623     * compares with expected value paying attention on sorting order of AVAs
624     */
625    public void testGetName_CANONICAL_SortOrder() throws Exception {
626        String dn = "ST=C + CN=A; OU=B + CN=D";
627        X500Principal principal = new X500Principal(dn);
628
629        String s = principal.getName(X500Principal.CANONICAL);
630        assertEquals("cn=a+st=c,cn=d+ou=b", s);
631
632    }
633
634    /**
635     * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
636     * gets string in CANONICAL format
637     * compares with expected value paying attention on sorting order of AVAs
638     */
639    public void testGetName_CANONICAL_SortOrder_01() throws Exception {
640        String dn = "OID.2.16.4.3=B + CN=A";
641        X500Principal principal = new X500Principal(dn);
642
643        String s = principal.getName(X500Principal.CANONICAL);
644        assertEquals("cn=a+2.16.4.3=#130142", s);
645
646    }
647
648    /**
649     * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword, and value given in hex format
650     * gets string in CANONICAL format
651     * compares with expected value paying attention on sorting order of AVAs
652     */
653    public void testGetName_CANONICAL_SortOrder_02() throws Exception {
654        String dn = "OID.2.16.4.3=#13024220+ CN=A";
655        X500Principal principal = new X500Principal(dn);
656
657        String s = principal.getName(X500Principal.CANONICAL);
658        assertEquals("cn=a+2.16.4.3=#13024220", s);
659
660    }
661
662    /**
663     * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
664     * gets string in CANONICAL format
665     * compares with expected value paying attention on sorting order of AVAs
666     */
667    public void testGetName_CANONICAL_SortOrder_03() throws Exception {
668        String dn = "OID.2.16.4.9=A + OID.2.16.4.3=B";
669        X500Principal principal = new X500Principal(dn);
670
671        String s = principal.getName(X500Principal.CANONICAL);
672        assertEquals("2.16.4.3=#130142+2.16.4.9=#130141", s);
673
674    }
675
676    /**
677     * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
678     * gets string in CANONICAL format
679     * compares with expected value paying attention on sorting order of AVAs
680     */
681    public void testGetName_CANONICAL_SortOrder_04() throws Exception {
682        String dn = "OID.2.2.2.2=A + OID.1.1.1.1=B";
683        X500Principal principal = new X500Principal(dn);
684
685        String s = principal.getName(X500Principal.CANONICAL);
686        assertEquals("1.1.1.1=#130142+2.2.2.2=#130141", s);
687
688    }
689
690    /**
691     * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
692     * gets string in CANONICAL format
693     * compares with expected value paying attention on sorting order of AVAs
694     */
695    public void testGetName_CANONICAL_SortOrder_05() throws Exception {
696        String dn = "OID.2.16.4.9=A + OID.2.16.4=B";
697        X500Principal principal = new X500Principal(dn);
698
699        String s = principal.getName(X500Principal.CANONICAL);
700        assertEquals("2.16.4=#130142+2.16.4.9=#130141", s);
701
702    }
703
704    /**
705     * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
706     * gets string in CANONICAL format
707     * compares with expected value paying attention on sorting order of AVAs
708     */
709    public void testGetName_CANONICAL_SortOrder_06() throws Exception {
710        String dn = "OID.1.1.2=A + OID.1.2=B";
711        X500Principal principal = new X500Principal(dn);
712
713        String s = principal.getName(X500Principal.CANONICAL);
714        assertEquals("1.1.2=#130141+1.2=#130142", s);
715
716    }
717
718    /**
719     * Inits X500Principal with a string, there are multiple AVAs and 2 Oids which do not fall into any keyword
720     * gets string in CANONICAL format
721     * compares with expected value paying attention on sorting order of AVAs
722     */
723    public void testGetName_CANONICAL_SortOrder_07() throws Exception {
724        String dn = "OID.1.1.1=A + OID.1.1=B";
725        X500Principal principal = new X500Principal(dn);
726
727        String s = principal.getName(X500Principal.CANONICAL);
728        assertEquals("1.1=#130142+1.1.1=#130141", s);
729
730    }
731
732    /**
733     * FIXME test is failed - implement unicode normalization
734     * @throws Exception
735     */
736    public void testGetNameUnicodeNormalized() throws Exception {
737        String unicodeStr = "CN= \u0401\u0410";
738        X500Principal principal = new X500Principal(unicodeStr);
739        principal.getName(X500Principal.CANONICAL);
740    }
741
742    /**
743     * Inits X500Principal with empty string
744     * gets encoding
745     * compares with expected encoding
746     */
747    public void testEmptyInputName() {
748        String dn = "CN=\"\"";
749        byte[] mess = { 0x30, 0x0B, 0x31, 0x09, 0x30, 0x07, 0x06, 0x03, 0x55,
750                0x04, 0x03, 0x13, 0x00 };
751        X500Principal principal = new X500Principal(dn);
752        assertTrue(Arrays.equals(mess, principal.getEncoded()));
753    }
754
755    /**
756     * Inits X500Principal with string as single escaped space
757     * gets encoding
758     * compares with expected encoding
759     */
760    public void testNameSingleEscapedSpace() {
761        String dn = "CN=\\ ";
762        byte[] mess = { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
763                0x04, 0x03, 0x13, 0x01, 0x20 };
764        X500Principal principal = new X500Principal(dn);
765        assertTrue(Arrays.equals(mess, principal.getEncoded()));
766    }
767
768    /**
769     * Inits X500Principal with string with spaces
770     * gets Name in RFC2253 format
771     * compares with expected value of name
772     */
773    public void testNameOnlySpaces_RFC1779() {
774        String dn = "CN=\"  \"";
775        X500Principal principal = new X500Principal(dn);
776        assertEquals("CN=\"  \"", principal.getName(X500Principal.RFC1779));
777    }
778
779    /**
780     * Inits X500Principal with string with spaces
781     * gets Name in RFC2253 format
782     * compares with expected value of name
783     */
784    public void testNameOnlySpaces_RFC2253() {
785        String dn = "CN=\"  \"";
786        X500Principal principal = new X500Principal(dn);
787        assertEquals("CN=\\ \\ ", principal.getName(X500Principal.RFC2253));
788    }
789
790    /**
791     * Inits X500Principal with string with only spaces,
792     * gets Name in CANONICAL format:leading and trailing white space
793     * chars are removed even string doesn't have other chars (bug???)
794     */
795    public void testNameOnlySpaces_CANONICAL() {
796        String dn = "CN=\"  \"";
797        X500Principal principal = new X500Principal(dn);
798        assertEquals("cn=", principal.getName(X500Principal.CANONICAL));
799    }
800
801    ///*** Negative Tests ***///
802    /**
803     * Inits X500Principal with string, where DN name is improper "CNN"
804     * checks if proper exception is thrown
805     */
806    public void testIllegalInputName() {
807        try {
808            String dn = "CNN=A";
809            new X500Principal(dn);
810            fail("No IllegalArgumentException on improper input name \"CNN\"");
811        } catch (IllegalArgumentException e) {
812        }
813    }
814
815    /**
816     * Inits X500Principal with string, where there is leading ';'
817     * checks if proper exception is thrown
818     */
819    public void testIllegalInputName_01() {
820        try {
821            String dn = ";CN=A";
822            new X500Principal(dn);
823            fail("No IllegalArgumentException on leading ';' in input name");
824        } catch (IllegalArgumentException e) {
825        }
826    }
827
828    /**
829     * Inits X500Principal with string, where there is leading '='
830     * checks if proper exception is thrown
831     */
832    public void testIllegalInputName_02() {
833        try {
834            String dn = "=CN=A";
835            new X500Principal(dn);
836            fail("No IllegalArgumentException on leading '=' in input name");
837        } catch (IllegalArgumentException e) {
838        }
839    }
840
841    /**
842     * Inits X500Principal with string, where there is no value
843     * checks if proper exception is thrown
844     */
845    public void testEmptyInputName_0() {
846        String dn = "CN=";
847        byte[] mess = { 0x30, 0x0B, 0x31, 0x09, 0x30, 0x07, 0x06, 0x03, 0x55,
848                0x04, 0x03, 0x13, 0x00 };
849        X500Principal principal = new X500Principal(dn);
850        assertTrue(Arrays.equals(mess, principal.getEncoded()));
851    }
852
853    public void testEmptyInputName_1() {
854        String dn = "CN=\"\", C=\"\"";
855        X500Principal principal = new X500Principal(dn);
856        dn = "CN=, C=";
857        X500Principal principal2 = new X500Principal(dn);
858        assertTrue(Arrays.equals(principal.getEncoded(), principal2
859                .getEncoded()));
860
861    }
862
863    public void testEmptyInputName_2() {
864        String dn = "CN=\"\" + OU=A, C=\"\"";
865        X500Principal principal = new X500Principal(dn);
866        dn = "CN=+OU=A, C=";
867        X500Principal principal2 = new X500Principal(dn);
868        assertTrue(Arrays.equals(principal.getEncoded(), principal2
869                .getEncoded()));
870
871    }
872
873    public void testIllegalInputName_15() {
874        try {
875            String dn = "CN=,C";
876            new X500Principal(dn);
877            fail("No IllegalArgumentException on improper attribute value");
878        } catch (IllegalArgumentException e) {
879        }
880    }
881
882    public void testIllegalInputName_16() {
883        try {
884            String dn = "CN=,C=+";
885            new X500Principal(dn);
886            fail("No IllegalArgumentException on improper attribute value");
887        } catch (IllegalArgumentException e) {
888        }
889    }
890
891    /**
892     * Inits X500Principal with string, where value is given in wrong hex format
893     * checks if proper exception is thrown
894     */
895    public void testIllegalInputName_04() {
896        try {
897            String dn = "CN=#XYZ";
898            new X500Principal(dn);
899            fail("No IllegalArgumentException on improper hex value");
900        } catch (IllegalArgumentException e) {
901        }
902    }
903
904    /**
905     * Inits X500Principal with string, where value is given with special chars
906     * checks if proper exception is thrown
907     */
908    public void testIllegalInputName_05() {
909        try {
910            String dn = "CN=X+YZ";
911            new X500Principal(dn);
912            fail("No IllegalArgumentException on improper attribute value");
913        } catch (IllegalArgumentException e) {
914        }
915    }
916
917    /**
918     * Inits X500Principal with string, where value is given with special chars
919     * Compatibility issue: according RFC 2253 such string is invalid
920     * but we accept it, not string char is escaped
921     */
922    public void testIllegalInputName_06() {
923        String dn = "CN=X=YZ";
924        X500Principal p = new X500Principal(dn);
925        assertEquals("CN=X\\=YZ", p.getName(X500Principal.RFC2253));
926    }
927
928    /**
929     * Inits X500Principal with string, where value is given with not string chars
930     * Compatibility issue: according RFC 2253 such string is invalid
931     * but we accept it, not string char is escaped
932     */
933    public void testIllegalInputName_07() {
934        String dn = "CN=X\"YZ";
935        X500Principal p = new X500Principal(dn);
936        assertEquals("CN=X\\\"YZ", p.getName(X500Principal.RFC2253));
937    }
938
939    /**
940     * Inits X500Principal with string, where value is given with special chars
941     * Compatibility issue: according RFC 2253 such string is invalid
942     * but we accept it, special char is escaped
943     */
944    public void testIllegalInputName_08() {
945        String dn = "CN=X<YZ";
946        X500Principal p = new X500Principal(dn);
947        assertEquals("CN=X\\<YZ", p.getName(X500Principal.RFC2253));
948    }
949
950    /**
951     * Inits X500Principal with string, where value is given with special chars
952     * checks if proper exception is thrown
953     */
954    public void testIllegalInputName_09() {
955        try {
956            String dn = "CN=#";
957            new X500Principal(dn);
958            fail("No IllegalArgumentException on improper attribute hex value");
959        } catch (IllegalArgumentException e) {
960            //ignore
961        }
962
963    }
964
965    /**
966     * Inits X500Principal with string, where value is given with special chars
967     * checks if proper exception is thrown
968     */
969    public void testIllegalInputName_10() {
970        try {
971            String dn = "CN=#13";
972            new X500Principal(dn);
973            fail("No IllegalArgumentException on improper attribute hex value");
974        } catch (IllegalArgumentException e) {
975            //ignore
976        }
977
978    }
979
980    /**
981     * Inits X500Principal with string, where value is given with special chars
982     * checks if proper exception is thrown
983     */
984    public void testIllegalInputName_11() {
985        try {
986            String dn = "CN=#1301";
987            new X500Principal(dn);
988            fail("No IllegalArgumentException on improper attribute hex value");
989        } catch (IllegalArgumentException e) {
990            //ignore
991        }
992
993    }
994
995    /**
996     * Inits X500Principal with string, where value is given with special chars
997     * checks if proper exception is thrown
998     */
999    public void testIllegalInputName_12() {
1000        try {
1001            String dn = "CN=#13010101";
1002            new X500Principal(dn);
1003            fail("No IllegalArgumentException on improper attribute hex value");
1004        } catch (IllegalArgumentException e) {
1005        }
1006    }
1007
1008    /**
1009     * Inits X500Principal with string, where value is given with special chars
1010     * checks if proper exception is thrown
1011     */
1012    public void testIllegalInputName_13() {
1013        try {
1014            String dn = "CN=# 0";
1015            new X500Principal(dn);
1016            fail("No IllegalArgumentException on improper attribute hex value");
1017        } catch (IllegalArgumentException e) {
1018        }
1019    }
1020
1021    /**
1022     * Inits X500Principal with string, where value is given in hex format, but improper tag
1023     * checks if it is ignored
1024     */
1025    public void testSemiIllegalInputName_14() {
1026        String dn = "CN=#7E0142";
1027        new X500Principal(dn);
1028    }
1029
1030    public void testInitClause() {
1031        try {
1032            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1033                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1034                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1035            mess[3] = 0x12;//length field
1036            new X500Principal(mess);
1037
1038            fail("No IllegalArgumentException on input array with improper length field");
1039        } catch (IllegalArgumentException e) {
1040        }
1041    }
1042
1043    /**
1044     * Inits X500Principal with byte array = null
1045     * checks if proper exception is thrown
1046     */
1047    public void testIllegalInputArray_0() {
1048        try {
1049            byte[] mess = null;
1050            new X500Principal(mess);
1051            fail("No IllegalArgumentException on input array with improper length field");
1052        } catch (IllegalArgumentException e) {
1053        }
1054    }
1055
1056    /**
1057     * Inits X500Principal with byte array with wrong length field
1058     * checks if proper exception is thrown
1059     */
1060    public void testIllegalInputArray() {
1061        try {
1062            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1063                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1064                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1065            mess[3] = 0x12;//length field
1066            new X500Principal(mess);
1067
1068            fail("No IllegalArgumentException on input array with improper length field");
1069        } catch (IllegalArgumentException e) {
1070        }
1071    }
1072
1073    /**
1074     * Inits X500Principal with input stream with wrong length field
1075     * checks if proper exception is thrown
1076     */
1077    public void testIllegalInputArray_is() {
1078        try {
1079            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1080                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1081                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1082            mess[3] = 0x12;//length field
1083            ByteArrayInputStream is = new ByteArrayInputStream(mess);
1084            new X500Principal(is);
1085
1086            fail("No IllegalArgumentException on input array with improper length field");
1087        } catch (IllegalArgumentException e) {
1088        }
1089    }
1090
1091    /**
1092     * Inits X500Principal with byte array with wrong inner Sequence tag field
1093     * checks if proper exception is thrown
1094     */
1095    public void testIllegalInputArray_01() {
1096        try {
1097            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1098                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1099                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1100            mess[4] = 0x12;//inner Sequence tag field
1101            new X500Principal(mess);
1102
1103            fail("No IllegalArgumentException on input array with improper inner Sequence tag field");
1104        } catch (IllegalArgumentException e) {
1105        }
1106    }
1107
1108    /**
1109     * Inits X500Principal with byte array with wrong last byte of OID
1110     * checks if proper exception is thrown
1111     */
1112    public void testIllegalInputArray_02() {
1113        try {
1114            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1115                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1116                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1117            mess[10] = (byte) 0xFE;//last byte of OID
1118            new X500Principal(mess);
1119
1120            fail("No IllegalArgumentException on input array with improper last byte of OID");
1121        } catch (IllegalArgumentException e) {
1122        }
1123    }
1124
1125    /**
1126     * Inits X500Principal with byte array with wrong length of OID
1127     * checks if proper exception is thrown
1128     */
1129    public void testIllegalInputArray_03() {
1130        try {
1131            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1132                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1133                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1134            mess[7] = 2;//length of OID
1135            new X500Principal(mess);
1136
1137            fail("No IllegalArgumentException on input array with improper length of OID");
1138        } catch (IllegalArgumentException e) {
1139        }
1140    }
1141
1142    /**
1143     * Inits X500Principal with byte array with wrong tag of value
1144     * checks if it is ignored
1145     */
1146    public void testSemiIllegalInputArray_04() {
1147        byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55,
1148                0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08, 0x06,
1149                0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1150        mess[11] = (byte) 0x0F;//tag of value
1151        new X500Principal(mess);
1152    }
1153
1154    /**
1155     * Inits X500Principal with byte array with wrong length of value
1156     * checks if proper exception is thrown
1157     */
1158    public void testIllegalInputArray_05() {
1159        try {
1160            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1161                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1162                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1163            mess[12] = 2;//length of value
1164            new X500Principal(mess);
1165
1166            fail("No IllegalArgumentException on input array with improper length of value");
1167        } catch (IllegalArgumentException e) {
1168        }
1169    }
1170
1171    /**
1172     * Inits X500Principal with input stream with wrong length of value
1173     * checks if proper exception is thrown
1174     */
1175    public void testIllegalInputArray_05_is() {
1176        try {
1177            byte[] mess = { 0x30, 0x18, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
1178                    0x55, 0x04, 0x03, 0x13, 0x01, 0x42, 0x31, 0x0A, 0x30, 0x08,
1179                    0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x01, 0x41 };
1180            mess[12] = 2;//length of value
1181            ByteArrayInputStream is = new ByteArrayInputStream(mess);
1182            new X500Principal(is);
1183
1184            fail("No IllegalArgumentException on input array with improper length of value");
1185        } catch (IllegalArgumentException e) {
1186        }
1187    }
1188
1189    /**
1190     * Inits X500Principal with string
1191     * Calls getName with improper parameter as format
1192     * checks if proper exception is thrown
1193     */
1194    public void testIllegalFormat() {
1195        try {
1196            String dn = "CN=A";
1197            X500Principal principal = new X500Principal(dn);
1198            principal.getName("WRONG FORMAT");
1199            fail("No IllegalArgumentException on improper parameter as format");
1200        } catch (IllegalArgumentException e) {
1201        }
1202    }
1203
1204    /**
1205     * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
1206     * Gets encoding
1207     * Inits other X500Principal with the encoding
1208     * gets string in RFC1779 format
1209     * compares with expected value paying attention on sorting order of AVAs
1210     */
1211    public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_RFC1779()
1212            throws Exception {
1213        String dn = "OID.2.16.4.3=B + CN=A";
1214        X500Principal principal = new X500Principal(dn);
1215        byte[] enc = principal.getEncoded();
1216        X500Principal principal2 = new X500Principal(enc);
1217        String s = principal2.getName(X500Principal.RFC1779);
1218        assertEquals("OID.2.16.4.3=B + CN=A", s);
1219
1220    }
1221
1222    /**
1223     * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
1224     * Gets encoding
1225     * Inits other X500Principal with the encoding
1226     * gets string in RFC2253 format
1227     * compares with expected value paying attention on sorting order of AVAs
1228     */
1229    public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_RFC2253()
1230            throws Exception {
1231        String dn = "OID.2.16.4.3=B + CN=A";
1232        X500Principal principal = new X500Principal(dn);
1233        byte[] enc = principal.getEncoded();
1234        X500Principal principal2 = new X500Principal(enc);
1235        String s = principal2.getName(X500Principal.RFC2253);
1236        assertEquals("2.16.4.3=#130142+CN=A", s);
1237
1238    }
1239
1240    /**
1241     * Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
1242     * Gets encoding
1243     * Inits other X500Principal with the encoding
1244     * gets string in CANONICAL format
1245     * compares with expected value paying attention on sorting order of AVAs
1246     */
1247    public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_CANONICAL()
1248            throws Exception {
1249        String dn = "OID.2.16.4.3=B + CN=A";
1250        X500Principal principal = new X500Principal(dn);
1251        byte[] enc = principal.getEncoded();
1252        X500Principal principal2 = new X500Principal(enc);
1253        String s = principal2.getName(X500Principal.CANONICAL);
1254        assertEquals("cn=a+2.16.4.3=#130142", s);
1255
1256    }
1257
1258    /**
1259     * Inits X500Principal with byte array, where there are leading and tailing spaces
1260     * gets Name in RFC1779 format
1261     * compares with expected value of name
1262     */
1263    public void testNameSpaceFromEncoding_RFC1779() throws Exception {
1264        byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
1265                0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
1266        X500Principal principal = new X500Principal(mess);
1267        String s = principal.getName(X500Principal.RFC1779);
1268        assertEquals("CN=\" A \"", s);
1269
1270    }
1271
1272    /**
1273     * Inits X500Principal with byte array, where there are leading and tailing spaces
1274     * gets Name in RFC2253 format
1275     * compares with expected value of name
1276     */
1277    public void testNameSpaceFromEncoding_RFC2253() throws Exception {
1278        byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
1279                0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
1280        X500Principal principal = new X500Principal(mess);
1281        String s = principal.getName(X500Principal.RFC2253);
1282        assertEquals("CN=\\ A\\ ", s);
1283
1284    }
1285
1286    /**
1287     * Inits X500Principal with byte array, where there are leading and tailing spaces
1288     * gets Name in CANONICAL format
1289     * compares with expected value of name
1290     */
1291    public void testNameSpaceFromEncoding_CANONICAL() throws Exception {
1292        byte[] mess = { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03, 0x55,
1293                0x04, 0x03, 0x13, 0x03, 0x20, 0x41, 0x20, };
1294        X500Principal principal = new X500Principal(mess);
1295        String s = principal.getName(X500Principal.CANONICAL);
1296        assertEquals("cn=a", s);
1297
1298    }
1299
1300    /**
1301     * Inits X500Principal with byte array, where there are special characters
1302     * gets Name in RFC1779 format
1303     * compares with expected value of name, checks if the string is in quotes
1304     */
1305    public void testNameSpecialCharsFromEncoding_RFC1779() throws Exception {
1306        byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
1307                0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
1308        X500Principal principal = new X500Principal(mess);
1309        String s = principal.getName(X500Principal.RFC1779);
1310        assertEquals("CN=\";,\"", s);
1311
1312    }
1313
1314    /**
1315     * Inits X500Principal with byte array, where there are special characters
1316     * gets Name in RFC1779 format
1317     * compares with expected value of name, checks if the characters are escaped
1318     */
1319    public void testNameSpecialCharsFromEncoding_RFC2253() throws Exception {
1320        byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
1321                0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
1322        X500Principal principal = new X500Principal(mess);
1323        String s = principal.getName(X500Principal.RFC2253);
1324        assertEquals("CN=\\;\\,", s);
1325
1326    }
1327
1328    /**
1329     * Inits X500Principal with byte array, where there are special characters
1330     * gets Name in CANONICAL format
1331     * compares with expected value of name, checks if the characters are escaped
1332     */
1333    public void testNameSpecialCharsFromEncoding_CANONICAL() throws Exception {
1334        byte[] mess = { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
1335                0x04, 0x03, 0x0C, 0x02, 0x3B, 0x2C };
1336        X500Principal principal = new X500Principal(mess);
1337        String s = principal.getName(X500Principal.CANONICAL);
1338        assertEquals("cn=\\;\\,", s);
1339
1340    }
1341
1342    /**
1343     * Inits X500Principal with the string with special characters - \"B
1344     * gets Name in RFC1779 format
1345     * compares with expected value of name - "\B"
1346     */
1347    public void testNameSpecialChars_RFC1779() throws Exception {
1348        String dn = "CN=A,CN=\\\"B";
1349        X500Principal principal = new X500Principal(dn);
1350        String s = principal.getName(X500Principal.RFC1779);
1351        assertEquals("CN=A, CN=\"\\\"B\"", s);
1352
1353    }
1354
1355    /**
1356     * Inits X500Principal with the string with special characters - \"B
1357     * gets Name in RFC2253 format
1358     * compares with expected value of name - "\B"
1359     */
1360    public void testNameSpecialChars_RFC2253() throws Exception {
1361        String dn = "CN=A,CN=\\\"B";
1362        X500Principal principal = new X500Principal(dn);
1363        String s = principal.getName(X500Principal.RFC2253);
1364        assertEquals("CN=A,CN=\\\"B", s);
1365
1366    }
1367
1368    /**
1369     * Inits X500Principal with the string with special characters - \"B
1370     * gets Name in CANONICAL format
1371     * compares with expected value of name - "\b"
1372     */
1373    public void testNameSpecialChars_CANONICAL() throws Exception {
1374        String dn = "CN=A,CN=\\\"B";
1375        X500Principal principal = new X500Principal(dn);
1376        String s = principal.getName(X500Principal.CANONICAL);
1377        assertEquals("cn=a,cn=\\\"b", s);
1378
1379    }
1380
1381    /**
1382     * Inits X500Principal with the string with special characters - \\nB
1383     * gets Name in RFC1779 format
1384     * compares with expected value of name - "\nB"
1385     */
1386    public void testNameSpecialChars_RFC1779_01() throws Exception {
1387        //FIXME see testNameSpecialChars_RFC2253_01
1388        //        String dn = "CN=\\\nB";
1389        //        X500Principal principal = new X500Principal(dn);
1390        //        String s = principal.getName(X500Principal.RFC1779);
1391        //        assertEquals("CN=\"\nB\"", s);
1392
1393    }
1394
1395    /**
1396     * Inits X500Principal with the string with special characters - \\nB
1397     * gets Name in RFC2253 format
1398     * compares with expected value of name - \\nB
1399     */
1400    public void testNameSpecialChars_RFC2253_01() throws Exception {
1401
1402        try {
1403            // compatibility issue:
1404            // don't accept escaped \n because it is not a special char
1405            new X500Principal("CN=\\\nB");
1406            fail("No expected IllegalArgumentException");
1407        } catch (IllegalArgumentException e) {
1408        }
1409    }
1410
1411    /**
1412     * Inits X500Principal with the string with special characters - \\nB
1413     * gets Name in CANONICAL format
1414     * compares with expected value of name - \\nb
1415     */
1416    public void testNameSpecialChars_CANONICAL_01() throws Exception {
1417        //FIXME testNameSpecialChars_RFC2253_01
1418        //        String dn = "CN=\\\nB";
1419        //        X500Principal principal = new X500Principal(dn);
1420        //        String s = principal.getName(X500Principal.CANONICAL);
1421        //        assertEquals("cn=b", s);
1422
1423    }
1424
1425    /**
1426     * Inits X500Principal with the string with special characters - \\B
1427     * gets Name in RFC1779 format
1428     * compares with expected value of name - "\B"
1429     */
1430    public void testNameSpecialChars_RFC1779_02() throws Exception {
1431        String dn = "CN=\\\\B";
1432        X500Principal principal = new X500Principal(dn);
1433        String s = principal.getName(X500Principal.RFC1779);
1434        assertEquals("CN=\"\\\\B\"", s);
1435
1436    }
1437
1438    /**
1439     * Inits X500Principal with the string with special characters - \\B
1440     * gets Name in RFC2253 format
1441     * compares with expected value of name - \\B
1442     */
1443    public void testNameSpecialChars_RFC2253_02() throws Exception {
1444        String dn = "CN=\\\\B";
1445        X500Principal principal = new X500Principal(dn);
1446        String s = principal.getName(X500Principal.RFC2253);
1447        assertEquals("CN=\\\\B", s);
1448
1449    }
1450
1451    /**
1452     * Inits X500Principal with the string with special characters - \\B
1453     * gets Name in CANONICAL format
1454     * compares with expected value of name - \\b
1455     */
1456    public void testNameSpecialChars_CANONICAL_02() throws Exception {
1457        String dn = "CN=\\\\B";
1458        X500Principal principal = new X500Principal(dn);
1459        String s = principal.getName(X500Principal.CANONICAL);
1460        assertEquals("cn=\\\\b", s);
1461
1462    }
1463
1464    /**
1465     * Inits X500Principal with the string with special characters - ABC"DEF"
1466     * gets encoding
1467     * compares with expected encoding
1468     */
1469    public void testNameWithQuotation() throws Exception {
1470        String dn = "CN=\"ABCDEF\"";
1471
1472        X500Principal principal = new X500Principal(dn);
1473        byte[] enc = principal.getEncoded();
1474        assertTrue(Arrays.equals(new byte[] { 0x30, 0x11, 0x31, 0x0F, 0x30,
1475                0x0D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x06, 0x41, 0x42,
1476                0x43, 0x44, 0x45, 0x46 }, enc));
1477
1478    }
1479
1480    /**
1481     * Inits X500Principal with the string with special characters - "ABCDEF
1482     * checks if the proper exception is thrown
1483     */
1484    public void testNameWithQuotation_01() throws Exception {
1485        String dn = "CN=\"ABCDEF";
1486        try {
1487            new X500Principal(dn);
1488            fail("No IllegalArgumentException on string with no closing quotations");
1489        } catch (IllegalArgumentException e) {
1490        }
1491    }
1492
1493    /**
1494     * Inits X500Principal with the string with special characters - ABC"D#EF"
1495     * gets encoding
1496     * compares with expected encoding
1497     */
1498    public void testNameWithQuotation_02() throws Exception {
1499        String dn = "CN=\"ABCD#EF\"";
1500        X500Principal principal = new X500Principal(dn);
1501        byte[] enc = principal.getEncoded();
1502        assertTrue(Arrays.equals(new byte[] { 0x30, 0x12, 0x31, 0x10, 0x30,
1503                0x0E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x07, 0x41, 0x42,
1504                0x43, 0x44, 0x23, 0x45, 0x46 }, enc));
1505    }
1506
1507    /**
1508     * Inits X500Principal with the string with special characters - ABC"DEF"
1509     * Compatibility issue: according RFC 2253 such string is invalid
1510     * but we accept it, not string char is escaped
1511     */
1512    public void testNameWithQuotation_03() throws Exception {
1513        String dn = "CN=ABC\"DEF\"";
1514        X500Principal principal = new X500Principal(dn);
1515        assertEquals("CN=ABC\\\"DEF\\\"", principal
1516                .getName(X500Principal.RFC2253));
1517    }
1518
1519    /**
1520     * Inits X500Principal with the string with special characters - ABC"DEF"
1521     * gets Name in RFC1779 format
1522     * compares with expected value of name - "ABCDEF"
1523     */
1524    public void testNameSpecialChars_RFC1779_03() throws Exception {
1525        String dn = "CN=\"ABCDEF\"";
1526        X500Principal principal = new X500Principal(dn);
1527        String s = principal.getName(X500Principal.RFC1779);
1528        assertEquals("CN=ABCDEF", s);
1529
1530    }
1531
1532    /**
1533     * Inits X500Principal with the string with special characters - ABC"DEF"
1534     * gets Name in RFC2253 format
1535     * compares with expected value of name - ABC"DEF"
1536     */
1537    public void testNameSpecialChars_RFC2253_03() throws Exception {
1538        String dn = "CN=\"ABCDEF\"";
1539        X500Principal principal = new X500Principal(dn);
1540        String s = principal.getName(X500Principal.RFC2253);
1541        assertEquals("CN=ABCDEF", s);
1542
1543    }
1544
1545    /**
1546     * Inits X500Principal with the string with special characters - ABC"DEF"
1547     * gets Name in CANONICAL format
1548     * compares with expected value of name - abc"def"
1549     */
1550    public void testNameSpecialChars_CANONICAL_03() throws Exception {
1551        String dn = "CN=\"ABCDEF\"";
1552        X500Principal principal = new X500Principal(dn);
1553        String s = principal.getName(X500Principal.CANONICAL);
1554        assertEquals("cn=abcdef", s);
1555
1556    }
1557
1558    /**
1559     * Inits X500Principal with the string with special characters - ABC"D#EF"
1560     * gets Name in RFC1779 format
1561     * compares with expected value of name - "ABCD#EF"
1562     */
1563    public void testNameSpecialChars_RFC1779_04() throws Exception {
1564        String dn = "CN=\"ABCD#EF\"";
1565        X500Principal principal = new X500Principal(dn);
1566        String s = principal.getName(X500Principal.RFC1779);
1567        assertEquals("CN=\"ABCD#EF\"", s);
1568
1569    }
1570
1571    /**
1572     * Inits X500Principal with the string with special characters - ABC"D#EF"
1573     * gets Name in RFC1779 format
1574     * compares with expected value of name - ABCD\#EF
1575     */
1576    public void testNameSpecialChars_RFC2253_04() throws Exception {
1577        String dn = "CN=\"ABCD#EF\"";
1578        X500Principal principal = new X500Principal(dn);
1579        String s = principal.getName(X500Principal.RFC2253);
1580        assertEquals("CN=ABCD\\#EF", s);
1581
1582    }
1583
1584    /**
1585     * Inits X500Principal with the string with special characters - ABC"D#EF"
1586     * gets Name in RFC1779 format
1587     * compares with expected value of name - abc"d#ef"
1588     */
1589    public void testNameSpecialChars_CANONICAL_04() throws Exception {
1590        String dn = "CN=\"ABCD#EF\"";
1591        X500Principal principal = new X500Principal(dn);
1592        String s = principal.getName(X500Principal.CANONICAL);
1593        assertEquals("cn=abcd#ef", s);
1594
1595    }
1596
1597    /**
1598     * Inits X500Principal with the string with special characters - X#YZ
1599     * gets Name in RFC1779 format
1600     * compares with expected value of name - "X#YZ"
1601     */
1602    public void testNameSpecialChars_RFC1779_05() {
1603        String dn = "CN=X#YZ";
1604        X500Principal principal = new X500Principal(dn);
1605
1606        String s = principal.getName(X500Principal.RFC1779);
1607        assertEquals("CN=\"X#YZ\"", s);
1608
1609    }
1610
1611    /**
1612     * Inits X500Principal with the string with special characters - X#YZ
1613     * gets Name in RFC2253 format
1614     * compares with expected value of name - X\#YZ
1615     */
1616    public void testNameSpecialChars_RFC2253_05() {
1617        String dn = "CN=X#YZ";
1618        X500Principal principal = new X500Principal(dn);
1619
1620        String s = principal.getName(X500Principal.RFC2253);
1621
1622        assertEquals("CN=X\\#YZ", s);
1623
1624    }
1625
1626    /**
1627     * Inits X500Principal with the string with special characters - X#YZ
1628     * gets Name in CANONICAL format
1629     * compares with expected value of name - x#yz
1630     */
1631    public void testNameSpecialChars_CANONICAL_05() {
1632        String dn = "CN=X#YZ";
1633        X500Principal principal = new X500Principal(dn);
1634
1635        String s = principal.getName(X500Principal.CANONICAL);
1636        assertEquals("cn=x#yz", s);
1637
1638    }
1639
1640    /**
1641     * Inits X500Principal with the string with special characters - CN=\#XYZ
1642     * gets Name in RFC1779 format
1643     * compares with expected value of name - CN="#XYZ"
1644     */
1645    public void testNameSpecialChars_RFC1779_6() throws Exception {
1646        String dn = "CN=\\#XYZ";
1647        X500Principal principal = new X500Principal(dn);
1648        String s = principal.getName(X500Principal.RFC1779);
1649        assertEquals("CN=\"#XYZ\"", s);
1650
1651    }
1652
1653    /**
1654     * Inits X500Principal with the string with special characters - CN=\#XYZ
1655     * gets Name in RFC2253 format
1656     * compares with expected value of name - CN=\#XYZ
1657     */
1658    public void testNameSpecialChars_RFC2253_6() throws Exception {
1659        String dn = "CN=\\#XYZ";
1660        X500Principal principal = new X500Principal(dn);
1661        String s = principal.getName(X500Principal.RFC2253);
1662        assertEquals("CN=\\#XYZ", s);
1663    }
1664
1665    /**
1666     * Inits X500Principal with the string with special characters - CN=\#XYZ
1667     * gets Name in CANONICAL format
1668     * compares with expected value of name - cn=\#xyz
1669     */
1670    public void testNameSpecialChars_CANONICAL_6() throws Exception {
1671        String dn = "CN=\\#XYZ";
1672        X500Principal principal = new X500Principal(dn);
1673        String s = principal.getName(X500Principal.CANONICAL);
1674        assertEquals("cn=\\#xyz", s);
1675    }
1676
1677    /**
1678     * Inits X500Principal with the string with special characters - B\'space'
1679     * gets Name in RFC1779 format
1680     * compares with expected value of name - "B "
1681     */
1682    public void testNameSpaces_RFC1779() throws Exception {
1683        String dn = "CN=A,CN=B\\ ";
1684        X500Principal principal = new X500Principal(dn);
1685        String s = principal.getName(X500Principal.RFC1779);
1686        assertEquals("CN=A, CN=\"B \"", s);
1687
1688    }
1689
1690    /**
1691     * Inits X500Principal with the string with special characters - B\'space'
1692     * gets Name in RFC2253 format
1693     * compares with expected value of name - B\'space'
1694     */
1695    public void testNameSpaces_RFC2253() throws Exception {
1696        String dn = "CN=A,CN=B\\ ";
1697        X500Principal principal = new X500Principal(dn);
1698        String s = principal.getName(X500Principal.RFC2253);
1699        assertEquals("CN=A,CN=B\\ ", s);
1700
1701    }
1702
1703    /**
1704     * Inits X500Principal with the string with special characters - B\'space'
1705     * gets Name in CANONICAL format
1706     * compares with expected value of name - B\
1707     */
1708    public void testNameSpaces_CANONICAL() throws Exception {
1709        String dn = "CN=A,CN=B\\ ";
1710        X500Principal principal = new X500Principal(dn);
1711        String s = principal.getName(X500Principal.CANONICAL);
1712        assertEquals("cn=a,cn=b", s);
1713
1714    }
1715
1716    /**
1717     * Inits X500Principal with the string with special characters - "B'space''space''space'A"
1718     * gets Name in RFC1779 format
1719     * compares with expected value of name - "B   A"
1720     */
1721    public void testNameSpaces_RFC1779_01() throws Exception {
1722        String dn = "CN=\"B   A\"";
1723        X500Principal principal = new X500Principal(dn);
1724        String s = principal.getName(X500Principal.RFC1779);
1725        assertEquals("CN=B   A", s);
1726
1727    }
1728
1729    /**
1730     * Inits X500Principal with the string with special characters - "B'space''space''space'A"
1731     * gets Name in 2253 format
1732     * compares with expected value of name - B'space''space''space'A
1733     */
1734    public void testNameSpaces_RFC2253_01() throws Exception {
1735        String dn = "CN=\"B   A\"";
1736        X500Principal principal = new X500Principal(dn);
1737        String s = principal.getName(X500Principal.RFC2253);
1738        assertEquals("CN=B   A", s);
1739
1740    }
1741
1742    /**
1743     * Inits X500Principal with the string with special characters - "B'space''space''space'A"
1744     * gets Name in CANONICAL format
1745     * compares with expected value of name - b'space'a
1746     */
1747    public void testNameSpaces_CANONICAL_01() throws Exception {
1748        String dn = "CN=\"B   A\"";
1749        X500Principal principal = new X500Principal(dn);
1750        String s = principal.getName(X500Principal.CANONICAL);
1751        assertEquals("cn=b a", s);
1752
1753    }
1754
1755    /**
1756     * Inits X500Principal with the string with special characters - \\'space''space'B
1757     * gets Name in RFC1779 format
1758     * compares with expected value of name - "  B"
1759     */
1760    public void testNameSpaces_RFC1779_02() throws Exception {
1761        String dn = "CN=\\  B";
1762        X500Principal principal = new X500Principal(dn);
1763        String s = principal.getName(X500Principal.RFC1779);
1764        assertEquals("CN=\"  B\"", s);
1765
1766    }
1767
1768    /**
1769     * Inits X500Principal with the string with special characters - \\'space''space'B
1770     * gets Name in RFC1779 format
1771     * compares with expected value of name - \'space''space'B
1772     */
1773    public void testNameSpaces_RFC2253_02() throws Exception {
1774        String dn = "CN=\\  B";
1775        X500Principal principal = new X500Principal(dn);
1776        String s = principal.getName(X500Principal.RFC2253);
1777        assertEquals("CN=\\  B", s);
1778
1779    }
1780
1781    /**
1782     * Inits X500Principal with the string with special characters - \\'space''space'B
1783     * gets Name in CANONICAL format
1784     * compares with expected value of name - \'space''space'b
1785     */
1786    public void testNameSpaces_CANONICAL_02() throws Exception {
1787        String dn = "CN=\\  B";
1788        X500Principal principal = new X500Principal(dn);
1789        String s = principal.getName(X500Principal.CANONICAL);
1790        assertEquals("cn=b", s);
1791
1792    }
1793
1794    /**
1795     * Inits X500Principal with the string with special characters - ""B
1796     * checks if the proper exception is thrown
1797     */
1798    public void testNameQu() throws Exception {
1799        String dn = "CN=\"\"B";
1800        try {
1801            new X500Principal(dn);
1802            fail("No IllegalArgumentException on improper string");
1803        } catch (IllegalArgumentException e) {
1804        }
1805    }
1806
1807    /**
1808     * Inits X500Principal with the string with special characters - "A\"B"
1809     * gets Name in RFC1779 format
1810     * compares with expected value of name - "A\"B"
1811     */
1812    public void testNameQu_RFC1779_2() throws Exception {
1813        String dn = "CN=\"A\\\"B\"";
1814        X500Principal principal = new X500Principal(dn);
1815        String s = principal.getName(X500Principal.RFC1779);
1816        assertEquals("CN=\"A\\\"B\"", s);
1817    }
1818
1819    /**
1820     * Inits X500Principal with the string with special characters - "A\"B"
1821     * gets Name in RFC2253 format
1822     * compares with expected value of name - A\"B
1823     */
1824    public void testNameQu_RFC2253_2() throws Exception {
1825        String dn = "CN=\"A\\\"B\"";
1826        X500Principal principal = new X500Principal(dn);
1827        String s = principal.getName(X500Principal.RFC2253);
1828        assertEquals("CN=A\\\"B", s);
1829    }
1830
1831    /**
1832     * Inits X500Principal with the string with special characters - "A\"B"
1833     * gets Name in CANONICAL format
1834     * compares with expected value of name - a\"b
1835     */
1836    public void testNameQu_CANONICAL_2() throws Exception {
1837        String dn = "CN=\"A\\\"B\"";
1838        X500Principal principal = new X500Principal(dn);
1839        String s = principal.getName(X500Principal.CANONICAL);
1840        assertEquals("cn=a\\\"b", s);
1841
1842    }
1843
1844    /**
1845     * Inits X500Principal with the string with special characters - "A\""
1846     * gets Name in RFC1779 format
1847     * compares with expected value of name - "A\""
1848     */
1849    public void testNameQu_RFC1779_3() throws Exception {
1850        String dn = "CN=\"A\\\"\"";
1851        X500Principal principal = new X500Principal(dn);
1852        String s = principal.getName(X500Principal.RFC1779);
1853        assertEquals("CN=\"A\\\"\"", s);
1854    }
1855
1856    /**
1857     * Inits X500Principal with the string with special characters - "A\""
1858     * gets Name in RFC2253 format
1859     * compares with expected value of name - A\"
1860     */
1861    public void testNameQu_RFC2253_3() throws Exception {
1862        String dn = "CN=\"A\\\"\"";
1863        X500Principal principal = new X500Principal(dn);
1864        String s = principal.getName(X500Principal.RFC2253);
1865        assertEquals("CN=A\\\"", s);
1866    }
1867
1868    /**
1869     * Inits X500Principal with the string with special characters - "A\""
1870     * gets Name in CANONICAL format
1871     * compares with expected value of name - A\"
1872     */
1873    public void testNameQu_CANONICAL_3() throws Exception {
1874        String dn = "CN=\"A\\\"\"";
1875        X500Principal principal = new X500Principal(dn);
1876        String s = principal.getName(X500Principal.CANONICAL);
1877        assertEquals("cn=a\\\"", s);
1878
1879    }
1880
1881    /**
1882     * Inits X500Principal with the string with special characters - "A\", C=B"
1883     * gets Name in RFC1779 format
1884     * compares with expected value of name - "A\", C=B"
1885     */
1886    public void testNameQu_4() throws Exception {
1887        String dn = "CN=\"A\\\", C=B\"";
1888        X500Principal principal = new X500Principal(dn);
1889        String s = principal.getName(X500Principal.RFC1779);
1890        assertEquals("CN=\"A\\\", C=B\"", s);
1891
1892    }
1893
1894    /**
1895     * Inits X500Principal with the string with special characters - CN="A\\", C=B
1896     * gets Name in RFC1779 format
1897     * compares with expected value of name - CN="A\\", C=B
1898     */
1899    public void testNameQu_5() throws Exception {
1900        String dn = "CN=\"A\\\\\", C=B";
1901        X500Principal principal = new X500Principal(dn);
1902        String s = principal.getName(X500Principal.RFC1779);
1903        assertEquals("CN=\"A\\\\\", C=B", s);
1904
1905    }
1906
1907    /**
1908     * Inits X500Principal with the string with special characters - CN=A\nB
1909     * gets Name in RFC1779 format
1910     * compares with expected value of name - CN="A\nB"
1911     */
1912    public void testNameCR_RFC1779() throws Exception {
1913        String dn = "CN=A\nB";
1914        X500Principal principal = new X500Principal(dn);
1915        String s = principal.getName(X500Principal.RFC1779);
1916        assertEquals("CN=A\nB", s);
1917    }
1918
1919    /**
1920     * Inits X500Principal with the string with special characters - CN=A\nB
1921     * gets Name in RFC2253 format
1922     * compares with expected value of name - CN=A\nB
1923     */
1924    public void testNameCR_RFC2253() throws Exception {
1925        String dn = "CN=A\nB";
1926        X500Principal principal = new X500Principal(dn);
1927        String s = principal.getName(X500Principal.RFC2253);
1928        assertEquals("CN=A\nB", s);
1929    }
1930
1931    /**
1932     * Inits X500Principal with the string with special characters - CN=A\nB
1933     * gets Name in CANONICAL format
1934     * compares with expected value of name - cn=a\nb
1935     */
1936    public void testNameCR_CANONICAL() throws Exception {
1937        String dn = "CN=A\nB";
1938        X500Principal principal = new X500Principal(dn);
1939        String s = principal.getName(X500Principal.CANONICAL);
1940        assertEquals("cn=a\nb", s);
1941    }
1942
1943    public static final String[] RFC2253_SPECIAL = new String[] { ",", "=",
1944            "+", "<", ">", "#", ";" };
1945
1946    public void testValidDN() throws Exception {
1947
1948        TestList list = new TestList();
1949
1950        list.add("", "", "", "", new byte[] { 0x30, 0x00 }); // empty RDN sequence
1951
1952        // sequence of RDN: RDN *("," RDN)
1953        list.add("CN=A,C=B", "CN=A,C=B", "CN=A, C=B", "cn=a,c=b");
1954        list.add("C=B,CN=A", "C=B,CN=A", "C=B, CN=A", "c=b,cn=a");
1955        list.add("CN=A,CN=A", "CN=A,CN=A", "CN=A, CN=A", "cn=a,cn=a"); // duplicate RDNs
1956
1957        // sequence of RDN: RFC 1779 compatibility
1958        list.add("CN=A , C=B", "CN=A,C=B", "CN=A, C=B");
1959        list.add("CN=A  ,  C=B", "CN=A,C=B", "CN=A, C=B");
1960        list.add("CN=A;C=B", "CN=A,C=B", "CN=A, C=B");
1961        list.add("CN=A ; C=B", "CN=A,C=B", "CN=A, C=B");
1962        //FIXME list.add("CN=A\r,\rC=B", "CN=A,C=B"); // <CR> & comma => comma
1963        list.add("  CN=A,C=B  ", "CN=A,C=B", "CN=A, C=B"); // spaces at beg&end
1964        list.add("  CN=A,C=\"B\"  ", "CN=A,C=B", "CN=A, C=B"); // spaces at beg&end
1965
1966        // set of ATAV: ATAV *("+" ATAV)
1967        list.add("CN=A+ST=CA", "CN=A+ST=CA", "CN=A + ST=CA", "cn=a+st=ca");
1968        list.add("CN=A+CN=A", "CN=A+CN=A", "CN=A + CN=A", "cn=a+cn=a"); // duplicate AT
1969        list
1970                .add("2.5.4.3=A+2.5.4.3=A", "CN=A+CN=A", "CN=A + CN=A",
1971                        "cn=a+cn=a"); // duplicate AT
1972
1973        // set of ATAV: RFC 1779 compatibility
1974        list.add("CN=A + ST=CA", "CN=A+ST=CA", "CN=A + ST=CA");
1975        list.add("CN=A  +  ST=CA", "CN=A+ST=CA", "CN=A + ST=CA");
1976        //FIXME list.add("CN=A\r+\rST=CA", "CN=A+ST=CA"); // <CR> & '+' => '+'
1977
1978        // ATAV = AttributeType "=" AttributeValue
1979        list.add("CN=A", "CN=A", "CN=A");
1980        list.add("cn=A", "CN=A", "CN=A"); // AT case insensitive
1981        list.add("cN=A", "CN=A", "CN=A"); // AT case insensitive
1982        list.add("cn=a", "CN=a", "CN=a"); // AT case insensitive
1983
1984        // ATAV : RFC 1779 compatibility
1985        list.add("CN = A", "CN=A", "CN=A");
1986        list.add("CN  =  A", "CN=A", "CN=A");
1987        // FIXME list.add("CN\r=\rA", "CN=A"); // <CR> & '=' => '='
1988
1989        // AttributeType = <name string> | <OID>
1990        // testing OID case :  OID => <name string>
1991        // tested all OIDs from RFC 2253 (2.3) and RFC 1779 (Table 1)
1992
1993        // different variants of 2.5.4.3 (CN) OID
1994        list.add("OID.2.5.4.3=A", "CN=A", "CN=A");
1995        list.add("oid.2.5.4.3=A", "CN=A", "CN=A");
1996        list.add("2.5.4.3=A", "CN=A", "CN=A");
1997        list.add("02.5.4.3=A", "CN=A", "CN=A"); // first: 02 => 2
1998        list.add("2.5.4.0003=A", "CN=A", "CN=A"); // last: 0003 => 3
1999
2000        // the rest of OIDs
2001        list.add("2.5.4.7=A", "L=A", "L=A", "l=a");
2002        list.add("2.5.4.8=A", "ST=A", "ST=A", "st=a");
2003        list.add("2.5.4.10=A", "O=A", "O=A", "o=a");
2004        list.add("2.5.4.11=A", "OU=A", "OU=A", "ou=a");
2005        list.add("2.5.4.6=A", "C=A", "C=A", "c=a");
2006        list.add("2.5.4.9=A", "STREET=A", "STREET=A", "street=a");
2007        list.add("0.9.2342.19200300.100.1.25=A", "DC=A",
2008                "OID.0.9.2342.19200300.100.1.25=A", "dc=a");
2009        list.add("0.9.2342.19200300.100.1.1=A", "UID=A",
2010                "OID.0.9.2342.19200300.100.1.1=A", "uid=a");
2011
2012        // attribute types from RFC 2459 (see Appendix A)
2013        // keywords are from the API spec
2014        list.add("T=A", "2.5.4.12=#130141", "OID.2.5.4.12=A",
2015                "2.5.4.12=#130141");
2016        list.add("DNQ=A", "2.5.4.46=#130141", "OID.2.5.4.46=A",
2017                "2.5.4.46=#130141");
2018        list.add("DNQUALIFIER=A", "2.5.4.46=#130141", "OID.2.5.4.46=A",
2019                "2.5.4.46=#130141");
2020        list.add("SURNAME=A", "2.5.4.4=#130141", "OID.2.5.4.4=A",
2021                "2.5.4.4=#130141");
2022        list.add("GIVENNAME=A", "2.5.4.42=#130141", "OID.2.5.4.42=A",
2023                "2.5.4.42=#130141");
2024        list.add("INITIALS=A", "2.5.4.43=#130141", "OID.2.5.4.43=A",
2025                "2.5.4.43=#130141");
2026        list.add("GENERATION=A", "2.5.4.44=#130141", "OID.2.5.4.44=A",
2027                "2.5.4.44=#130141");
2028        list.add("EMAILADDRESS=A", "1.2.840.113549.1.9.1=#130141",
2029                "OID.1.2.840.113549.1.9.1=A", "1.2.840.113549.1.9.1=#130141",
2030                null, (byte) 0x05); //FIXME bug???
2031        list.add("SERIALNUMBER=A", "2.5.4.5=#130141", "OID.2.5.4.5=A",
2032                "2.5.4.5=#130141");
2033
2034        // AttributeValue => BER encoding (if OID in dotted-decimal form)
2035        // see RFC 2253 (2.4)
2036        list.add("OID.2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
2037        list.add("oid.2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
2038        list.add("2.5.4.12=A", "2.5.4.12=#130141", "OID.2.5.4.12=A");
2039        list.add("1.1=A", "1.1=#130141", "OID.1.1=A");
2040
2041        //
2042        // AttributeValue first alternative : *( stringchar / pair )
2043        // testing pair characters.
2044        //
2045        // Note: for RFC1779 quoted string is returned (unspecified)
2046        //
2047        list.add("CN=", "CN=", "CN="); // zero string chars
2048        list.add("CN= ", "CN=", "CN="); // zero string chars
2049        list.add("CN=A+ST=", "CN=A+ST=", "CN=A + ST="); // zero string chars
2050        list.add("CN=+ST=A", "CN=+ST=A", "CN= + ST=A"); // empty value for 1 RDN
2051        list.add("CN=A+ST= ", "CN=A+ST=", "CN=A + ST="); // empty value for 1 RDN
2052        list.add("CN=+ST=", "CN=+ST=", "CN= + ST="); // empty value for both RDNs
2053        list.add("CN=,ST=B", "CN=,ST=B", "CN=, ST=B"); // empty value for 1 RDN
2054        list.add("CN=,ST=", "CN=,ST=", "CN=, ST="); // empty value for both RDNs
2055        list.add("CN=;ST=B", "CN=,ST=B", "CN=, ST=B"); // empty value for 1 RDN
2056        list.add("CN=;ST=", "CN=,ST=", "CN=, ST="); // empty value for both RDNs
2057        for (String element : RFC2253_SPECIAL) {
2058            // \special
2059            list.add("CN=\\" + element,
2060                    "CN=\\" + element, "CN=\"" + element
2061                            + "\"");
2062
2063            // A + \special + B
2064            list.add("CN=A\\" + element + "B", "CN=A\\"
2065                    + element + "B", "CN=\"A" + element
2066                    + "B\"");
2067        }
2068
2069        // pair = \"
2070        list.add("CN=\\\"", "CN=\\\"", "CN=\"\\\"\"", null, (byte) 0x02);
2071        list.add("CN=\\\"A", "CN=\\\"A", "CN=\"\\\"A\"", null, (byte) 0x02);
2072        list.add("CN=\\\",C=\\\"", "CN=\\\",C=\\\"", "CN=\"\\\"\", C=\"\\\"\"",
2073                null, (byte) 0x02); // 2 RDN
2074        list.add("CN=A\\\"B", "CN=A\\\"B", "CN=\"A\\\"B\"", null, (byte) 0x02); // A\"B
2075        list.add("CN=A ST=B", "CN=A ST\\=B", "CN=\"A ST=B\""); // no RDN separator
2076
2077        // pair = \space
2078        list.add("CN=\\ ", "CN=\\ ", "CN=\" \"", "cn=");
2079
2080        // pair = \hexpair
2081        list.add("CN=\\41", "CN=A", "CN=A"); // 0x41=='A'
2082        list.add("CN=\\41\\2C", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2C=','
2083        list.add("CN=\\41\\2c", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2c=','
2084        list.add("CN=\\D0\\AF", "CN=" + ((char) 1071), "CN=" + ((char) 1071),
2085                new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2086                        0x55, 0x04, 0x03,
2087                        // UTF8 String
2088                        0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // 0xD0AF == the last letter(capital) of Russian alphabet
2089        list.add("CN=\\D0\\AFA\\41", "CN=" + ((char) 1071) + "AA", "CN="
2090                + ((char) 1071) + "AA", new byte[] { 0x30, 0x0F, 0x31, 0x0D,
2091                0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03,
2092                // UTF8 String
2093                0x0C, 0x04, (byte) 0xD0, (byte) 0xAF, 0x41, 0x41 }); // 0xD0AF == the last letter(capital) of Russian alphabet
2094        // UTF-8(0xE090AF) is non-shortest form of UTF-8(0xD0AF)
2095        //FIXME list.add("CN=\\E0\\90\\AF", "CN=" + ((char) 1071), "CN="
2096        //        + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
2097        //        0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
2098        //        // UTF8 String
2099        //        0x0C, 0x02, (byte) 0xD0, (byte) 0xAF });
2100        // UTF-8(0xF08090AF) is non-shortest form of UTF-8(0xD0AF)
2101        //FIXME list.add("CN=\\F0\\80\\90\\AF", "CN=" + ((char) 1071), "CN="
2102        //        + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
2103        //        0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
2104        //        // UTF8 String
2105        //        0x0C, 0x02, (byte) 0xD0, (byte) 0xAF });
2106        //FIXME        list.add("CN=\\D0", "CN=" + ((char) 65533), "CN=" + ((char) 65533),
2107        //                new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2108        //                        0x55, 0x04, 0x03,
2109        //                        // UTF8 String
2110        //                        0x0C, 0x01, 0x3F }); // 0xD0 is not correct UTF8 char => '?'
2111        list.add("CN=\\41+ST=A", "CN=A+ST=A", "CN=A + ST=A"); // 0x41=='A'
2112        list.add("CN=\\41\\2C+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2C=','
2113        list.add("CN=\\41\\2c+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2c=','
2114
2115        // stringchar '=' or not leading '#'
2116        //FIXME RFC 2253 grammar violation: '=' and '#' is a special char
2117        list.add("CN==", "CN=\\=", "CN=\"=\"");
2118        list.add("CN=A=", "CN=A\\=", "CN=\"A=\"");
2119        list.add("CN=A#", "CN=A\\#", "CN=\"A#\"");
2120
2121        // not leading or trailing spaces
2122        list.add("CN=A B", "CN=A B", "CN=A B", "cn=a b");
2123        list.add("CN=A\\ B", "CN=A B", "CN=A B", "cn=a b");
2124        list.add("CN=A \\,B", "CN=A \\,B", "CN=\"A ,B\"", "cn=a \\,b");
2125
2126        //not alphabet chars
2127        list.add("CN=$", "CN=$", "CN=$", new byte[] { 0x30, 0x0C, 0x31, 0x0A,
2128                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
2129                //UTF-8 String: "$"
2130                0x0C, 0x01, 0x24 });
2131        list.add("CN=(", "CN=(", "CN=(", new byte[] { 0x30, 0x0C, 0x31, 0x0A,
2132                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
2133                //PrintableString: "("
2134                0x13, 0x01, 0x28 });
2135
2136        //
2137        //
2138        // AttributeValue second alternative : "#" hexstring
2139        //
2140        //
2141        list.add("CN=#130141", "CN=A", "CN=A", "cn=a"); // ASN1 Printable hex string = 'A'
2142        list.add("CN=#140141", "CN=A", "CN=A", "cn=#140141", new byte[] { 0x30,
2143                0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
2144                0x14, 0x01, 0x41 }); // ASN1 Teletex hex string = 'A'
2145
2146        list.add("CN=#010100", "CN=#010100", "CN=#010100", "cn=#010100"); // ASN1 Boolean = FALSE
2147        list.add("CN=#0101fF", "CN=#0101ff", "CN=#0101FF", "cn=#0101ff"); // ASN1 Boolean = TRUE
2148        //FIXME list.add("CN=#3000", "CN=#3000", "CN=#3000"); // ASN1 Sequence
2149        //FIXME list.add("CN=#0500", "CN=A", "CN=A"); // ASN1 Null
2150        list.add("CN= #0101fF", "CN=#0101ff", "CN=#0101FF", // space at beginning
2151                new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2152                        0x55, 0x04, 0x03, 0x01, 0x01, (byte) 0xFF } // ASN.1 Boolean = TRUE
2153                );
2154        list.add("CN= #0101fF+ST=A", "CN=#0101ff+ST=A", "CN=#0101FF + ST=A",
2155                "cn=#0101ff+st=a"); //space
2156        list.add("CN= #0101fF ", "CN=#0101ff", "CN=#0101FF", // space at the end
2157                new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2158                        0x55, 0x04, 0x03, 0x01, 0x01, (byte) 0xFF } // ASN.1 Boolean = TRUE
2159                , (byte) 0x00);
2160
2161        //FIXME unspecified output for RFC1779
2162        //FIXME list.add("CN=#1C0141", "CN=A", "CN=A"); // ASN1 Universal hex string = 'A'
2163        //FIXME list.add("CN=#1E0141", "CN=A", "CN=A"); // ASN1 Bmp hex string = 'A'
2164
2165        //
2166        // AttributeValue third alternative : " *( quotechar / pair ) "
2167        // quotechar = <any character except '\' or '"' >
2168        //
2169        // Note:
2170        // RFC2253: passed quoted AV string is unquoted, special chars are escaped
2171        // RFC1779: escaped quoted chars are unescaped
2172        //
2173        list.add("CN=\"\"", "CN=", "CN="); // empty quoted string
2174        list.add("CN=\"A\"", "CN=A", "CN=A"); // "A"
2175        for (String element : RFC2253_SPECIAL) {
2176            // "special" => \special
2177            list.add("CN=\"" + element + "\"", "CN=\\"
2178                    + element, "CN=\"" + element + "\"");
2179
2180            // "A + special + B" => A + \special + B
2181            list.add("CN=\"A" + element + "B\"", "CN=A\\"
2182                    + element + "B", "CN=\"A" + element
2183                    + "B\"");
2184        }
2185        for (String element : RFC2253_SPECIAL) {
2186            // "\special" => \special
2187            list.add("CN=\"\\" + element + "\"", "CN=\\"
2188                    + element, "CN=\"" + element + "\"");
2189
2190            // "A + \special + B" => A + \special + B
2191            list.add("CN=\"A\\" + element + "B\"", "CN=A\\"
2192                    + element + "B", "CN=\"A" + element
2193                    + "B\"");
2194        }
2195        list.add("CN=\"\\\"\"", "CN=\\\"", "CN=\"\\\"\"", null, (byte) 0x02); // "\""
2196        list.add("CN=\"A\\\"B\"", "CN=A\\\"B", "CN=\"A\\\"B\"", null,
2197                (byte) 0x02); // "A\"B"
2198
2199        // pair = \hexpair (test cases are the same as for the first alternative)
2200        list.add("CN=\"\\41\"", "CN=A", "CN=A"); // 0x41=='A'
2201        list.add("CN=\"\\41\\2C\"", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2C=','
2202        list.add("CN=\"\\41\\2c\"", "CN=A\\,", "CN=\"A,\""); // 0x41=='A', 0x2c=','
2203        list.add("CN=\"\\D0\\AF\"", "CN=" + ((char) 1071), "CN="
2204                + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
2205                0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
2206                // UTF8 String
2207                0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // 0xD0AF == the last letter(capital) of Russian alphabet
2208        list.add("CN=\"\\D0\\AFA\\41\"", "CN=" + ((char) 1071) + "AA", "CN="
2209                + ((char) 1071) + "AA", new byte[] { 0x30, 0x0F, 0x31, 0x0D,
2210                0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03,
2211                // UTF8 String
2212                0x0C, 0x04, (byte) 0xD0, (byte) 0xAF, 0x41, 0x41 }); // 0xD0AF == the last letter(capital) of Russian alphabet
2213        list.add("CN=\"\\E0\\90\\AF\"", "CN=" + ((char) 1071), "CN="
2214                + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
2215                0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
2216                // UTF8 String
2217                0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // UTF8(0xE090AF that is not quite correct)== UTF8(0xD0AF) == the last letter(capital) of Russian alphabet
2218        list.add("CN=\"\\F0\\80\\90\\AF\"", "CN=" + ((char) 1071), "CN="
2219                + ((char) 1071), new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30,
2220                0x09, 0x06, 0x03, 0x55, 0x04, 0x03,
2221                // UTF8 String
2222                0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }); // UTF8(0xF08090AF that is not quite correct)== UTF8(0xD0AF) == the last letter(capital) of Russian alphabet
2223
2224        list.add("CN=\"\\41\"+ST=A", "CN=A+ST=A", "CN=A + ST=A"); // 0x41=='A'
2225        list.add("CN=\"\\41\\2C\"+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2C=','
2226        list.add("CN=\"\\41\\2c\"+ST=A", "CN=A\\,+ST=A", "CN=\"A,\" + ST=A"); // 0x41=='A', 0x2c=','
2227
2228        // AttributeValue third alternative : RFC 1779 compatibility
2229        //FIXME list.add("CN=\"\r\"", "CN=\"\r\""); // "<CR>"
2230        //FIXME list.add("CN=\"\\\r\"", "CN=\"\\\r\""); // "\<CR>"
2231
2232        // AttributeValue : RFC 1779 compatibility
2233        list.add("CN=  A  ", "CN=A", "CN=A", "cn=a"); // leading & trailing spaces
2234        list.add("CN=\\  A  ", "CN=\\  A", "CN=\"  A\"", "cn=a", null,
2235                (byte) 0x01); // escaped leading space
2236        list.add("CN=  A \\ ", "CN=A \\ ", "CN=\"A  \"", "cn=a", null,
2237                (byte) 0x01); // escaped trailing space
2238
2239        list.add("CN=  \"A\"  ", "CN=A", "CN=A", "cn=a"); // leading & trailing spaces
2240
2241        StringBuffer errorMsg = new StringBuffer();
2242        for (int i = 0; i < list.size(); i++) {
2243
2244            Object[] obj = list.get(i);
2245
2246            String dn = (String) obj[0];
2247            String rfc2253 = (String) obj[1];
2248            String rfc1779 = (String) obj[2];
2249            String canonical = (String) obj[3];
2250            byte[] encoded = (byte[]) obj[4];
2251            byte mask = ((byte[]) obj[5])[0];
2252
2253            try {
2254                X500Principal p = new X500Principal(dn);
2255                if (!rfc2253.equals(p.getName(X500Principal.RFC2253))) {
2256                    if (!testing || ((mask & 0x01) == 0)) {
2257
2258                        errorMsg.append("RFC2253: " + i);
2259                        errorMsg.append("\tparm: '" + dn + "'");
2260                        errorMsg.append("\t\texpected: '" + rfc2253 + "'");
2261                        errorMsg.append("\treturned: '"
2262                                + p.getName(X500Principal.RFC2253) + "'\n");
2263                    }
2264                }
2265
2266                if (!rfc1779.equals(p.getName(X500Principal.RFC1779))) {
2267                    if (!testing || ((mask & 0x02) == 0)) {
2268
2269                        errorMsg.append("RFC1779: " + i);
2270                        errorMsg.append("\tparm: '" + dn + "'");
2271                        errorMsg.append("\t\texpected: " + rfc1779 + "'");
2272                        errorMsg.append("\treturned: '"
2273                                + p.getName(X500Principal.RFC1779) + "'\n");
2274                    }
2275                }
2276
2277                if (canonical != null) {
2278                    if (!canonical.equals(p.getName(X500Principal.CANONICAL))) {
2279                        if (!testing || ((mask & 0x04) == 0)) {
2280
2281                            errorMsg.append("CANONICAL: " + i);
2282                            errorMsg.append("\tparm: '" + dn + "'");
2283                            errorMsg.append("\t\texpected: " + canonical + "'");
2284                            errorMsg.append("\treturned: '"
2285                                    + p.getName(X500Principal.CANONICAL)
2286                                    + "'\n");
2287                        }
2288                    }
2289                }
2290
2291                if (encoded != null) {
2292                    if (!Arrays.equals(encoded, p.getEncoded())) {
2293                        if (!testing || ((mask & 0x08) == 0)) {
2294
2295                            errorMsg.append("Unexpected encoding for: " + i
2296                                    + ", dn= '" + dn + "'\n");
2297
2298                            System.out.println("\nI " + i);
2299                            byte[] enc = p.getEncoded();
2300                            for (byte element : enc) {
2301                                System.out.print(", 0x"
2302                                        + Integer.toHexString(element));
2303                            }
2304                        }
2305                    }
2306                }
2307            } catch (IllegalArgumentException e) {
2308                errorMsg.append("IllegalArgumentException: " + i);
2309                errorMsg.append("\tparm: '" + dn + "'\n");
2310            } catch (Exception e) {
2311                errorMsg.append("Exception: " + i);
2312                errorMsg.append("\tparm: '" + dn + "'");
2313                errorMsg.append("\texcep: " + e.getClass().getName() + "\n");
2314            }
2315        }
2316
2317        if (errorMsg.length() != 0) {
2318            fail(errorMsg.toString());
2319        }
2320
2321    }
2322
2323    public void testInvalidDN() {
2324        String[] illegalDN = new String[] {
2325        // RDN
2326                //FIXME " ", // space only
2327                "CN", // attribute type only
2328                "CN=A;", // RFC 1779: BNF allows this, but ...
2329                "CN=A,", // RFC 1779: BNF allows this, but ...
2330                ",CN=A", // no AttributeType for first RDN
2331                "CN=,A", // no AttributeType for second RDN
2332                "CN=A+", // no AttributeTypeAndValue for second RDN
2333                "CN=#130141 ST=B", // no RDN separator
2334
2335                // AttributeType = <name string> | <OID>
2336                "AAA=A", // no such <name string>
2337                "1..1=A", // wrong OID
2338                ".1.1=A", // wrong OID
2339                "11=A", // wrong OID
2340                "1=A", // wrong OID
2341                "AID.1.1=A", // wrong OID
2342                "1.50=A", // wrong OID
2343                "5.1.0=A", // wrong OID
2344                "2.-5.4.3=A", // wrong OID
2345                "2.5.-4.3=A", // wrong OID
2346                "2.5.4-.3=A", // wrong OID
2347                //FIXME "2.5.4.-3=A", // wrong OID
2348
2349                // AttributeValue first alternative : *( stringchar / pair )
2350                "CN=,", // stringchar = ','
2351                //FIXME "CN==",
2352                "CN=+", // stringchar = '+'
2353                //FIXME "CN=<", // stringchar = '<'
2354                //FIXME "CN=>", // stringchar = '>'
2355                "CN=#", // stringchar = '#'
2356                //FIXME "CN=Z#", // stringchar = '#'
2357                "CN=;", // stringchar = ';'
2358                "CN=\"", // stringchar = "
2359                //FIXME "CN=A\"B", // stringchar = "
2360                "CN=\\", // stringchar = \
2361                "CN=A\\", // stringchar = \
2362                "CN=A\\B", // stringchar = \
2363                "CN=\\z", // invalid pair = \z
2364                "CN=\\4", // invalid pair = \4
2365                "CN=\\4Z", // invalid pair = \4Z
2366                "CN=\\4\\2c", // invalid pair = \4\2c
2367
2368                // AttributeValue second alternative : "#" hexstring
2369                "CN=#", // no hex string
2370                "CN=#2", // no hex pair
2371                "CN=#22", // hexpair is not BER encoding
2372                "CN=#0001", // invalid BER encoding (missed content)
2373                "CN=#000201", // invalid BER encoding (wrong length)
2374                "CN=#0002010101", // invalid BER encoding (wrong length)
2375                "CN=#00FF", // invalid BER encoding (wrong length)
2376                "CN=#ZZ", // not hex pair
2377
2378                // FIXME boolean with indefinite length
2379                //"CN=#0100010000", // invalid BER encoding (wrong length)
2380
2381                // AttributeValue third alternative : " *( quotechar / pair ) "
2382                "CN=\"A\" B", // TODO comment me
2383                "CN=\"A\\", // TODO comment me
2384                "CN=\"\\4\"", // invalid pair = \4
2385                "CN=\"\\4Z\"", // invalid pair = \4Z
2386                "CN=\"\\4\\2c\"", // invalid pair = \4\2c
2387        };
2388
2389        StringBuffer errorMsg = new StringBuffer();
2390        for (String element : illegalDN) {
2391
2392            try {
2393                new X500Principal(element);
2394                errorMsg.append("No IllegalArgumentException: '" + element
2395                        + "'\n");
2396            } catch (IllegalArgumentException e) {
2397            }
2398        }
2399
2400        if (errorMsg.length() != 0) {
2401            fail(errorMsg.toString());
2402        }
2403    }
2404
2405    public void testValidEncoding() {
2406        TestList list = new TestList();
2407
2408        //
2409        // Empty
2410        //
2411        list.add(new byte[] { 0x30, 0x00 }, "", "", "");
2412        list.add(new byte[] { 0x30, 0x02, 0x31, 0x00 }, "", "", ""); //??? invalid size constraints
2413
2414        //
2415        // Known OID + string with different tags(all string)
2416        //
2417        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2418                0x55, 0x04, 0x03,
2419                // PrintableString
2420                0x13, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
2421        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2422                0x55, 0x04, 0x03,
2423                // TeletexString
2424                0x14, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=#14015a");
2425        //FIXME:compatibility        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2426        //                0x55, 0x04, 0x03,
2427        //                // UniversalString
2428        //                0x1C, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
2429        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2430                0x55, 0x04, 0x03,
2431                // UTF8String
2432                0x0C, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
2433        //FIXME:compatibility        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2434        //                0x55, 0x04, 0x03,
2435        //                // BMPString
2436        //                0x1E, 0x01, 0x5A }, "CN=Z", "CN=Z", "cn=z");
2437
2438        //
2439        // Unknown OID + string with different tags(all string)
2440        //
2441        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2442                0x00,
2443                // PrintableString
2444                0x13, 0x01, 0x5A }, "0.0=#13015a", "OID.0.0=Z", "0.0=#13015a");
2445        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2446                0x00,
2447                // TeletexString
2448                0x14, 0x01, 0x5A }, "0.0=#14015a", "OID.0.0=Z", "0.0=#14015a");
2449        //FIXME:compatibility        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2450        //                0x00,
2451        //                // UniversalString
2452        //                0x1C, 0x01, 0x5A }, "0.0=#1c015a", "OID.0.0=Z", "cn=z");
2453        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2454                0x00,
2455                // UTF8String
2456                0x0C, 0x01, 0x5A }, "0.0=#0c015a", "OID.0.0=Z", "0.0=#0c015a");
2457        //FIXME:compatibility        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2458        //                0x00,
2459        //                // BMPString
2460        //                0x1E, 0x01, 0x5A }, "0.0=#1e015a", "OID.0.0=Z", "cn=z");
2461
2462        //
2463        // Known OID + not a string value
2464        //
2465        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2466                0x55, 0x04, 0x03,
2467                // Boolean
2468                0x01, 0x01, (byte) 0xFF }, "CN=#0101ff", "CN=#0101FF",
2469                "cn=#0101ff");
2470        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2471                0x55, 0x04, 0x03,
2472                // Integer
2473                0x02, 0x01, 0x0F }, "CN=#02010f", "CN=#02010F", "cn=#02010f");
2474        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2475                0x55, 0x04, 0x03,
2476                // BitString
2477                0x03, 0x01, 0x00 }, "CN=#030100", "CN=#030100", "cn=#030100");
2478        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2479                0x55, 0x04, 0x03,
2480                // SEQUENCE
2481                0x30, 0x01, 0x0A }, "CN=#30010a", "CN=#30010A", "cn=#30010a");
2482
2483        //
2484        // unknown OID + not a string value
2485        //
2486        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2487                0x00,
2488                // Boolean
2489                0x01, 0x01, (byte) 0xFF }, "0.0=#0101ff", "OID.0.0=#0101FF",
2490                "0.0=#0101ff");
2491        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2492                0x00,
2493                // Integer
2494                0x02, 0x01, 0x0F }, "0.0=#02010f", "OID.0.0=#02010F",
2495                "0.0=#02010f");
2496        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2497                0x00,
2498                // BitString
2499                0x03, 0x01, 0x00 }, "0.0=#030100", "OID.0.0=#030100",
2500                "0.0=#030100");
2501        list.add(new byte[] { 0x30, 0x0A, 0x31, 0x08, 0x30, 0x06, 0x06, 0x01,
2502                0x00,
2503                // SEQUENCE
2504                0x30, 0x01, 0x0A }, "0.0=#30010a", "OID.0.0=#30010A",
2505                "0.0=#30010a");
2506
2507        //
2508        // Known OID + UTF-8 string with chars to be escaped
2509        //
2510
2511        // spaces
2512        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2513                0x55, 0x04, 0x03,
2514                // UTF8String: a single space char
2515                0x0C, 0x01, 0x20 }, "CN=\\ ", "CN=\" \"", "cn=");
2516        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2517                0x55, 0x04, 0x03,
2518                // UTF8String: a space char at the beginning
2519                0x0C, 0x02, 0x20, 0x5A }, "CN=\\ Z", "CN=\" Z\"", "cn=z");
2520        list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2521                0x55, 0x04, 0x03,
2522                // UTF8String: two space chars at the beginning
2523                0x0C, 0x03, 0x20, 0x20, 0x5A }, "CN=\\  Z", "CN=\"  Z\"",
2524                "cn=z", (byte) 0x01);
2525        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2526                0x55, 0x04, 0x03,
2527                // UTF8String: a space char at the end
2528                0x0C, 0x02, 0x5A, 0x20 }, "CN=Z\\ ", "CN=\"Z \"", "cn=z");
2529        list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2530                0x55, 0x04, 0x03,
2531                // UTF8String: two space chars at the end
2532                0x0C, 0x03, 0x5A, 0x20, 0x20 }, "CN=Z \\ ", "CN=\"Z  \"",
2533                "cn=z", (byte) 0x01);
2534
2535        // special chars
2536        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2537                0x55, 0x04, 0x03,
2538                // UTF8String: a '#' char at the beginning
2539                0x0C, 0x02, 0x23, 0x5A }, "CN=\\#Z", "CN=\"#Z\"", "cn=\\#z");
2540        list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2541                0x55, 0x04, 0x03,
2542                // UTF8String: two '#' chars
2543                0x0C, 0x03, 0x23, 0x5A, 0x23 }, "CN=\\#Z\\#", "CN=\"#Z#\"",
2544                "cn=\\#z#");
2545        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2546                0x55, 0x04, 0x03,
2547                // UTF8String: ','
2548                0x0C, 0x02, 0x5A, 0x2C }, "CN=Z\\,", "CN=\"Z,\"", "cn=z\\,");
2549        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2550                0x55, 0x04, 0x03,
2551                // UTF8String: '+'
2552                0x0C, 0x02, 0x5A, 0x2B }, "CN=Z\\+", "CN=\"Z+\"", "cn=z\\+");
2553        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2554                0x55, 0x04, 0x03,
2555                // UTF8String: '"'
2556                0x0C, 0x02, 0x5A, 0x22 }, "CN=Z\\\"", "CN=\"Z\\\"\"",
2557                "cn=z\\\"", (byte) 0x02);
2558        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2559                0x55, 0x04, 0x03,
2560                // UTF8String: '\'
2561                0x0C, 0x02, 0x5A, 0x5C }, "CN=Z\\\\", "CN=\"Z\\\\\"",
2562                "cn=z\\\\", (byte) 0x02);
2563        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2564                0x55, 0x04, 0x03,
2565                // UTF8String: '<'
2566                0x0C, 0x02, 0x5A, 0x3C }, "CN=Z\\<", "CN=\"Z<\"", "cn=z\\<");
2567        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2568                0x55, 0x04, 0x03,
2569                // UTF8String: '>'
2570                0x0C, 0x02, 0x5A, 0x3E }, "CN=Z\\>", "CN=\"Z>\"", "cn=z\\>");
2571        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2572                0x55, 0x04, 0x03,
2573                // UTF8String: ';'
2574                0x0C, 0x02, 0x5A, 0x3B }, "CN=Z\\;", "CN=\"Z;\"", "cn=z\\;");
2575        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2576                0x55, 0x04, 0x03,
2577                // UTF8String: '='
2578                0x0C, 0x02, 0x5A, 0x3D }, "CN=Z\\=", "CN=\"Z=\"", "cn=z=");
2579        //FIXME        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2580        //                0x55, 0x04, 0x03,
2581        //                // UTF8String: ';'
2582        //                0x0C, 0x02, 0x5A, 0x0D }, "CN=Z\\\r", "CN=\"Z\r\"", "cn=z");
2583
2584        // combinations
2585        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2586                0x55, 0x04, 0x03,
2587                // UTF8String: '\ '
2588                0x0C, 0x02, 0x5C, 0x20 }, "CN=\\\\\\ ", "CN=\"\\\\ \"",
2589                "cn=\\\\", (byte) 0x02);
2590        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2591                0x55, 0x04, 0x03,
2592                // UTF8String: ' \'
2593                0x0C, 0x02, 0x20, 0x5C }, "CN=\\ \\\\", "CN=\" \\\\\"",
2594                "cn=\\\\", (byte) 0x02);
2595        list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2596                0x55, 0x04, 0x03,
2597                // UTF8String: ' \ '
2598                0x0C, 0x03, 0x20, 0x5C, 0x20 }, "CN=\\ \\\\\\ ",
2599                "CN=\" \\\\ \"", "cn=\\\\", (byte) 0x02);
2600        list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2601                0x55, 0x04, 0x03,
2602                // UTF8String: 'Z Z' no escaping
2603                0x0C, 0x03, 0x5A, 0x20, 0x5A }, "CN=Z Z", "CN=Z Z", "cn=z z");
2604        list.add(new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
2605                0x55, 0x04, 0x03,
2606                // UTF8String: 'Z  Z' no escaping
2607                0x0C, 0x04, 0x5A, 0x20, 0x20, 0x5A }, "CN=Z  Z", "CN=Z  Z",
2608                "cn=z z", (byte) 0x02);
2609        list.add(new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
2610                0x55, 0x04, 0x03,
2611                // UTF8String: ' #Z ' no escaping
2612                0x0C, 0x04, 0x20, 0x23, 0x5A, 0x20 }, "CN=\\ \\#Z\\ ",
2613                "CN=\" #Z \"", "cn=#z");
2614
2615        //
2616        // Special cases
2617        //
2618        //        list.add(new byte[] {
2619        //        // Name
2620        //                0x30, 0x13, 0x31, 0x11, 0x30, 0x0F,
2621        //                // OID
2622        //                0x06, 0x0A, 0x09, (byte) 0x92, 0x26, (byte) 0x89, (byte) 0x93,
2623        //                (byte) 0xF2, 0x2C, 0x64, 0x01, 0x01,
2624        //                // ANY
2625        //                0x13, 0x01, 0x41 }, "UID=A", "OID.0.9.2342.19200300.100.1.1=A",
2626        //                "uid=a");
2627        //
2628        //        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2629        //                0x55, 0x04, 0x03, 0x1E, 0x01, 0x5A }, "CN=Z", "CN=Z",
2630        //                "cn=#1e015a");
2631
2632        //
2633        // Multi-valued DN
2634        //
2635        list.add(new byte[] { 0x30, 0x14, 0x31, 0x12,
2636        // 1
2637                0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
2638                // UTF8String: 'Z'
2639                0x0C, 0x01, 0x5A,
2640                //2
2641                0x30, 0x06, 0x06, 0x01, 0x01,
2642                // UTF8String: 'A'
2643                0x0C, 0x01, 0x41 }, "CN=Z+0.1=#0c0141", "CN=Z + OID.0.1=A",
2644                "cn=z+0.1=#0c0141");
2645
2646        //
2647        //
2648        //
2649        list.add(new byte[] { 0x30, 0x0D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
2650                0x55, 0x04, 0x03,
2651                // UTF8String: the last letter(capital) of Russian alphabet
2652                0x0C, 0x02, (byte) 0xD0, (byte) 0xAF }, "CN=" + ((char) 1071),
2653                "CN=" + ((char) 1071), "cn=" + ((char) 1103));
2654        // FIXME list.add(new byte[] { 0x30, 0x0E, 0x31, 0x0C, 0x30, 0x0A, 0x06, 0x03,
2655        //        0x55, 0x04, 0x03,
2656        //        // UTF8String: the last letter(capital) of Russian alphabet
2657        //        0x0C, 0x03, (byte) 0xE0, (byte) 0x90, (byte) 0xAF }, "CN="
2658        //        + ((char) 1071), "CN=" + ((char) 1071), "cn=" + ((char) 1103));
2659        // FIXME list.add(
2660        //        new byte[] { 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03,
2661        //                0x55, 0x04, 0x03,
2662        //                // UTF8String: the last letter(capital) of Russian alphabet
2663        //                0x0C, 0x04, (byte) 0xF0, (byte) 0x80, (byte) 0x90,
2664        //                (byte) 0xAF }, "CN=" + ((char) 1071), "CN="
2665        //                + ((char) 1071), "cn=" + ((char) 1103));
2666        list.add(new byte[] { 0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03,
2667                0x55, 0x04, 0x03,
2668                // PrintableString: char '$' is not in table 8 (X.680)
2669                0x13, 0x01, 0x24 }, "CN=$", "CN=$", "cn=$");
2670
2671        StringBuffer errorMsg = new StringBuffer();
2672        for (int i = 0; i < list.size(); i++) {
2673
2674            Object[] values = list.get(i);
2675            byte[] encoded = (byte[]) values[0];
2676            String rfc2253 = (String) values[1];
2677            String rfc1179 = (String) values[2];
2678            String canonical = (String) values[3];
2679            byte mask = ((byte[]) values[4])[0];
2680
2681            X500Principal p;
2682            try {
2683                p = new X500Principal(encoded);
2684
2685                if (!rfc2253.equals(p.getName(X500Principal.RFC2253))) {
2686                    if (!testing || ((mask & 0x01) == 0)) {
2687                        errorMsg.append("RFC2253: " + i);
2688                        errorMsg.append("\t\texpected: '" + rfc2253 + "'");
2689                        errorMsg.append("\treturned: '"
2690                                + p.getName(X500Principal.RFC2253) + "'\n");
2691                    }
2692                }
2693
2694                if (!rfc1179.equals(p.getName(X500Principal.RFC1779))) {
2695                    if (!testing || ((mask & 0x02) == 0)) {
2696                        errorMsg.append("RFC1779: " + i);
2697                        errorMsg.append("\t\texpected: '" + rfc1179 + "'");
2698                        errorMsg.append("\treturned: '"
2699                                + p.getName(X500Principal.RFC1779) + "'\n");
2700                    }
2701                }
2702
2703                if (!canonical.equals(p.getName(X500Principal.CANONICAL))) {
2704                    if (!testing || ((mask & 0x04) == 0)) {
2705                        errorMsg.append("CANONICAL: " + i);
2706                        errorMsg.append("\t\texpected: " + canonical + "'");
2707                        errorMsg.append("\treturned: '"
2708                                + p.getName(X500Principal.CANONICAL) + "'\n");
2709                    }
2710                }
2711
2712            } catch (IllegalArgumentException e) {
2713                errorMsg.append("\nIllegalArgumentException: " + i + ", for "
2714                        + rfc2253);
2715                continue;
2716            } catch (Exception e) {
2717                errorMsg.append("Exception: " + i + ", for " + rfc2253);
2718                errorMsg.append("\texcep: " + e.getClass().getName() + "\n");
2719                continue;
2720            }
2721
2722        }
2723
2724        if (errorMsg.length() != 0) {
2725            fail(errorMsg.toString());
2726        }
2727    }
2728
2729    @SuppressWarnings("serial")
2730    public static class TestList extends ArrayList<Object[]> {
2731        //
2732        // TODO comment me
2733        //
2734        public void add(String param, String rfc2253, String rfc1779) {
2735            add(param, rfc2253, rfc1779, (byte[]) null);
2736        }
2737
2738        public void add(String param, String rfc2253, String rfc1779,
2739                String canonical) {
2740            add(param, rfc2253, rfc1779, canonical, null);
2741        }
2742
2743        public void add(String param, String rfc2253, String rfc1779,
2744                byte[] encoded) {
2745            add(new Object[] { param, rfc2253, rfc1779, null, encoded,
2746                    emptyMask });
2747        }
2748
2749        public void add(String param, String rfc2253, String rfc1779,
2750                byte[] encoded, byte mask) {
2751            add(new Object[] { param, rfc2253, rfc1779, null, encoded,
2752                    new byte[] { mask } });
2753        }
2754
2755        public void add(String param, String rfc2253, String rfc1779,
2756                String canonical, byte[] encoded) {
2757            add(new Object[] { param, rfc2253, rfc1779, canonical, encoded,
2758                    emptyMask });
2759        }
2760
2761        public void add(String param, String rfc2253, String rfc1779,
2762                String canonical, byte[] encoded, byte mask) {
2763            add(new Object[] { param, rfc2253, rfc1779, canonical, encoded,
2764                    new byte[] { mask } });
2765        }
2766
2767        //
2768        // TODO comment me
2769        //
2770
2771        private static final byte[] emptyMask = new byte[] { 0x00 };
2772
2773        public void add(byte[] encoding, String rfc2253, String rfc1779,
2774                String canonical) {
2775            add(new Object[] { encoding, rfc2253, rfc1779, canonical, emptyMask });
2776        }
2777
2778        public void add(byte[] encoding, String rfc2253, String rfc1779,
2779                String canonical, byte mask) {
2780            add(new Object[] { encoding, rfc2253, rfc1779, canonical,
2781                    new byte[] { mask } });
2782        }
2783    }
2784}