PolicyQualifierInfoTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
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 Vladimir N. Molotkov
20*/
21
22package org.apache.harmony.security.tests.x509;
23
24import java.io.ByteArrayInputStream;
25import java.io.InputStream;
26
27import junit.framework.TestCase;
28
29/**
30 * Test for thread safety of the PolicyQualifierInfo DER decoder
31 * ("DER" stands for "Distinguished Encoding Rules",
32 *  see ITU-T Recommendation X.690,
33 *  http://asn1.elibel.tm.fr)
34 */
35public class PolicyQualifierInfoTest extends TestCase {
36    // Number of test working threads (may be set externally)
37    private static int workersNumber;
38    // Number of test iterations performed by each thread
39    // (may be set externally)
40    private static int iterationsNumber;
41
42    static {
43        try {
44            workersNumber = Integer.parseInt(
45                  System.getProperty("PolicyQualifierInfoTest.workersNumber",
46                    "10"));
47            iterationsNumber = Integer.parseInt(
48                  System.getProperty("PolicyQualifierInfoTest.iterationsNumber",
49                    "10000"));
50        } catch (Exception e) {
51            workersNumber = 10;
52            iterationsNumber = 10000;
53        }
54    }
55
56    // Holder for thread-specific PolicyQualifier DER encodings
57    private static final byte[][] enc = new byte [workersNumber][];
58
59    private volatile boolean arrayPassed = true;
60    private volatile boolean inpstPassed = true;
61
62    // "Valid" reference DER encoding
63    // (generated by own encoder during test development)
64    private static final byte[] encoding = {
65            (byte)0x30, (byte)0x26, // tag Seq, length
66            (byte)0x06, (byte)0x08, // tag OID, length
67              (byte)0x2b, (byte)0x06, (byte)0x01, (byte)0x05, // oid value
68              (byte)0x05, (byte)0x07, (byte)0x02, (byte)0x01, // oid value
69            (byte)0x16, (byte)0x1a, // tag IA5String, length
70              (byte)0x68, (byte)0x74, (byte)0x74, (byte)0x70,  // IA5String value
71              (byte)0x3a, (byte)0x2f, (byte)0x2f, (byte)0x77,  // IA5String value
72              (byte)0x77, (byte)0x77, (byte)0x2e, (byte)0x71,  // IA5String value
73              (byte)0x71, (byte)0x2e, (byte)0x63, (byte)0x6f,  // IA5String value
74              (byte)0x6d, (byte)0x2f, (byte)0x73, (byte)0x74,  // IA5String value
75              (byte)0x6d, (byte)0x74, (byte)0x2e, (byte)0x74,  // IA5String value
76              (byte)0x78, (byte)0x74   // IA5String value
77    };
78
79
80    // Test worker for decoding from byte array
81    private class TestWorker1 extends Thread {
82
83        private final int myIntValue;
84
85        public TestWorker1(int num) {
86            super("Worker_" + num);
87            myIntValue = num;
88        }
89
90        public void run() {
91            for (int i=0; i<iterationsNumber; i++) {
92                try {
93                    // Perform DER decoding:
94                    Object[] decoded =
95                        (Object[])org.apache.harmony.security.x509.
96                        PolicyQualifierInfo.ASN1.decode(
97                                getDerEncoding(myIntValue));
98                    // check OID value
99                    assertEquals(this.getName()+"(OID)",
100                            myIntValue, ((int[])decoded[0])[8]);
101                    // check qualifier
102                    assertEquals(this.getName()+"(QA)",
103                            (byte)myIntValue, ((byte[])decoded[1])[2]);
104                } catch (Throwable e) {
105                    System.err.println(e);
106                    arrayPassed = false;
107                    return;
108                }
109            }
110        }
111    }
112
113    // Test worker for decoding from InputStream
114    private class TestWorker2 extends Thread {
115
116        private final int myIntValue;
117
118        public TestWorker2(int num) {
119            super("Worker_" + num);
120            myIntValue = num;
121        }
122
123        public void run() {
124            for (int i=0; i<iterationsNumber; i++) {
125                try {
126                    // Perform DER decoding:
127                    Object[] decoded =
128                        (Object[])org.apache.harmony.security.x509.
129                        PolicyQualifierInfo.ASN1.decode(
130                                getDerInputStream(myIntValue));
131                    // check OID value
132                    assertEquals(this.getName()+"(OID)",
133                            myIntValue, ((int[])decoded[0])[8]);
134                    // check qualifier
135                    assertEquals(this.getName()+"(QA)",
136                            (byte)myIntValue, ((byte[])decoded[1])[2]);
137                } catch (Throwable e) {
138                    System.err.println(e);
139                    inpstPassed = false;
140                    return;
141                }
142            }
143        }
144    }
145
146    /**
147     * Test 1
148     * @throws InterruptedException
149     */
150    public final void testMtByteArray() throws InterruptedException {
151        Thread[] workers = new Thread[workersNumber];
152        for(int i=0; i<workersNumber; i++) {
153            workers[i] = new TestWorker1(i);
154        }
155        for(int i=0; i<workersNumber; i++) {
156            workers[i].start();
157        }
158        for(int i=0; i<workersNumber; i++) {
159            workers[i].join();
160        }
161        assertTrue(arrayPassed);
162    }
163
164    /**
165     * Test 2
166     * @throws InterruptedException
167     */
168    public final void testMtInputStream() throws InterruptedException {
169        Thread[] workers = new Thread[workersNumber];
170        for(int i=0; i<workersNumber; i++) {
171            workers[i] = new TestWorker2(i);
172        }
173        for(int i=0; i<workersNumber; i++) {
174            workers[i].start();
175        }
176        for(int i=0; i<workersNumber; i++) {
177            workers[i].join();
178        }
179        assertTrue(inpstPassed);
180    }
181
182    //
183    // Generates unique (based on parameter) DER encoding
184    // @param intVal value to be incorporated into the resulting encoding
185    // @return PolicyQualifier DER encoding
186    //
187    private static final byte[] getDerEncoding(int intVal) {
188        setEncArray(intVal);
189        return enc[intVal];
190    }
191
192    //
193    // Generates unique (based on parameter) DER encoding
194    // @param intVal value to be incorporated into the resulting encoding
195    // @return PolicyQualifier DER encoding
196    //
197    private static final InputStream getDerInputStream(int intVal) {
198        setEncArray(intVal);
199        return new ByteArrayInputStream(enc[intVal]);
200    }
201
202    //
203    // Init thread specific data
204    // @param intVal worker thread number
205    //
206    private static void setEncArray(int intVal) {
207        if (enc[intVal] == null) {
208            // make encoding thread-specific
209            byte[] a = encoding.clone();
210            a[11] = (byte)intVal;
211            a[14] = (byte)intVal;
212            enc[intVal] = a;
213        }
214    }
215}
216