001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Vladimir N. Molotkov
020: * @version $Revision$
021: */package org.apache.harmony.security.tests.x509;
022:
023: import java.io.ByteArrayInputStream;
024: import java.io.InputStream;
025:
026: import junit.framework.TestCase;
027:
028: /**
029: * Test for thread safety of the PolicyQualifierInfo DER decoder
030: * ("DER" stands for "Distinguished Encoding Rules",
031: * see ITU-T Recommendation X.690,
032: * http://asn1.elibel.tm.fr)
033: */
034: public class PolicyQualifierInfoTest extends TestCase {
035: // Number of test working threads (may be set externally)
036: private static int workersNumber;
037: // Number of test iterations performed by each thread
038: // (may be set externally)
039: private static int iterationsNumber;
040:
041: static {
042: try {
043: workersNumber = Integer.parseInt(System.getProperty(
044: "PolicyQualifierInfoTest.workersNumber", "10"));
045: iterationsNumber = Integer.parseInt(System
046: .getProperty(
047: "PolicyQualifierInfoTest.iterationsNumber",
048: "10000"));
049: } catch (Exception e) {
050: workersNumber = 10;
051: iterationsNumber = 10000;
052: }
053: }
054:
055: // Holder for thread-specific PolicyQualifier DER encodings
056: private static final byte[][] enc = new byte[workersNumber][];
057:
058: private volatile boolean arrayPassed = true;
059: private volatile boolean inpstPassed = true;
060:
061: // "Valid" reference DER encoding
062: // (generated by own encoder during test development)
063: private static final byte[] encoding = { (byte) 0x30, (byte) 0x26, // tag Seq, length
064: (byte) 0x06, (byte) 0x08, // tag OID, length
065: (byte) 0x2b, (byte) 0x06, (byte) 0x01, (byte) 0x05, // oid value
066: (byte) 0x05, (byte) 0x07, (byte) 0x02, (byte) 0x01, // oid value
067: (byte) 0x16, (byte) 0x1a, // tag IA5String, length
068: (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70, // IA5String value
069: (byte) 0x3a, (byte) 0x2f, (byte) 0x2f, (byte) 0x77, // IA5String value
070: (byte) 0x77, (byte) 0x77, (byte) 0x2e, (byte) 0x71, // IA5String value
071: (byte) 0x71, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, // IA5String value
072: (byte) 0x6d, (byte) 0x2f, (byte) 0x73, (byte) 0x74, // IA5String value
073: (byte) 0x6d, (byte) 0x74, (byte) 0x2e, (byte) 0x74, // IA5String value
074: (byte) 0x78, (byte) 0x74 // IA5String value
075: };
076:
077: // Test worker for decoding from byte array
078: private class TestWorker1 extends Thread {
079:
080: private final int myIntValue;
081:
082: public TestWorker1(int num) {
083: super ("Worker_" + num);
084: myIntValue = num;
085: }
086:
087: public void run() {
088: for (int i = 0; i < iterationsNumber; i++) {
089: try {
090: // Perform DER decoding:
091: Object[] decoded = (Object[]) org.apache.harmony.security.x509.PolicyQualifierInfo.ASN1
092: .decode(getDerEncoding(myIntValue));
093: // check OID value
094: assertEquals(this .getName() + "(OID)", myIntValue,
095: ((int[]) decoded[0])[8]);
096: // check qualifier
097: assertEquals(this .getName() + "(QA)",
098: (byte) myIntValue, ((byte[]) decoded[1])[2]);
099: } catch (Throwable e) {
100: System.err.println(e);
101: arrayPassed = false;
102: return;
103: }
104: }
105: }
106: }
107:
108: // Test worker for decoding from InputStream
109: private class TestWorker2 extends Thread {
110:
111: private final int myIntValue;
112:
113: public TestWorker2(int num) {
114: super ("Worker_" + num);
115: myIntValue = num;
116: }
117:
118: public void run() {
119: for (int i = 0; i < iterationsNumber; i++) {
120: try {
121: // Perform DER decoding:
122: Object[] decoded = (Object[]) org.apache.harmony.security.x509.PolicyQualifierInfo.ASN1
123: .decode(getDerInputStream(myIntValue));
124: // check OID value
125: assertEquals(this .getName() + "(OID)", myIntValue,
126: ((int[]) decoded[0])[8]);
127: // check qualifier
128: assertEquals(this .getName() + "(QA)",
129: (byte) myIntValue, ((byte[]) decoded[1])[2]);
130: } catch (Throwable e) {
131: System.err.println(e);
132: inpstPassed = false;
133: return;
134: }
135: }
136: }
137: }
138:
139: /**
140: * Test 1
141: * @throws InterruptedException
142: */
143: public final void testMtByteArray() throws InterruptedException {
144: Thread[] workers = new Thread[workersNumber];
145: for (int i = 0; i < workersNumber; i++) {
146: workers[i] = new TestWorker1(i);
147: }
148: for (int i = 0; i < workersNumber; i++) {
149: workers[i].start();
150: }
151: for (int i = 0; i < workersNumber; i++) {
152: workers[i].join();
153: }
154: assertTrue(arrayPassed);
155: }
156:
157: /**
158: * Test 2
159: * @throws InterruptedException
160: */
161: public final void testMtInputStream() throws InterruptedException {
162: Thread[] workers = new Thread[workersNumber];
163: for (int i = 0; i < workersNumber; i++) {
164: workers[i] = new TestWorker2(i);
165: }
166: for (int i = 0; i < workersNumber; i++) {
167: workers[i].start();
168: }
169: for (int i = 0; i < workersNumber; i++) {
170: workers[i].join();
171: }
172: assertTrue(inpstPassed);
173: }
174:
175: //
176: // Generates unique (based on parameter) DER encoding
177: // @param intVal value to be incorporated into the resulting encoding
178: // @return PolicyQualifier DER encoding
179: //
180: private static final byte[] getDerEncoding(int intVal) {
181: setEncArray(intVal);
182: return enc[intVal];
183: }
184:
185: //
186: // Generates unique (based on parameter) DER encoding
187: // @param intVal value to be incorporated into the resulting encoding
188: // @return PolicyQualifier DER encoding
189: //
190: private static final InputStream getDerInputStream(int intVal) {
191: setEncArray(intVal);
192: return new ByteArrayInputStream(enc[intVal]);
193: }
194:
195: //
196: // Init thread specific data
197: // @param intVal worker thread number
198: //
199: private static void setEncArray(int intVal) {
200: if (enc[intVal] == null) {
201: // make encoding thread-specific
202: byte[] a = encoding.clone();
203: a[11] = (byte) intVal;
204: a[14] = (byte) intVal;
205: enc[intVal] = a;
206: }
207: }
208: }
|