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* @author Vladimir N. Molotkov
19* @version $Revision$
20*/
21
22package tests.security.cert;
23
24import junit.framework.TestCase;
25
26import java.io.IOException;
27import java.security.cert.PolicyQualifierInfo;
28import java.util.Arrays;
29
30/**
31 * PolicyQualifierInfo test
32 *
33 */
34public class PolicyQualifierInfoTest extends TestCase {
35
36
37    /**
38     * Test #1 for <code>PolicyQualifierInfo</code> constructor<br>
39     * Assertion: throws <code>IOException</code> if byte array
40     * parameter does not represent a valid and parsable policy
41     * qualifier info
42     */
43    public final void test_Ctor() throws IOException {
44        try {
45            // pass null
46            new PolicyQualifierInfo(null);
47            fail("No expected NullPointerException");
48        } catch (NullPointerException e) {
49        }
50
51        try {
52            // pass empty array
53            new PolicyQualifierInfo(new byte[0]);
54            fail("IOE expected");
55        } catch (IOException e) {
56        }
57
58
59        try {
60            // pass invalid array
61            new PolicyQualifierInfo(
62                    new byte[] {(byte)0x06, (byte)0x03,
63                            (byte)0x81, (byte)0x34, (byte)0x03});
64            fail("IOE expected");
65        } catch (IOException e) {
66        }
67    }
68
69    /**
70     * Test #2 for <code>PolicyQualifierInfo</code> constructor<br>
71     * Assertion: throws <code>IOException</code> if byte array
72     * parameter does not represent a valid and parsable policy
73     * qualifier info
74     */
75    public final void testPolicyQualifierInfo02() {
76        // get valid encoding
77        byte[] encoding = getDerEncoding();
78        // corrupt root seq length
79        encoding[1] = (byte)0x27;
80
81        try {
82            // pass invalid array
83            new PolicyQualifierInfo(encoding);
84            fail("IOE expected");
85        } catch (IOException e) {
86        }
87
88
89        // get valid encoding
90        encoding = getDerEncoding();
91        // corrupt policy qualifier ID:
92        //  - change OID to the Relative OID
93        encoding[2] = (byte)13;
94        try {
95            // pass invalid array
96            new PolicyQualifierInfo(encoding);
97            fail("IOE expected");
98        } catch (IOException e) {
99        }
100    }
101
102    /**
103     * Test #3 for <code>PolicyQualifierInfo</code> constructor<br>
104     * Assertion: Creates an instance of <code>PolicyQualifierInfo</code>
105     * from the encoded bytes
106     *
107     * @throws IOException
108     */
109    public final void testPolicyQualifierInfo03() throws IOException {
110        // get valid encoding
111        byte[] encoding = getDerEncoding();
112        // pass valid array
113        new PolicyQualifierInfo(encoding);
114    }
115
116    /**
117     * Test #4 for <code>PolicyQualifierInfo</code> constructor<br>
118     * Assertion: The encoded byte array is copied on construction
119     *
120     * @throws IOException
121     */
122    public final void testPolicyQualifierInfo04() throws IOException  {
123        // get valid encoding
124        byte[] encoding = getDerEncoding();
125        byte[] encodingCopy = encoding.clone();
126        // pass valid array
127        PolicyQualifierInfo i = new PolicyQualifierInfo(encodingCopy);
128        // get encoding
129        byte[] encodingRet = i.getEncoded();
130        // check returned array
131        assertTrue(Arrays.equals(encoding, encodingRet));
132        // modify input
133        encodingCopy[0] = (byte)0;
134        // get encoding again
135        byte[] encodingRet1 = i.getEncoded();
136        // check that above modification did not change
137        // internal state of the PolicyQualifierInfo instance
138        assertTrue(Arrays.equals(encoding, encodingRet1));
139    }
140
141    /**
142     * Test #1 for <code>getEncoded()</code> method
143     * Assertion: Returns the ASN.1 DER encoded form of
144     * this <code>PolicyQualifierInfo</code>
145     *
146     * @throws IOException
147     */
148    public final void testGetEncoded01() throws IOException {
149        // get valid encoding
150        byte[] encoding = getDerEncoding();
151        // pass valid array
152        PolicyQualifierInfo i = new PolicyQualifierInfo(encoding);
153        // get encoding
154        byte[] encodingRet = i.getEncoded();
155        // check returned array
156        assertTrue(Arrays.equals(encoding, encodingRet));
157    }
158
159    /**
160     * Test #2 for <code>getEncoded()</code> method
161     * Assertion: a copy is returned each time
162     *
163     * @throws IOException
164     */
165    public final void testGetEncoded02() throws IOException {
166        // get valid encoding
167        byte[] encoding = getDerEncoding();
168        byte[] encodingCopy = encoding.clone();
169        // pass valid array
170        PolicyQualifierInfo i = new PolicyQualifierInfo(encodingCopy);
171        // get encoding
172        byte[] encodingRet = i.getEncoded();
173        // modify returned array
174        encodingRet[0] = (byte)0;
175        // get encoding again
176        byte[] encodingRet1 = i.getEncoded();
177        // check that above modification did not change
178        // internal state of the PolicyQualifierInfo instance
179        assertTrue(Arrays.equals(encoding, encodingRet1));
180    }
181
182    /**
183     * Test #1 for <code>getPolicyQualifier()</code> method
184     * Assertion: Returns the ASN.1 DER encoded form of
185     * this <code>PolicyQualifierInfo</code>
186     *
187     * @throws IOException
188     */
189    public final void testGetPolicyQualifier01() throws IOException {
190        // get valid encoding
191        byte[] encoding = getDerEncoding();
192        // get policy qualifier encoding
193        byte[] pqEncoding = new byte[28];
194        System.arraycopy(encoding, 12, pqEncoding, 0, pqEncoding.length);
195        // pass valid array
196        PolicyQualifierInfo i = new PolicyQualifierInfo(encoding);
197        // get encoding
198        byte[] pqEncodingRet = i.getPolicyQualifier();
199        // check returned array
200        assertTrue(Arrays.equals(pqEncoding, pqEncodingRet));
201    }
202
203    /**
204     * Test #2 for <code>getPolicyQualifier()</code> method
205     * Assertion: a copy is returned each time
206     *
207     * @throws IOException
208     */
209    public final void testGetPolicyQualifier02() throws IOException {
210        // get valid encoding
211        byte[] encoding = getDerEncoding();
212        // get policy qualifier encoding
213        byte[] pqEncoding = new byte[28];
214        System.arraycopy(encoding, 12, pqEncoding, 0, pqEncoding.length);
215        // pass valid array
216        PolicyQualifierInfo i = new PolicyQualifierInfo(encoding);
217        // get encoding
218        byte[] pqEncodingRet = i.getPolicyQualifier();
219        // modify returned array
220        pqEncodingRet[0] = (byte)0;
221        // get encoding again
222        byte[] pqEncodingRet1 = i.getPolicyQualifier();
223        //
224        assertNotSame(pqEncodingRet, pqEncodingRet1);
225        // check that above modification did not change
226        // internal state of the PolicyQualifierInfo instance
227        assertTrue(Arrays.equals(pqEncoding, pqEncodingRet1));
228    }
229
230    /**
231     * Test for <code>getPolicyQualifierId()</code> method
232     * Assertion: Returns the <code>policyQualifierId</code>
233     * field of this <code>PolicyQualifierInfo</code>.
234     * The <code>policyQualifierId</code> is an Object Identifier (OID)
235     * represented by a set of nonnegative integers separated by periods
236     *
237     * @throws IOException
238     */
239    public final void testGetPolicyQualifierId() throws IOException {
240        // get valid encoding
241        byte[] encoding = getDerEncoding();
242        // pass valid array
243        PolicyQualifierInfo i = new PolicyQualifierInfo(encoding);
244        // get OID as String and check it
245        assertEquals("1.3.6.1.5.5.7.2.1", i.getPolicyQualifierId());
246
247        // get valid encoding
248        encoding = getDerEncoding();
249        // change OID to 1.3.98437.82818.1
250        encoding[5] = (byte)0x86;
251        encoding[6] = (byte)0x81;
252        encoding[8] = (byte)0x85;
253        encoding[9] = (byte)0x87;
254        i = new PolicyQualifierInfo(encoding);
255        // get OID as String and check it
256        assertEquals("1.3.98437.82818.1", i.getPolicyQualifierId());
257    }
258
259    /**
260     * Test for <code>toString()</code> method
261     * Assertion: returns description of the contents of this
262     * <code>PolicyQualifierInfo</code> as printable <code>String</code>
263     * @throws IOException
264     *
265     * @throws IOException
266     */
267    public final void testToString() throws IOException {
268        // get valid encoding
269        byte[] encoding = getDerEncoding();
270        // pass valid array
271        PolicyQualifierInfo i = new PolicyQualifierInfo(encoding);
272
273        assertNotNull(i.toString());
274    }
275
276    //
277    // Private stuff
278    //
279
280    /**
281     * Returns valid DER encoding for the following ASN.1 definition
282     * (as specified in RFC 3280 -
283     *  Internet X.509 Public Key Infrastructure.
284     *  Certificate and Certificate Revocation List (CRL) Profile.
285     *  http://www.ietf.org/rfc/rfc3280.txt):
286     *
287     *   PolicyQualifierInfo ::= SEQUENCE {
288     *      policyQualifierId       PolicyQualifierId,
289     *      qualifier               ANY DEFINED BY policyQualifierId
290     *   }
291     *
292     * where policyQualifierId (OID) is
293     *      1.3.6.1.5.5.7.2.1
294     * and qualifier (IA5String) is
295     *      "http://www.qq.com/stmt.txt"
296     *
297     * (data generated by own encoder during test development)
298     */
299    private static final byte[] getDerEncoding() {
300        // DO NOT MODIFY!
301        return  new byte[] {
302            (byte)0x30, (byte)0x26, // tag Seq, length
303              (byte)0x06, (byte)0x08, // tag OID, length
304                (byte)0x2b, (byte)0x06, (byte)0x01, (byte)0x05, // oid value
305                (byte)0x05, (byte)0x07, (byte)0x02, (byte)0x01, // oid value
306              (byte)0x16, (byte)0x1a, // tag IA5String, length
307                (byte)0x68, (byte)0x74, (byte)0x74, (byte)0x70,  // IA5String value
308                (byte)0x3a, (byte)0x2f, (byte)0x2f, (byte)0x77,  // IA5String value
309                (byte)0x77, (byte)0x77, (byte)0x2e, (byte)0x71,  // IA5String value
310                (byte)0x71, (byte)0x2e, (byte)0x63, (byte)0x6f,  // IA5String value
311                (byte)0x6d, (byte)0x2f, (byte)0x73, (byte)0x74,  // IA5String value
312                (byte)0x6d, (byte)0x74, (byte)0x2e, (byte)0x74,  // IA5String value
313                (byte)0x78, (byte)0x74   // IA5String value
314        };
315    }
316}
317