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