1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package tests.targets.security; 17 18 import junit.framework.Assert; 19 20 import java.security.AlgorithmParameters; 21 import java.security.InvalidAlgorithmParameterException; 22 import java.security.InvalidKeyException; 23 import java.security.Key; 24 import java.security.KeyPair; 25 import java.security.KeyPairGenerator; 26 import java.security.NoSuchAlgorithmException; 27 import java.security.PrivateKey; 28 import java.security.PublicKey; 29 import java.security.Signature; 30 import java.security.SignatureException; 31 import java.security.spec.AlgorithmParameterSpec; 32 import java.security.spec.InvalidParameterSpecException; 33 import java.util.Arrays; 34 35 import javax.crypto.BadPaddingException; 36 import javax.crypto.Cipher; 37 import javax.crypto.IllegalBlockSizeException; 38 import javax.crypto.KeyAgreement; 39 import javax.crypto.KeyGenerator; 40 import javax.crypto.NoSuchPaddingException; 41 import javax.crypto.SecretKey; 42 43 abstract class TestHelper<T/*, U*/> { 44 void test(T testObject) { 45 Assert.fail("test called unimplemented method"); 46 } 47 48 // void test(T testObject1, U testObject2) { 49 // Assert.fail("test called unimplemented method"); 50 // } 51 } 52 53 54 abstract class CipherHelper<T/*, U*/> extends TestHelper<T/*, Key*/> { 55 56 private final String algorithmName; 57 private final String plainData; 58 private final int mode1; 59 private final int mode2; 60 61 CipherHelper(String algorithmName, String plainData, int mode1, int mode2) { 62 this.algorithmName = algorithmName; 63 this.plainData = plainData; 64 this.mode1 = mode1; 65 this.mode2 = mode2; 66 } 67 68 69 70 // @Override 71 void test(Key encryptKey, Key decryptKey) { 72 Cipher cipher = null; 73 try { 74 cipher = Cipher.getInstance(algorithmName); 75 } catch (NoSuchAlgorithmException e) { 76 Assert.fail(e.getMessage()); 77 } catch (NoSuchPaddingException e) { 78 Assert.fail(e.getMessage()); 79 } 80 try { 81 cipher.init(mode1, encryptKey); 82 } catch (InvalidKeyException e) { 83 Assert.fail(e.getMessage()); 84 } 85 86 byte[] encrypted = crypt(cipher, plainData.getBytes()); 87 88 try { 89 cipher.init(mode2, decryptKey); 90 } catch (InvalidKeyException e) { 91 Assert.fail(e.getMessage()); 92 } 93 94 byte[] decrypted = crypt(cipher, encrypted); 95 96 String decryptedString = new String(decrypted); 97 98 Assert.assertEquals("transformed data does not match", plainData, 99 decryptedString); 100 } 101 102 byte[] crypt(Cipher cipher, byte[] input) { 103 try { 104 return cipher.doFinal(input); 105 } catch (IllegalBlockSizeException e) { 106 Assert.fail(e.getMessage()); 107 } catch (BadPaddingException e) { 108 Assert.fail(e.getMessage()); 109 } 110 return null; 111 } 112 } 113 114 115 class CipherAsymmetricCryptHelper extends CipherHelper<KeyPair/*, U*/> { 116 117 private static final String plainData = "some data to encrypt and decrypt test"; 118 119 CipherAsymmetricCryptHelper(String algorithmName) { 120 super(algorithmName, plainData, Cipher.ENCRYPT_MODE, 121 Cipher.DECRYPT_MODE); 122 } 123 124 @Override 125 void test(KeyPair keyPair) { 126 test(keyPair.getPrivate(), keyPair.getPublic()); 127 } 128 } 129 130 131 class CipherSymmetricCryptHelper extends CipherHelper<SecretKey/*, U*/> { 132 133 private static final String plainData = "some data to encrypt and decrypt test"; 134 135 CipherSymmetricCryptHelper(String algorithmName) { 136 super(algorithmName, plainData, Cipher.ENCRYPT_MODE, 137 Cipher.DECRYPT_MODE); 138 } 139 140 @Override 141 void test(SecretKey key) { 142 test(key, key); 143 } 144 } 145 146 class SignatureHelper extends TestHelper<KeyPair> { 147 148 private final String algorithmName; 149 private final String plainData = "some data do sign and verify"; 150 151 protected SignatureHelper(String algorithmName) { 152 this.algorithmName = algorithmName; 153 } 154 155 @Override 156 void test(KeyPair keyPair) { 157 test(keyPair.getPrivate(), keyPair.getPublic()); 158 } 159 160 // @Override 161 void test(PrivateKey encryptKey, PublicKey decryptKey) { 162 163 Signature signature = null; 164 try { 165 signature = Signature.getInstance(algorithmName); 166 } catch (NoSuchAlgorithmException e) { 167 Assert.fail(e.getMessage()); 168 } 169 170 try { 171 signature.initSign(encryptKey); 172 } catch (InvalidKeyException e) { 173 Assert.fail(e.getMessage()); 174 } 175 176 try { 177 signature.update(plainData.getBytes()); 178 } catch (SignatureException e) { 179 Assert.fail(e.getMessage()); 180 } 181 182 byte[] signed = null; 183 try { 184 signed = signature.sign(); 185 } catch (SignatureException e) { 186 Assert.fail(e.getMessage()); 187 } 188 189 try { 190 signature.initVerify(decryptKey); 191 } catch (InvalidKeyException e) { 192 Assert.fail(e.getMessage()); 193 } 194 195 try { 196 signature.update(plainData.getBytes()); 197 } catch (SignatureException e) { 198 Assert.fail(e.getMessage()); 199 } 200 201 try { 202 Assert.assertTrue("signature could not be verified", signature 203 .verify(signed)); 204 } catch (SignatureException e) { 205 Assert.fail(e.getMessage()); 206 } 207 } 208 } 209 210 211 class KeyAgreementHelper extends TestHelper<KeyPair> { 212 213 private final String algorithmName; 214 215 protected KeyAgreementHelper(String algorithmName) { 216 this.algorithmName = algorithmName; 217 } 218 219 @Override 220 void test(KeyPair keyPair) { 221 test(keyPair.getPrivate(), keyPair.getPublic()); 222 } 223 // @Override 224 void test(PrivateKey encryptKey, PublicKey decryptKey) { 225 226 KeyAgreement keyAgreement = null; 227 try { 228 keyAgreement = KeyAgreement.getInstance(algorithmName); 229 } catch (NoSuchAlgorithmException e) { 230 Assert.fail(e.getMessage()); 231 } 232 233 try { 234 keyAgreement.init(encryptKey); 235 } catch (InvalidKeyException e) { 236 Assert.fail(e.getMessage()); 237 } 238 try { 239 keyAgreement.doPhase(decryptKey, true); 240 } catch (InvalidKeyException e) { 241 Assert.fail(e.getMessage()); 242 } catch (IllegalStateException e) { 243 Assert.fail(e.getMessage()); 244 } 245 Assert.assertNotNull("generated secret is null", keyAgreement 246 .generateSecret()); 247 248 } 249 } 250 251 class AlgorithmParameterAsymmetricHelper extends TestHelper<AlgorithmParameters> { 252 253 private static final String plainData = "some data to encrypt and decrypt"; 254 private final String algorithmName; 255 256 protected AlgorithmParameterAsymmetricHelper(String algorithmName) { 257 this.algorithmName = algorithmName; 258 } 259 260 @Override 261 void test(AlgorithmParameters parameters) { 262 263 KeyPairGenerator generator = null; 264 try { 265 generator = KeyPairGenerator.getInstance(algorithmName); 266 } catch (NoSuchAlgorithmException e) { 267 Assert.fail(e.getMessage()); 268 } 269 270 generator.initialize(1024); 271 272 KeyPair keyPair = generator.generateKeyPair(); 273 274 275 Cipher cipher = null; 276 try { 277 cipher = Cipher.getInstance(algorithmName); 278 } catch (NoSuchAlgorithmException e) { 279 Assert.fail(e.getMessage()); 280 } catch (NoSuchPaddingException e) { 281 Assert.fail(e.getMessage()); 282 } 283 284 try { 285 cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), parameters); 286 } catch (InvalidKeyException e) { 287 Assert.fail(e.getMessage()); 288 } catch (InvalidAlgorithmParameterException e) { 289 Assert.fail(e.getMessage()); 290 } 291 292 byte[] bs = null; 293 try { 294 bs = cipher.doFinal(plainData.getBytes()); 295 } catch (IllegalBlockSizeException e) { 296 Assert.fail(e.getMessage()); 297 } catch (BadPaddingException e) { 298 Assert.fail(e.getMessage()); 299 } 300 301 try { 302 cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate(), parameters); 303 } catch (InvalidKeyException e) { 304 Assert.fail(e.getMessage()); 305 } catch (InvalidAlgorithmParameterException e) { 306 Assert.fail(e.getMessage()); 307 } 308 309 byte[] decrypted = null; 310 try { 311 decrypted = cipher.doFinal(bs); 312 } catch (IllegalBlockSizeException e) { 313 Assert.fail(e.getMessage()); 314 } catch (BadPaddingException e) { 315 Assert.fail(e.getMessage()); 316 } 317 318 Assert.assertTrue(Arrays.equals(plainData.getBytes(), decrypted)); 319 } 320 } 321 322 class AlgorithmParameterSymmetricHelper extends TestHelper<AlgorithmParameters> { 323 324 private static final String plainData = "some data to encrypt and decrypt"; 325 private final String algorithmName; 326 private final int keySize; 327 private String blockmode; 328 329 protected AlgorithmParameterSymmetricHelper(String algorithmName, int keySize) { 330 this.algorithmName = algorithmName; 331 this.keySize = keySize; 332 } 333 334 protected AlgorithmParameterSymmetricHelper(String algorithmName, String blockmode, int keySize) { 335 this(algorithmName, keySize); 336 this.blockmode = blockmode; 337 } 338 339 @Override 340 void test(AlgorithmParameters parameters) { 341 342 KeyGenerator generator = null; 343 try { 344 generator = KeyGenerator.getInstance(algorithmName); 345 } catch (NoSuchAlgorithmException e) { 346 Assert.fail(e.getMessage()); 347 } 348 349 generator.init(keySize); 350 351 Key key = generator.generateKey(); 352 353 354 Cipher cipher = null; 355 try { 356 String transformation = algorithmName; 357 if (blockmode != null) 358 { 359 transformation += "/" + blockmode; 360 } 361 cipher = Cipher.getInstance(transformation); 362 } catch (NoSuchAlgorithmException e) { 363 Assert.fail(e.getMessage()); 364 } catch (NoSuchPaddingException e) { 365 Assert.fail(e.getMessage()); 366 } 367 368 try { 369 cipher.init(Cipher.ENCRYPT_MODE, key, parameters); 370 } catch (InvalidKeyException e) { 371 Assert.fail(e.getMessage()); 372 } catch (InvalidAlgorithmParameterException e) { 373 Assert.fail(e.getMessage()); 374 } 375 376 byte[] bs = null; 377 try { 378 bs = cipher.doFinal(plainData.getBytes()); 379 } catch (IllegalBlockSizeException e) { 380 Assert.fail(e.getMessage()); 381 } catch (BadPaddingException e) { 382 Assert.fail(e.getMessage()); 383 } 384 385 try { 386 cipher.init(Cipher.DECRYPT_MODE, key, parameters); 387 } catch (InvalidKeyException e) { 388 Assert.fail(e.getMessage()); 389 } catch (InvalidAlgorithmParameterException e) { 390 Assert.fail(e.getMessage()); 391 } 392 393 byte[] decrypted = null; 394 try { 395 decrypted = cipher.doFinal(bs); 396 } catch (IllegalBlockSizeException e) { 397 Assert.fail(e.getMessage()); 398 } catch (BadPaddingException e) { 399 Assert.fail(e.getMessage()); 400 } 401 402 Assert.assertTrue(Arrays.equals(plainData.getBytes(), decrypted)); 403 } 404 } 405 406 407 class AlgorithmParameterSignatureHelper<T extends AlgorithmParameterSpec> extends TestHelper<AlgorithmParameters> { 408 409 private final String algorithmName; 410 private final String plainData = "some data do sign and verify"; 411 private final Class<T> parameterSpecClass; 412 413 protected AlgorithmParameterSignatureHelper(String algorithmName, Class<T> parameterSpecCla1ss) { 414 this.algorithmName = algorithmName; 415 this.parameterSpecClass = parameterSpecCla1ss; 416 } 417 418 @Override 419 void test(AlgorithmParameters parameters) { 420 421 Signature signature = null; 422 try { 423 signature = Signature.getInstance(algorithmName); 424 } catch (NoSuchAlgorithmException e) { 425 Assert.fail(e.getMessage()); 426 } 427 428 429 T parameterSpec = null; 430 try { 431 parameterSpec = parameters.getParameterSpec(parameterSpecClass); 432 } catch (InvalidParameterSpecException e) { 433 Assert.fail(e.getMessage()); 434 } 435 436 KeyPairGenerator generator = null; 437 try { 438 generator = KeyPairGenerator.getInstance(algorithmName); 439 } catch (NoSuchAlgorithmException e) { 440 Assert.fail(e.getMessage()); 441 } 442 443 try { 444 generator.initialize(parameterSpec); 445 } catch (InvalidAlgorithmParameterException e) { 446 Assert.fail(e.getMessage()); 447 } 448 449 KeyPair keyPair = generator.genKeyPair(); 450 451 try { 452 signature.initSign(keyPair.getPrivate()); 453 } catch (InvalidKeyException e) { 454 Assert.fail(e.getMessage()); 455 } 456 457 try { 458 signature.update(plainData.getBytes()); 459 } catch (SignatureException e) { 460 Assert.fail(e.getMessage()); 461 } 462 463 byte[] signed = null; 464 try { 465 signed = signature.sign(); 466 } catch (SignatureException e) { 467 Assert.fail(e.getMessage()); 468 } 469 470 try { 471 signature.initVerify(keyPair.getPublic()); 472 } catch (InvalidKeyException e) { 473 Assert.fail(e.getMessage()); 474 } 475 476 try { 477 signature.update(plainData.getBytes()); 478 } catch (SignatureException e) { 479 Assert.fail(e.getMessage()); 480 } 481 482 try { 483 Assert.assertTrue("signature could not be verified", signature 484 .verify(signed)); 485 } catch (SignatureException e) { 486 Assert.fail(e.getMessage()); 487 } 488 } 489 } 490 491 class AlgorithmParameterKeyAgreementHelper extends TestHelper<AlgorithmParameters> { 492 493 private final String algorithmName; 494 495 protected AlgorithmParameterKeyAgreementHelper(String algorithmName) { 496 this.algorithmName = algorithmName; 497 } 498 499 @Override 500 void test(AlgorithmParameters parameters) { 501 502 KeyPairGenerator generator = null; 503 try { 504 generator = KeyPairGenerator.getInstance(algorithmName); 505 } catch (NoSuchAlgorithmException e) { 506 Assert.fail(e.getMessage()); 507 } 508 509 generator.initialize(1024); 510 511 KeyPair keyPair = generator.generateKeyPair(); 512 513 KeyAgreement keyAgreement = null; 514 try { 515 keyAgreement = KeyAgreement.getInstance(algorithmName); 516 } catch (NoSuchAlgorithmException e) { 517 Assert.fail(e.getMessage()); 518 } 519 520 try { 521 keyAgreement.init(keyPair.getPrivate()); 522 } catch (InvalidKeyException e) { 523 Assert.fail(e.getMessage()); 524 } 525 try { 526 keyAgreement.doPhase(keyPair.getPublic(), true); 527 } catch (InvalidKeyException e) { 528 Assert.fail(e.getMessage()); 529 } catch (IllegalStateException e) { 530 Assert.fail(e.getMessage()); 531 } 532 Assert.assertNotNull("generated secret is null", keyAgreement 533 .generateSecret()); 534 } 535 }