summaryrefslogtreecommitdiffstats
path: root/crypto/src
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:28:47 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:28:47 -0800
commitadc854b798c1cfe3bfd4c27d68d5cee38ca617da (patch)
tree6aed8b4923ca428942cbaa7e848d50237a3d31e0 /crypto/src
parent1c0fed63c71ddb230f3b304aac12caffbedf2f21 (diff)
downloadlibcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.zip
libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.gz
libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/main/java/javax/crypto/BadPaddingException.java53
-rw-r--r--crypto/src/main/java/javax/crypto/Cipher.java1449
-rw-r--r--crypto/src/main/java/javax/crypto/CipherInputStream.java246
-rw-r--r--crypto/src/main/java/javax/crypto/CipherOutputStream.java175
-rw-r--r--crypto/src/main/java/javax/crypto/CipherSpi.java589
-rw-r--r--crypto/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java566
-rw-r--r--crypto/src/main/java/javax/crypto/ExemptionMechanism.java396
-rw-r--r--crypto/src/main/java/javax/crypto/ExemptionMechanismException.java53
-rw-r--r--crypto/src/main/java/javax/crypto/ExemptionMechanismSpi.java139
-rw-r--r--crypto/src/main/java/javax/crypto/IllegalBlockSizeException.java54
-rw-r--r--crypto/src/main/java/javax/crypto/KeyAgreement.java340
-rw-r--r--crypto/src/main/java/javax/crypto/KeyAgreementSpi.java151
-rw-r--r--crypto/src/main/java/javax/crypto/KeyGenerator.java265
-rw-r--r--crypto/src/main/java/javax/crypto/KeyGeneratorSpi.java86
-rw-r--r--crypto/src/main/java/javax/crypto/Mac.java452
-rw-r--r--crypto/src/main/java/javax/crypto/MacSpi.java160
-rw-r--r--crypto/src/main/java/javax/crypto/NoSuchPaddingException.java54
-rw-r--r--crypto/src/main/java/javax/crypto/NullCipher.java51
-rw-r--r--crypto/src/main/java/javax/crypto/SealedObject.java305
-rw-r--r--crypto/src/main/java/javax/crypto/SecretKey.java44
-rw-r--r--crypto/src/main/java/javax/crypto/SecretKeyFactory.java243
-rw-r--r--crypto/src/main/java/javax/crypto/SecretKeyFactorySpi.java84
-rw-r--r--crypto/src/main/java/javax/crypto/ShortBufferException.java59
-rw-r--r--crypto/src/main/java/javax/crypto/interfaces/DHKey.java36
-rw-r--r--crypto/src/main/java/javax/crypto/interfaces/DHPrivateKey.java41
-rw-r--r--crypto/src/main/java/javax/crypto/interfaces/DHPublicKey.java40
-rw-r--r--crypto/src/main/java/javax/crypto/interfaces/PBEKey.java55
-rw-r--r--crypto/src/main/java/javax/crypto/interfaces/package.html12
-rw-r--r--crypto/src/main/java/javax/crypto/package.html19
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DESKeySpec.java219
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DESedeKeySpec.java133
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DHGenParameterSpec.java65
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DHParameterSpec.java94
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java78
-rw-r--r--crypto/src/main/java/javax/crypto/spec/DHPublicKeySpec.java79
-rw-r--r--crypto/src/main/java/javax/crypto/spec/IvParameterSpec.java93
-rw-r--r--crypto/src/main/java/javax/crypto/spec/OAEPParameterSpec.java126
-rw-r--r--crypto/src/main/java/javax/crypto/spec/PBEKeySpec.java200
-rw-r--r--crypto/src/main/java/javax/crypto/spec/PBEParameterSpec.java79
-rw-r--r--crypto/src/main/java/javax/crypto/spec/PSource.java111
-rw-r--r--crypto/src/main/java/javax/crypto/spec/RC2ParameterSpec.java166
-rw-r--r--crypto/src/main/java/javax/crypto/spec/RC5ParameterSpec.java218
-rw-r--r--crypto/src/main/java/javax/crypto/spec/SecretKeySpec.java186
-rw-r--r--crypto/src/main/java/javax/crypto/spec/package.html17
-rw-r--r--crypto/src/main/java/org/apache/harmony/crypto/internal/NullCipherSpi.java175
-rw-r--r--crypto/src/main/java/org/apache/harmony/crypto/internal/nls/Messages.java147
-rw-r--r--crypto/src/main/java/org/apache/harmony/crypto/internal/nls/messages.properties87
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java65
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java102
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStream1Test.java329
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStreamTest.java85
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStream1Test.java270
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStreamTest.java60
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java455
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java1684
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java2252
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java125
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java151
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java734
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java104
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java132
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java975
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java104
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorTest.java690
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java281
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java1189
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java104
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NullCipherTest.java435
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java340
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java80
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactoryTest.java596
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java72
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java102
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java51
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java73
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java56
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java69
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java45
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java69
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java99
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBEThread.java60
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java98
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSAThread.java50
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherSymmetricKeyThread.java73
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherThread.java174
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherWrapThread.java47
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java42
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementThread.java88
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java96
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorThread.java68
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java74
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacThread.java57
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java60
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryThread.java39
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/TestThread.java90
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java43
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java109
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java110
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java118
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java45
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java49
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java49
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java49
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java49
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java49
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java54
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java332
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java234
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java92
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java119
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java103
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java103
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java168
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java202
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java364
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java126
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java162
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java262
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java358
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java323
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/EncryptedPrivateKeyInfoData.java1229
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java122
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyExemptionMechanismSpi.java140
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyAgreementSpi.java86
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyGeneratorSpi.java64
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyMacSpi.java76
-rw-r--r--crypto/src/test/java/org/apache/harmony/crypto/tests/support/MySecretKeyFactorySpi.java57
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.0.serbin0 -> 1388 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.1.serbin0 -> 1388 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.2.serbin0 -> 1473 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.0.serbin0 -> 1412 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.1.serbin0 -> 1412 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.2.serbin0 -> 1497 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.0.serbin0 -> 1406 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.1.serbin0 -> 1406 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.2.serbin0 -> 1491 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.0.serbin0 -> 1397 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.1.serbin0 -> 1397 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.2.serbin0 -> 1482 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.0.serbin0 -> 1391 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.1.serbin0 -> 1391 bytes
-rw-r--r--crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.2.serbin0 -> 1476 bytes
-rw-r--r--crypto/src/test/java/tests/crypto/AllTests.java43
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test1.ciphertext1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test1.iv1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test1.key1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test1.plaintext1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test2.ciphertextbin0 -> 128 bytes
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test2.iv1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test2.key1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test2.plaintextbin0 -> 126 bytes
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertextbin0 -> 10008 bytes
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test3.iv1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test3.key1
-rw-r--r--crypto/src/test/resources/hyts_des-ede3-cbc.test3.plaintextbin0 -> 10000 bytes
155 files changed, 27081 insertions, 0 deletions
diff --git a/crypto/src/main/java/javax/crypto/BadPaddingException.java b/crypto/src/main/java/javax/crypto/BadPaddingException.java
new file mode 100644
index 0000000..19fdaa8
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/BadPaddingException.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * The exception that is thrown when a padding mechanism is expected for the
+ * input data, but the input data does not have the proper padding bytes.
+ *
+ * @since Android 1.0
+ */
+public class BadPaddingException extends GeneralSecurityException {
+
+ /**
+ * @serial
+ */
+ private static final long serialVersionUID = -5315033893984728443L;
+
+ /**
+ * Creates a new instance of {@code BadPaddingException} with a message.
+ *
+ * @param msg
+ * the message
+ * @since Android 1.0
+ */
+ public BadPaddingException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new instance of {@code BadPaddingException} with no message.
+ *
+ * @since Android 1.0
+ */
+ public BadPaddingException() {
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/Cipher.java b/crypto/src/main/java/javax/crypto/Cipher.java
new file mode 100644
index 0000000..ae72226
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/Cipher.java
@@ -0,0 +1,1449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.InvalidParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.harmony.crypto.internal.NullCipherSpi;
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+/**
+ * This class provides access to implementations of cryptographic ciphers for
+ * encryption and decryption. Cipher classes can not be instantiated directly,
+ * one has to call the Cipher's {@code getInstance} method with the name of a
+ * requested transformation, optionally with a provider. A transformation
+ * specifies an operation (or a set of operations) as a string in the form:
+ * <ul>
+ * <li><i>"algorithm/mode/padding"</i></li> or
+ * <li><i>"algorithm"</i></li>
+ * </ul>
+ * <i>algorithm</i> is the name of a cryptographic algorithm, <i>mode</i> is the
+ * name of a feedback mode and <i>padding</i> is the name of a padding scheme.
+ * If <i>mode</i> and/or <i>padding</i> values are omitted, provider specific
+ * default values will be used.
+ * <p>
+ * A valid transformation would be:
+ * <ul>
+ * {@code Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");}
+ * </ul>
+ * When a block cipher is requested in in stream cipher mode, the number of bits
+ * to be processed at a time can be optionally specified by appending it to the
+ * mode name. e.g. <i>"AES/CFB8/NoPadding"</i>. If no number is specified, a
+ * provider specific default value is used.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class Cipher {
+
+ /**
+ * Constant for decryption operation mode.
+ *
+ * @since Android 1.0
+ */
+ public static final int DECRYPT_MODE = 2;
+
+ /**
+ * Constant for encryption operation mode.
+ *
+ * @since Android 1.0
+ */
+ public static final int ENCRYPT_MODE = 1;
+
+ /**
+ * Constant indicating that the key to be unwrapped is a private key.
+ *
+ * @since Android 1.0
+ */
+ public static final int PRIVATE_KEY = 2;
+
+ /**
+ * Constant indicating that the key to be unwrapped is a public key.
+ *
+ * @since Android 1.0
+ */
+ public static final int PUBLIC_KEY = 1;
+
+ /**
+ * Constant indicating that the key to be unwrapped is a secret key.
+ *
+ * @since Android 1.0
+ */
+ public static final int SECRET_KEY = 3;
+
+ /**
+ * Constant for key unwrapping operation mode.
+ *
+ * @since Android 1.0
+ */
+ public static final int UNWRAP_MODE = 4;
+
+ /**
+ * Constant for key wrapping operation mode.
+ *
+ * @since Android 1.0
+ */
+ public static final int WRAP_MODE = 3;
+
+ private int mode;
+
+ /**
+ * The service name.
+ */
+ private static final String SERVICE = "Cipher"; //$NON-NLS-1$
+
+ /**
+ * Used to access common engine functionality.
+ */
+ private static final Engine engine = new Engine(SERVICE);
+
+ /**
+ * The provider.
+ */
+ private Provider provider;
+
+ /**
+ * The SPI implementation.
+ */
+ private CipherSpi spiImpl;
+
+ /**
+ * The transformation.
+ */
+ private String transformation;
+
+ private static SecureRandom sec_rand;
+
+ /**
+ * Creates a new Cipher instance.
+ *
+ * @param cipherSpi
+ * the implementation delegate of the cipher.
+ * @param provider
+ * the provider of the implementation of this cipher.
+ * @param transformation
+ * the name of the transformation that this cipher performs.
+ * @throws NullPointerException
+ * if either cipherSpi is {@code null} or provider is {@code
+ * null} and {@code cipherSpi} is a {@code NullCipherSpi}.
+ * @since Android 1.0
+ */
+ protected Cipher(CipherSpi cipherSpi, Provider provider,
+ String transformation) {
+ if (cipherSpi == null) {
+ throw new NullPointerException();
+ }
+ if (!(cipherSpi instanceof NullCipherSpi) && provider == null) {
+ throw new NullPointerException();
+ }
+ this.provider = provider;
+ this.transformation = transformation;
+ this.spiImpl = cipherSpi;
+ }
+
+ /**
+ * Creates a new Cipher for the specified transformation. The installed
+ * providers are searched in order for an implementation of the specified
+ * transformation. The first found provider providing the transformation is
+ * used to create the cipher. If no provider is found an exception is
+ * thrown.
+ *
+ * @param transformation
+ * the name of the transformation to create a cipher for.
+ * @return a cipher for the requested transformation.
+ * @throws NoSuchAlgorithmException
+ * if no installed provider can provide the
+ * <i>transformation</i>, or it is {@code null}, empty or in an
+ * invalid format.
+ * @throws NoSuchPaddingException
+ * if no installed provider can provide the padding scheme in
+ * the <i>transformation</i>.
+ * @since Android 1.0
+ */
+ public static final Cipher getInstance(String transformation)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ return getCipher(transformation, null);
+ }
+
+ /**
+ * Creates a new cipher for the specified transformation provided by the
+ * specified provider.
+ *
+ * @param transformation
+ * the name of the transformation to create a cipher for.
+ * @param provider
+ * the name of the provider to ask for the transformation.
+ * @return a cipher for the requested transformation.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider can not provide the
+ * <i>transformation</i>, or it is {@code null}, empty or in an
+ * invalid format.
+ * @throws NoSuchProviderException
+ * if no provider with the specified name can be found.
+ * @throws NoSuchPaddingException
+ * if the requested padding scheme in the <i>transformation</i>
+ * is not available.
+ * @throws IllegalArgumentException
+ * if the specified provider is {@code null}.
+ * @since Android 1.0
+ */
+ public static final Cipher getInstance(String transformation,
+ String provider) throws NoSuchAlgorithmException,
+ NoSuchProviderException, NoSuchPaddingException {
+
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+
+ Provider p = Security.getProvider(provider);
+ if (p == null) {
+ throw new NoSuchProviderException(Messages.getString("crypto.16", provider)); //$NON-NLS-1$
+ }
+ return getInstance(transformation, p);
+ }
+
+ /**
+ * Creates a new cipher for the specified transformation.
+ *
+ * @param transformation
+ * the name of the transformation to create a cipher for.
+ * @param provider
+ * the provider to ask for the transformation.
+ * @return a cipher for the requested transformation.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider can not provide the
+ * <i>transformation</i>, or it is {@code null}, empty or in an
+ * invalid format.
+ * @throws NoSuchPaddingException
+ * if the requested padding scheme in the <i>transformation</i>
+ * is not available.
+ * @throws IllegalArgumentException
+ * if the provider is {@code null}.
+ * @since Android 1.0
+ */
+ public static final Cipher getInstance(String transformation,
+ Provider provider) throws NoSuchAlgorithmException,
+ NoSuchPaddingException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ Cipher c = getCipher(transformation, provider);
+ return c;
+ }
+
+ /**
+ * Find appropriate Cipher according the specification rules
+ *
+ * @param transformation
+ * @param provider
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws NoSuchPaddingException
+ */
+ private static synchronized Cipher getCipher(String transformation, Provider provider)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+
+ if (transformation == null || "".equals(transformation)) { //$NON-NLS-1$
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
+ transformation));
+ }
+
+ String[] transf = checkTransformation(transformation);
+
+ boolean needSetPadding = false;
+ boolean needSetMode = false;
+ if (transf[1] == null && transf[2] == null) { // "algorithm"
+ if (provider == null) {
+ engine.getInstance(transf[0], null);
+ } else {
+ engine.getInstance(transf[0], provider, null);
+ }
+ } else {
+ String[] searhOrder = {
+ transf[0] + "/" + transf[1] + "/" + transf[2], // "algorithm/mode/padding" //$NON-NLS-1$ //$NON-NLS-2$
+ transf[0] + "/" + transf[1], // "algorithm/mode" //$NON-NLS-1$
+ transf[0] + "//" + transf[2], // "algorithm//padding" //$NON-NLS-1$
+ transf[0] // "algorithm"
+ };
+ int i;
+ for (i = 0; i < searhOrder.length; i++) {
+ try {
+ if (provider == null) {
+ engine.getInstance(searhOrder[i], null);
+ } else {
+ engine.getInstance(searhOrder[i], provider, null);
+ }
+ break;
+ } catch (NoSuchAlgorithmException e) {
+ if ( i == searhOrder.length-1) {
+ throw new NoSuchAlgorithmException(transformation);
+ }
+ }
+ }
+ switch (i) {
+ case 1: // "algorithm/mode"
+ needSetPadding = true;
+ break;
+ case 2: // "algorithm//padding"
+ needSetMode = true;
+ break;
+ case 3: // "algorithm"
+ needSetPadding = true;
+ needSetMode = true;
+ }
+ }
+ CipherSpi cspi;
+ try {
+ cspi = (CipherSpi) engine.spi;
+ } catch (ClassCastException e) {
+ throw new NoSuchAlgorithmException(e);
+ }
+ Cipher c = new Cipher(cspi, engine.provider, transformation);
+ if (needSetMode) {
+ c.spiImpl.engineSetMode(transf[1]);
+ }
+ if (needSetPadding) {
+ c.spiImpl.engineSetPadding(transf[2]);
+ }
+ return c;
+ }
+
+ private static String[] checkTransformation(String transformation)
+ throws NoSuchAlgorithmException {
+ String[] transf = { null, null, null };
+ StringTokenizer st;
+ int i = 0;
+ for (st = new StringTokenizer(transformation, "/"); st //$NON-NLS-1$
+ .hasMoreElements();) {
+ if (i > 2) {
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
+ transformation));
+ }
+ transf[i] = st.nextToken();
+ if (transf[i] != null) {
+ transf[i] = transf[i].trim();
+ if ("".equals(transf[i])) { //$NON-NLS-1$
+ transf[i] = null;
+ }
+ i++;
+ }
+ }
+ if (transf[0] == null) {
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
+ transformation));
+ }
+ if (!(transf[1] == null && transf[2] == null)
+ && (transf[1] == null || transf[2] == null)) {
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.17", //$NON-NLS-1$
+ transformation));
+ }
+ return transf;
+ }
+
+ /**
+ * Returns the provider of this cipher instance.
+ *
+ * @return the provider of this cipher instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Returns the name of the algorithm of this cipher instance.
+ * <p>
+ * This is the name of the <i>transformation</i> argument used in the
+ * {@code getInstance} call creating this object.
+ * </p>
+ *
+ * @return the name of the algorithm of this cipher instance.
+ * @since Android 1.0.
+ */
+ public final String getAlgorithm() {
+ return transformation;
+ }
+
+ /**
+ * Returns this ciphers block size (in bytes).
+ *
+ * @return this ciphers block size.
+ * @since Android 1.0
+ */
+ public final int getBlockSize() {
+ return spiImpl.engineGetBlockSize();
+ }
+
+ /**
+ * Returns the length in bytes an output buffer needs to be when this cipher
+ * is updated with {@code inputLen} bytes.
+ *
+ * @param inputLen
+ * the number of bytes of the input.
+ * @return the output buffer length for the input length.
+ * @throws IllegalStateException
+ * if this cipher instance is in an invalid state.
+ * @since Android 1.0
+ */
+ public final int getOutputSize(int inputLen) {
+ if (mode == 0) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.18")); //$NON-NLS-1$
+ }
+ return spiImpl.engineGetOutputSize(inputLen);
+ }
+
+ /**
+ * Returns the <i>initialization vector</i> for this cipher instance.
+ *
+ * @return the <i>initialization vector</i> for this cipher instance.
+ * @since Android 1.0
+ */
+ public final byte[] getIV() {
+ return spiImpl.engineGetIV();
+ }
+
+ /**
+ * Returns the parameters that where used to create this cipher instance.
+ * <p>
+ * These may be a the same parameters that were used to create this cipher
+ * instance, or may be a combination of default and random parameters,
+ * depending on the underlying cipher implementation.
+ *
+ * @return the parameters that where used to create this cipher instance, or
+ * {@code null} if this cipher instance does not have any
+ * parameters.
+ * @since Android 1.0
+ */
+ public final AlgorithmParameters getParameters() {
+ return spiImpl.engineGetParameters();
+ }
+
+ /**
+ * Returns the exemption mechanism associated with this cipher.
+ *
+ * @return currently {@code null}
+ * @since Android 1.0
+ */
+ public final ExemptionMechanism getExemptionMechanism() {
+ //FIXME implement getExemptionMechanism
+
+ // try {
+ // return ExemptionMechanism.getInstance(transformation, provider);
+ // } catch (NoSuchAlgorithmException e) {
+ return null;
+ // }
+
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key.
+ * <p>
+ * The cipher is initialized for the specified operational mode (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters or random values
+ * that the specified key can not provide, the underlying implementation of
+ * this cipher is supposed to generate the required parameters (using its
+ * provider or random values).
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, meaning that it
+ * is equivalent to creating a new instance and calling its {@code init}
+ * method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key) throws InvalidKeyException {
+ if (sec_rand == null) {
+ // In theory it might be thread-unsafe but in the given case it's OK
+ // since it does not matter which SecureRandom instance is passed
+ // to the init()
+ sec_rand = new SecureRandom();
+ }
+ init(opmode, key, sec_rand);
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key and a source of
+ * randomness.
+ * <p>
+ * The cipher is initialized for the specified operational mode (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters or random values
+ * that the specified key can not provide, the underlying implementation of
+ * this cipher is supposed to generate the required parameters (using its
+ * provider or random values). Random values are generated using {@code
+ * random};
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @throws InvalidParameterException
+ * if the specified opmode is invalid.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
+ && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
+ throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
+ }
+ // FIXME InvalidKeyException
+ // if keysize exceeds the maximum allowable keysize
+ // (jurisdiction policy files)
+ spiImpl.engineInit(opmode, key, random);
+ mode = opmode;
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key and algorithm
+ * parameters.
+ * <p>
+ * The cipher is initialized for the specified operational mode (one of:
+ * encryption, decryption, key wrapping or key unwrapping).
+ * </p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values).
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @throws InvalidAlgorithmParameterException
+ * it the specified parameters are inappropriate for this
+ * cipher.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (sec_rand == null) {
+ sec_rand = new SecureRandom();
+ }
+ init(opmode, key, params, sec_rand);
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher is initialized for the specified operational mode (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * <p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random};
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, meaning that it
+ * is equivalent to creating a new instance and calling it {@code init}
+ * method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @throws InvalidAlgorithmParameterException
+ * it the specified parameters are inappropriate for this
+ * cipher.
+ * @throws InvalidParameterException
+ * if the specified {@code opmode} is invalid.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
+ && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
+ throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
+ }
+ // FIXME InvalidKeyException
+ // if keysize exceeds the maximum allowable keysize
+ // (jurisdiction policy files)
+ // FIXME InvalidAlgorithmParameterException
+ // cryptographic strength exceed the legal limits
+ // (jurisdiction policy files)
+ spiImpl.engineInit(opmode, key, params, random);
+ mode = opmode;
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key and algorithm
+ * parameters.
+ * <p>
+ * The cipher is initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values).
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, meaning that it
+ * is equivalent to creating a new instance and calling it {@code init}
+ * method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @throws InvalidAlgorithmParameterException
+ * it the specified parameters are inappropriate for this
+ * cipher.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key, AlgorithmParameters params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (sec_rand == null) {
+ sec_rand = new SecureRandom();
+ }
+ init(opmode, key, params, sec_rand);
+ }
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random}.
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key can not be used to initialize this
+ * cipher instance.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are inappropriate for this
+ * cipher.
+ * @throws InvalidParameterException
+ * if the specified {@code opmode} is invalid.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
+ && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
+ throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
+ }
+ // FIXME InvalidKeyException
+ // if keysize exceeds the maximum allowable keysize
+ // (jurisdiction policy files)
+ // FIXME InvalidAlgorithmParameterException
+ // cryptographic strength exceed the legal limits
+ // (jurisdiction policy files)
+ spiImpl.engineInit(opmode, key, params, random);
+ mode = opmode;
+ }
+
+ /**
+ * Initializes this cipher instance with the public key from the specified
+ * certificate.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * <p>
+ * It the type of the certificate is X.509 and the certificate has a <i>key
+ * usage</i> extension field marked as critical, the specified {@code
+ * opmode} has the be enabled for this key, otherwise an {@code
+ * InvalidKeyException} is thrown.
+ * <p>
+ * If this cipher instance needs any algorithm parameters that the key in
+ * the certificate can not provide, the underlying implementation of this
+ * cipher is supposed to generate the required parameters (using its
+ * provider or random values).
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param certificate
+ * the certificate.
+ * @throws InvalidKeyException
+ * if the public key in the certificate can not be used to
+ * initialize this cipher instance.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Certificate certificate)
+ throws InvalidKeyException {
+ if (sec_rand == null) {
+ sec_rand = new SecureRandom();
+ }
+ init(opmode, certificate, sec_rand);
+ }
+
+ /**
+ * Initializes this cipher instance with the public key from the specified
+ * certificate and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * It the type of the certificate is X.509 and the certificate has a <i>key
+ * usage</i> extension field marked as critical, the specified {@code
+ * opmode} has the be enabled for this key, otherwise an {@code
+ * InvalidKeyException} is thrown.
+ * <p>
+ * If this cipher instance needs any algorithm parameters that the key in
+ * the certificate can not provide, the underlying implementation of this
+ * cipher is supposed to generate the required parameters (using its
+ * provider or random values). Random values are generated using {@code
+ * random}.
+ * </p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param certificate
+ * the certificate.
+ * @param random
+ * the source of randomness to be used.
+ * @throws InvalidKeyException
+ * if the public key in the certificate can not be used to
+ * initialize this cipher instance.
+ * @since Android 1.0
+ */
+ public final void init(int opmode, Certificate certificate,
+ SecureRandom random) throws InvalidKeyException {
+ if (opmode != ENCRYPT_MODE && opmode != DECRYPT_MODE
+ && opmode != UNWRAP_MODE && opmode != WRAP_MODE) {
+ throw new InvalidParameterException(Messages.getString("crypto.19")); //$NON-NLS-1$
+ }
+ if (certificate instanceof X509Certificate) {
+ Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs();
+ boolean critical = false;
+ if (ce != null && !ce.isEmpty()) {
+ for (String oid : ce) {
+ if (oid.equals("2.5.29.15")) { //KeyUsage OID = 2.5.29.15 //$NON-NLS-1$
+ critical = true;
+ break;
+ }
+ }
+ if (critical) {
+ boolean[] keyUsage = ((X509Certificate) certificate)
+ .getKeyUsage();
+ // As specified in RFC 3280 -
+ // Internet X.509 Public Key Infrastructure
+ // Certificate and Certificate Revocation List (CRL) Profile.
+ // (http://www.ietf.org/rfc/rfc3280.txt)
+ //
+ // KeyUsage ::= BIT STRING {digitalSignature (0),
+ // ...
+ // encipherOnly (7),
+ // decipherOnly (8) }
+ if (keyUsage != null) {
+ if (opmode == ENCRYPT_MODE && (!keyUsage[7])) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.1A")); //$NON-NLS-1$
+ } else if (opmode == DECRYPT_MODE && (!keyUsage[8])) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.1B")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ // FIXME InvalidKeyException
+ // if keysize exceeds the maximum allowable keysize
+ // (jurisdiction policy files)
+ spiImpl.engineInit(opmode, certificate.getPublicKey(), random);
+ mode = opmode;
+ }
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are returned.
+ *
+ * @param input
+ * the input bytes to transform.
+ * @return the transformed bytes in a new buffer, or {@code null} if the
+ * input has zero length.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is {@code null}.
+ * @since Android 1.0
+ */
+ public final byte[] update(byte[] input) {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (input == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
+ }
+ if (input.length == 0) {
+ return null;
+ }
+ return spiImpl.engineUpdate(input, 0, input.length);
+ }
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are returned.
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @return the transformed bytes in a new buffer, or {@code null} if the
+ * input has zero length.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is {@code null}, or if {@code inputOffset} and
+ * {@code inputLen} do not specify a valid chunk in the input
+ * buffer.
+ * @since Android 1.0
+ */
+ public final byte[] update(byte[] input, int inputOffset, int inputLen) {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (input == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
+ }
+ if (inputOffset < 0 || inputLen < 0
+ || inputLen > input.length
+ || inputOffset > input.length - inputLen) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.1E")); //$NON-NLS-1$
+ }
+ if (input.length == 0) {
+ return null;
+ }
+ return spiImpl.engineUpdate(input, inputOffset, inputLen);
+ }
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are stored in the {@code output} buffer.
+ * <p>
+ * If the size of the {@code output} buffer is too small to hold the result,
+ * a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ * </p>
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @param output
+ * the output buffer.
+ * @return the number of bytes placed in output.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is {@code null}, the output is {@code null}, or
+ * if {@code inputOffset} and {@code inputLen} do not specify a
+ * valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ public final int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output) throws ShortBufferException {
+ return update(input, inputOffset, inputLen, output, 0);
+ }
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are stored in the {@code output} buffer.
+ * <p>
+ * If the size of the {@code output} buffer is too small to hold the result,
+ * a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ * </p>
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @param output
+ * the output buffer.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in output.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is {@code null}, the output is {@code null}, or
+ * if {@code inputOffset} and {@code inputLen} do not specify a
+ * valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ public final int update(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (input == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.1D")); //$NON-NLS-1$
+ }
+ if (output == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.1F")); //$NON-NLS-1$
+ }
+ if (outputOffset < 0) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.20")); //$NON-NLS-1$
+ }
+ if (inputOffset < 0 || inputLen < 0
+ || inputLen > input.length
+ || inputOffset > input.length - inputLen) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.21")); //$NON-NLS-1$
+ }
+ if (input.length == 0) {
+ return 0;
+ }
+ return spiImpl.engineUpdate(input, inputOffset, inputLen, output,
+ outputOffset);
+ }
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * {@code input.remaining()} bytes starting at {@code input.position()} are
+ * transformed and stored in the {@code output} buffer.
+ * <p>
+ * If the {@code output.remaining()} is too small to hold the transformed
+ * bytes a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ * </p>
+ *
+ * @param input
+ * the input buffer to transform.
+ * @param output
+ * the output buffer to store the result within.
+ * @return the number of bytes stored in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input buffer and the output buffer are the identical
+ * object.
+ * @since Android 1.0
+ */
+ public final int update(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (input == output) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.22")); //$NON-NLS-1$
+ }
+ return spiImpl.engineUpdate(input, output);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes any bytes that may have been buffered in previous {@code
+ * update} calls.
+ * </p>
+ *
+ * @return the final bytes from the transformation.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @since Android 1.0
+ */
+ public final byte[] doFinal() throws IllegalBlockSizeException,
+ BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(null, 0, 0);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes any bytes that may have been buffered in previous {@code
+ * update} calls.
+ * </p>
+ * The final transformed bytes are stored in the {@code output} buffer.
+ *
+ * @param output
+ * the output buffer.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in the output buffer.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @since Android 1.0
+ */
+ public final int doFinal(byte[] output, int outputOffset)
+ throws IllegalBlockSizeException, ShortBufferException,
+ BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (outputOffset < 0) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.20")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(null, 0, 0, output, outputOffset);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the bytes in {@code input} buffer, and any bytes that have been
+ * buffered in previous {@code update} calls.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @return the final bytes from the transformation.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @since Android 1.0
+ */
+ public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException,
+ BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(input, 0, input.length);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
+ * inputOffset}, and any bytes that have been buffered in previous {@code
+ * update} calls.
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input
+ * @return the final bytes from the transformation.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if {@code inputOffset} and {@code inputLen} do not specify an
+ * valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (inputOffset < 0 || inputLen < 0
+ || inputOffset + inputLen > input.length) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.1E")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(input, inputOffset, inputLen);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
+ * inputOffset}, and any bytes that have been buffered in previous {@code
+ * update} calls.
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @param output
+ * the output buffer for the transformed bytes.
+ * @return the number of bytes placed in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if {@code inputOffset} and {@code inputLen} do not specify an
+ * valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ public final int doFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ return doFinal(input, inputOffset, inputLen, output, 0);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
+ * inputOffset}, and any bytes that have been buffered in previous {@code
+ * update} calls.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @param output
+ * the output buffer for the transformed bytes.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if {@code inputOffset} and {@code inputLen} do not specify an
+ * valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ public final int doFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (inputOffset < 0 || inputLen < 0
+ || inputOffset + inputLen > input.length) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.1E")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(input, inputOffset, inputLen, output,
+ outputOffset);
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code input.remaining()} bytes in {@code input} buffer at
+ * {@code input.position()}, and any bytes that have been buffered in
+ * previous {@code update} calls. The transformed bytes are placed into
+ * {@code output} buffer.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @param output
+ * the output buffer.
+ * @return the number of bytes placed into the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalArgumentException
+ * if the input buffer and the output buffer are the same
+ * object.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @since Android 1.0
+ */
+ public final int doFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ if (input == output) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.2E")); //$NON-NLS-1$
+ }
+ return spiImpl.engineDoFinal(input, output);
+ }
+
+ /**
+ * Wraps a key using this cipher instance.
+ *
+ * @param key
+ * the key to wrap.
+ * @return the wrapped key.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws InvalidKeyException
+ * if this cipher instance can not wrap this key.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for wrapping.
+ * @since Android 1.0
+ */
+ public final byte[] wrap(Key key) throws IllegalBlockSizeException,
+ InvalidKeyException {
+ if (mode != WRAP_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ return spiImpl.engineWrap(key);
+ }
+
+ /**
+ * Unwraps a key using this cipher instance.
+ *
+ * @param wrappedKey
+ * the wrapped key to unwrap.
+ * @param wrappedKeyAlgorithm
+ * the algorithm for the wrapped key.
+ * @param wrappedKeyType
+ * the type of the wrapped key (one of: {@code SECRET_KEY
+ * <code>, <code>PRIVATE_KEY} or {@code PUBLIC_KEY})
+ * @return the unwrapped key
+ * @throws InvalidKeyException
+ * if the {@code wrappedKey} can not be unwrapped to a key of
+ * type {@code wrappedKeyType} for the {@code
+ * wrappedKeyAlgorithm}.
+ * @throws NoSuchAlgorithmException
+ * if no provider can be found that can create a key of type
+ * {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for unwrapping.
+ * @since Android 1.0
+ */
+ public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType) throws InvalidKeyException,
+ NoSuchAlgorithmException {
+ if (mode != UNWRAP_MODE) {
+ throw new IllegalStateException(
+ Messages.getString("crypto.1C")); //$NON-NLS-1$
+ }
+ return spiImpl.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
+ wrappedKeyType);
+ }
+
+ /**
+ * Returns the maximum key length for the specified transformation.
+ *
+ * @param transformation
+ * the transformation name.
+ * @return the maximum key length, currently {@code Integer.MAX_VALUE}.
+ * @throws NoSuchAlgorithmException
+ * if no provider for the specified {@code transformation} can
+ * be found.
+ * @throws NullPointerException
+ * if {@code transformation} is {@code null}.
+ * @since Android 1.0
+ */
+ public static final int getMaxAllowedKeyLength(String transformation)
+ throws NoSuchAlgorithmException {
+ if (transformation == null) {
+ throw new NullPointerException();
+ }
+ checkTransformation(transformation);
+ //FIXME jurisdiction policy files
+ return Integer.MAX_VALUE;
+ }
+
+ /**
+ * Returns the maximum cipher parameter value for the specified
+ * transformation. If there is no maximum limit, {@code null} is returned.
+ *
+ * @param transformation
+ * the transformation name.
+ * @return a parameter spec holding the maximum value or {@code null}.
+ * Currently {@code null}.
+ * @throws NoSuchAlgorithmException
+ * if no provider for the specified {@code transformation} can
+ * be found.
+ * @throws NullPointerException
+ * if {@code transformation} is {@code null}.
+ * @since Android 1.0
+ */
+ public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
+ String transformation) throws NoSuchAlgorithmException {
+ if (transformation == null) {
+ throw new NullPointerException();
+ }
+ checkTransformation(transformation);
+ //FIXME jurisdiction policy files
+ return null;
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/CipherInputStream.java b/crypto/src/main/java/javax/crypto/CipherInputStream.java
new file mode 100644
index 0000000..ca64c49
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/CipherInputStream.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.crypto.NullCipher;
+import java.security.GeneralSecurityException;
+
+/**
+ * This class wraps an {@code InputStream} and a cipher so that {@code read()}
+ * methods return data that are read from the underlying {@code InputStream} and
+ * processed by the cipher.
+ * <p>
+ * The cipher must be initialized for the requested operation before being used
+ * by a {@code CipherInputStream}. For example, if a cipher initialized for
+ * decryption is used with a {@code CipherInputStream}, the {@code
+ * CipherInputStream} tries to read the data an decrypt them before returning.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class CipherInputStream extends FilterInputStream {
+
+ private final Cipher cipher;
+ private final int I_BUFFER_SIZE = 20;
+ private final byte[] i_buffer = new byte[I_BUFFER_SIZE];
+ private int index; // index of the bytes to return from o_buffer
+ private byte[] o_buffer;
+ private boolean finished;
+
+ /**
+ * Creates a new {@code CipherInputStream} instance for an {@code
+ * InputStream} and a cipher.
+ *
+ * @param is
+ * the input stream to read data from.
+ * @param c
+ * the cipher to process the data with.
+ * @since Android 1.0
+ */
+ public CipherInputStream(InputStream is, Cipher c) {
+ super(is);
+ this.cipher = c;
+ }
+
+ /**
+ * Creates a new {@code CipherInputStream} instance for an {@code
+ * InputStream} without a cipher.
+ * <p>
+ * A {@code NullCipher} is created and used to process the data.
+ * </p>
+ *
+ * @param is
+ * the input stream to read data from.
+ * @since Android 1.0
+ */
+ protected CipherInputStream(InputStream is) {
+ this(is, new NullCipher());
+ }
+
+ /**
+ * Reads the next byte from this cipher input stream.
+ *
+ * @return the next byte, or {@code -1} if the end of the stream is reached.
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public int read() throws IOException {
+ if (finished) {
+ return ((o_buffer == null) || (index == o_buffer.length))
+ ? -1
+ : o_buffer[index++] & 0xFF;
+ }
+ if ((o_buffer != null) && (index < o_buffer.length)) {
+ return o_buffer[index++] & 0xFF;
+ }
+ index = 0;
+ o_buffer = null;
+ int num_read;
+ while (o_buffer == null) {
+ if ((num_read = in.read(i_buffer)) == -1) {
+ try {
+ o_buffer = cipher.doFinal();
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ finished = true;
+ break;
+ }
+ o_buffer = cipher.update(i_buffer, 0, num_read);
+ }
+ return read();
+ }
+
+ /**
+ * Reads the next {@code b.length} bytes from this input stream into buffer
+ * {@code b}.
+ *
+ * @param b
+ * the buffer to be filled with data.
+ * @return the number of bytes filled into buffer {@code b}, or {@code -1}
+ * if the end of the stream is reached.
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ /**
+ * Reads the next {@code len} bytes from this input stream into buffer
+ * {@code b} starting at offset {@code off}.
+ * <p>
+ * if {@code b} is {@code null}, the next {@code len} bytes are read and
+ * discarded.
+ * </p>
+ *
+ * @param b
+ * the buffer to be filled with data.
+ * @param off
+ * the offset to start in the buffer.
+ * @param len
+ * the maximum number of bytes to read.
+ * @return the number of bytes filled into buffer {@code b}, or {@code -1}
+ * of the of the stream is reached.
+ * @throws IOException
+ * if an error occurs.
+ * @throws NullPointerException
+ * if the underlying input stream is {@code null}.
+ * @since Android 1.0
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (in == null) {
+ throw new NullPointerException("Underlying input stream is null");
+ }
+
+ int read_b;
+ int i;
+ for (i=0; i<len; i++) {
+ if ((read_b = read()) == -1) {
+ return (i == 0) ? -1 : i;
+ }
+ if (b != null) {
+ b[off+i] = (byte) read_b;
+ }
+ }
+ return i;
+ }
+
+ /**
+ * Skips up to n bytes from this input stream.
+ * <p>
+ * The number of bytes skipped depends on the result of a call to
+ * {@link CipherInputStream#available() available}. The smaller of n and the
+ * result are the number of bytes being skipped.
+ * </p>
+ * Skipping is (currently) not supported in Android.
+ *
+ * @param n
+ * the number of bytes that should be skipped.
+ * @return the number of bytes actually skipped.
+ * @throws IOException
+ * if an error occurs
+ * @since Android 1.0
+ */
+ @Override
+ public long skip(long n) throws IOException {
+ long i = 0;
+ int available = available();
+ if (available < n) {
+ n = available;
+ }
+ while ((i < n) && (read() != -1)) {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * Returns the number of bytes available without blocking. It (currently)
+ * always returns {@code 0} in Android.
+ *
+ * @return the number of bytes available, currently zero.
+ * @throws IOException
+ * if an error occurs
+ * @since Android 1.0
+ */
+ @Override
+ public int available() throws IOException {
+ return 0;
+ }
+
+ /**
+ * Closes this {@code CipherInputStream}, also closes the underlying input
+ * stream and call {@code doFinal} on the cipher object.
+ *
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public void close() throws IOException {
+ in.close();
+ try {
+ cipher.doFinal();
+ } catch (GeneralSecurityException ignore) {
+ //do like RI does
+ }
+
+ }
+
+ /**
+ * Returns whether this input stream supports {@code mark} and {@code reset}
+ * , which it does not.
+ *
+ * @return false, since this input stream does not support {@code mark} and
+ * {@code reset}.
+ * @since Android 1.0
+ */
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/CipherOutputStream.java b/crypto/src/main/java/javax/crypto/CipherOutputStream.java
new file mode 100644
index 0000000..8bce42b
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/CipherOutputStream.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.crypto.NullCipher;
+
+/**
+ * This class wraps an output stream and a cipher so that {@code write} methods
+ * send the data through the cipher before writing them to the underlying output
+ * stream.
+ * <p>
+ * The cipher must be initialized for the requested operation before being used
+ * by a {@code CipherOutputStream}. For example, if a cipher initialized for
+ * encryption is used with a {@code CipherOutputStream}, the {@code
+ * CipherOutputStream} tries to encrypt the data writing it out.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class CipherOutputStream extends FilterOutputStream {
+
+ private final Cipher cipher;
+ private final byte[] arr = new byte[1];
+
+ /**
+ * Creates a new {@code CipherOutputStream} instance for an {@code
+ * OutputStream} and a {@code Cipher}.
+ *
+ * @param os
+ * the output stream to write data to.
+ * @param c
+ * the cipher to process the data with.
+ * @since Android 1.0
+ */
+ public CipherOutputStream(OutputStream os, Cipher c) {
+ super(os);
+ cipher = c;
+ }
+
+ /**
+ * Creates a new {@code CipherOutputStream} instance for an {@code
+ * OutputStream} without a cipher.
+ * <p>
+ * A {@code NullCipher} is created to process the data.
+ * </p>
+ *
+ * @param os
+ * the output stream to write the data to.
+ * @since Android 1.0
+ */
+ protected CipherOutputStream(OutputStream os) {
+ this(os, new NullCipher());
+ }
+
+ /**
+ * Writes the single byte to this cipher output stream.
+ *
+ * @param b
+ * the byte to write.
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public void write(int b) throws IOException {
+ byte[] result;
+ arr[0] = (byte) b;
+ result = cipher.update(arr);
+ if (result != null) {
+ out.write(result);
+ }
+ }
+
+ /**
+ * Writes the buffer of bytes to this cipher output stream.
+ *
+ * @param b
+ * the buffer of bytes.
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ /**
+ * Writes the {@code len} bytes from buffer {@code b} starting at offset
+ * {@code off} to this cipher output stream.
+ *
+ * @param b
+ * the buffer.
+ * @param off
+ * the offset to start at.
+ * @param len
+ * the number of bytes.
+ * @throws IOException
+ * if an error occurs.
+ * @since Android 1.0
+ */
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (len == 0) {
+ return;
+ }
+ byte[] result = cipher.update(b, off, len);
+ if (result != null) {
+ out.write(result);
+ }
+ }
+
+ /**
+ * Flushes this cipher output stream.
+ *
+ * @throws IOException
+ * if an error occurs
+ */
+ @Override
+ public void flush() throws IOException {
+ out.flush();
+ }
+
+ /**
+ * Close this cipher output stream.
+ * <p>
+ * On the underlying cipher {@code doFinal} will be invoked, and any
+ * buffered bytes from the cipher are also written out, and the cipher is
+ * reset to its initial state. The underlying output stream is also closed.
+ *
+ * @throws IOException
+ * if an error occurs.
+ */
+ @Override
+ public void close() throws IOException {
+ byte[] result;
+ try {
+ if (cipher != null) {
+ result = cipher.doFinal();
+ if (result != null) {
+ out.write(result);
+ }
+ }
+ if (out != null) {
+ out.flush();
+ }
+ } catch (BadPaddingException e) {
+ throw new IOException(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new IOException(e.getMessage());
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/CipherSpi.java b/crypto/src/main/java/javax/crypto/CipherSpi.java
new file mode 100644
index 0000000..f6da929
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/CipherSpi.java
@@ -0,0 +1,589 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.nio.ByteBuffer;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for
+ * cryptographic ciphers.
+ * <p>
+ * Implementers of cryptographic ciphers must implement all the abstract methods
+ * for every cipher they implement. {@code CipherSpi} instances are created
+ * along with ciphers when the {@link Cipher#getInstance} method is called. A
+ * {@code Cipher} is referenced by a <i>transformation</i>, which is a string
+ * that describes the operation (or set of operations), always consisting of the
+ * cipher's name and optionally followed by a mode and a padding, in the form:
+ * <ul>
+ * <li>"algorithm"</li>or
+ * <li>"algorithm/mode/padding"</li>
+ * </ul>
+ * The following behavior should be implemented for obtaining {@code Cipher}
+ * instances.
+ * </p>
+ * When one of the {@link Cipher#getInstance} factory methods is called with a
+ * <i>transformation</i> that is only an <i>algorithm</i>, check if the provider
+ * defines a {@code CipherSpi} for "algorithm", if so: return it, otherwise
+ * throw a {@link NoSuchAlgorithmException}.
+ * <p>
+ * The following rules apply when a <i>transformation</i> is of the form
+ * "algorithm/mode/padding":
+ * <ul>
+ * 1. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm/mode/padding": return it, otherwise go to step 2.
+ * </ul>
+ * <ul>
+ * 2. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm/mode": instantiate it, call
+ * {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the
+ * padding name and return it, otherwise go to step 3.
+ * </ul>
+ * <ul>
+ * 3. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm//padding": instantiate it, call
+ * {@link CipherSpi#engineSetMode(String) engineSetMode(String)} for the mode
+ * name and return it, otherwise go to step 4.
+ * </ul>
+ * <ul>
+ * 4. The Provider has a {@code CipherSpi} subclass registered for "algorithm":
+ * instantiate it, call {@link CipherSpi#engineSetMode(String)
+ * engineSetMode(String)} for the mode name , call
+ * {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the
+ * padding name and return it, otherwise throw a
+ * {@link NoSuchAlgorithmException}.
+ * </ul>
+ * </p>
+ *
+ * @see Cipher
+ * @since Android 1.0
+ */
+public abstract class CipherSpi {
+
+ /**
+ * Creates a new {@code CipherSpi} instance.
+ *
+ * @since Android 1.0
+ */
+ public CipherSpi() {
+ }
+
+ /**
+ * Sets the mode for this cipher.
+ *
+ * @param mode
+ * the name of the cipher mode.
+ * @throws NoSuchAlgorithmException
+ * if the specified cipher mode is not supported by this
+ * provider.
+ * @since Android 1.0
+ */
+ protected abstract void engineSetMode(String mode)
+ throws NoSuchAlgorithmException;
+
+ /**
+ * Sets the padding method for this cipher.
+ *
+ * @param padding
+ * the name of the padding method.
+ * @throws NoSuchPaddingException
+ * if the specified padding method is not supported by this
+ * cipher.
+ * @since Android 1.0
+ */
+ protected abstract void engineSetPadding(String padding)
+ throws NoSuchPaddingException;
+
+ /**
+ * Returns the block size of this cipher (in bytes)
+ *
+ * @return the block size of this cipher, or zero if this cipher is not a
+ * block cipher.
+ * @since Android 1.0
+ */
+ protected abstract int engineGetBlockSize();
+
+ /**
+ * Returns the size for a buffer (in bytes), that the next call to {@code
+ * update} of {@code doFinal} would return, taking into account any buffered
+ * data from previous {@code update} calls and padding.
+ * <p>
+ * The actual output length of the next call to {@code update} or {@code
+ * doFinal} may be smaller than the length returned by this method.
+ * </p>
+ *
+ * @param inputLen
+ * the length of the input (in bytes).
+ * @return the size for a buffer (in bytes).
+ * @since Android 1.0
+ */
+ protected abstract int engineGetOutputSize(int inputLen);
+
+ /**
+ * Returns the Initialization Vector (IV) that was used to initialize this
+ * cipher or {@code null} if none was used.
+ *
+ * @return the Initialization Vector (IV), or {@code null} if none was used.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineGetIV();
+
+ /**
+ * Returns the parameters that where used to create this cipher instance.
+ * <p>
+ * These may be a the same parameters that were used to create this cipher
+ * instance, or may be a combination of default and random parameters,
+ * depending on the underlying cipher implementation.
+ * </p>
+ *
+ * @return the parameters that where used to create this cipher instance, or
+ * {@code null} if this cipher instance does not have any parameters
+ * at all.
+ * @since Android 1.0
+ */
+ protected abstract AlgorithmParameters engineGetParameters();
+
+ /**
+ * Initializes this cipher instance with the specified key and a source of
+ * randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters or random values
+ * that the specified key cannot provide, the underlying implementation of
+ * this cipher is supposed to generate the required parameters (using its
+ * provider or random values). Random values will be generated using {@code
+ * random};
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException;
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random}.
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ * @throws InvalidAlgorithmParameterException
+ * it the specified parameters are inappropriate for this
+ * cipher.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(int opmode, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * </p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random}.
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ * </p>
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are inappropriate for this
+ * cipher.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(int opmode, Key key,
+ AlgorithmParameters params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are returned.
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @return the transformed bytes in a new buffer, or {@code null} if the
+ * input has zero length.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is null, or if {@code inputOffset} and {@code
+ * inputLen} do not specify a valid chunk in the input buffer.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
+ int inputLen);
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are stored in the {@code output} buffer.
+ * <p>
+ * If the size of the {@code output} buffer is too small to hold the result,
+ * a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ * </p>
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @param output
+ * the output buffer.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in output.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @since Android 1.0
+ */
+ protected abstract int engineUpdate(byte[] input, int inputOffset,
+ int inputLen, byte[] output, int outputOffset)
+ throws ShortBufferException;
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * {@code input.remaining()} bytes starting at {@code input.position()} are
+ * transformed and stored in the {@code output} buffer.
+ * <p>
+ * If the {@code output.remaining()} is too small to hold the transformed
+ * bytes a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ * </p>
+ *
+ * @param input
+ * the input buffer to transform.
+ * @param output
+ * the output buffer to store the result within.
+ * @return the number of bytes stored in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @since Android 1.0
+ */
+ protected int engineUpdate(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ if (input == null) {
+ throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
+ }
+ if (output == null) {
+ throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
+ }
+ int position = input.position();
+ int limit = input.limit();
+ if ((limit - position) <= 0) {
+ return 0;
+ }
+ byte[] bInput;
+ byte[] bOutput;
+ if (input.hasArray()) {
+ bInput = input.array();
+ int offset = input.arrayOffset();
+ bOutput = engineUpdate(bInput, offset + position, limit - position);
+ input.position(limit);
+ } else {
+ bInput = new byte[limit - position];
+ input.get(bInput);
+ bOutput = engineUpdate(bInput, 0, limit - position);
+ }
+ if (output.remaining() < bOutput.length) {
+ throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
+ }
+ try {
+ output.put(bOutput);
+ } catch (java.nio.BufferOverflowException e) {
+ throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
+ }
+ return bOutput.length;
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
+ * inputOffset}, and any bytes that have been buffered in previous {@code
+ * update} calls.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @return the final bytes from the transformation.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
+ int inputLen) throws IllegalBlockSizeException, BadPaddingException;
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at
+ * {@code inputOffset}, and any bytes that have been buffered in previous
+ * {@code update} calls.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @param output
+ * the output buffer for the transformed bytes.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @since Android 1.0
+ */
+ protected abstract int engineDoFinal(byte[] input, int inputOffset,
+ int inputLen, byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException;
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code input.remaining()} bytes in {@code input} buffer at
+ * {@code input.position()}, and any bytes that have been buffered in
+ * previous {@code update} calls. The transformed bytes are placed into
+ * {@code output} buffer.
+ * </p>
+ *
+ * @param input
+ * the input buffer.
+ * @param output
+ * the output buffer.
+ * @return the number of bytes placed into the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalArgumentException
+ * if the input buffer and the output buffer are the same
+ * object.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ */
+ protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ if (input == null) {
+ throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
+ }
+ if (output == null) {
+ throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
+ }
+ int position = input.position();
+ int limit = input.limit();
+
+ if ((limit - position) <= 0) {
+ return 0;
+ }
+ byte[] bInput;
+ byte[] bOutput;
+
+ if (input.hasArray()) {
+ bInput = input.array();
+ int offset = input.arrayOffset();
+ bOutput = engineDoFinal(bInput, offset + position, limit - position);
+ input.position(limit);
+ } else {
+ bInput = new byte[limit - position];
+ input.get(bInput);
+ bOutput = engineDoFinal(bInput, 0, limit - position);
+ }
+ if (output.remaining() < bOutput.length) {
+ throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
+ }
+ try {
+ output.put(bOutput);
+ } catch (java.nio.BufferOverflowException e) {
+ throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
+ }
+ return bOutput.length;
+ }
+
+ /**
+ * Wraps a key using this cipher instance. This method has been added to
+ * this class (for backwards compatibility, it cannot be abstract). If this
+ * method is not overridden, it throws an {@code
+ * UnsupportedOperationException}.
+ *
+ * @param key
+ * the key to wrap.
+ * @return the wrapped key
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws InvalidKeyException
+ * if this cipher instance cannot wrap this key.
+ * @since Android 1.0
+ */
+ protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
+ InvalidKeyException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.10")); //$NON-NLS-1$
+ }
+
+ /**
+ * Unwraps a key using this cipher instance.
+ * <p>
+ * This method has been added to this class (for backwards compatibility, it
+ * cannot be abstract). If this method is not overridden, it throws an
+ * {@code UnsupportedOperationException}.
+ * </p>
+ *
+ * @param wrappedKey
+ * the wrapped key to unwrap.
+ * @param wrappedKeyAlgorithm
+ * the algorithm for the wrapped key.
+ * @param wrappedKeyType
+ * the type of the wrapped key (one of: {@code SECRET_KEY},
+ * {@code PRIVATE_KEY} or {@code PUBLIC_KEY})
+ * @return the unwrapped key.
+ * @throws InvalidKeyException
+ * if the {@code wrappedKey} cannot be unwrapped to a key of
+ * type {@code wrappedKeyType} for the {@code
+ * wrappedKeyAlgorithm}.
+ * @throws NoSuchAlgorithmException
+ * if no provider can be found that can create a key of type
+ * {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
+ * @since Android 1.0
+ */
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType) throws InvalidKeyException,
+ NoSuchAlgorithmException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.11")); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the size of a specified key object in bits. This method has been
+ * added to this class (for backwards compatibility, it cannot be abstract).
+ * If this method is not overridden, it throws an {@code
+ * UnsupportedOperationException}.
+ *
+ * @param key
+ * the key to get the size for.
+ * @return the size of a specified key object in bits.
+ * @throws InvalidKeyException
+ * if the size of the key cannot be determined by this
+ * implementation.
+ * @since Android 1.0
+ */
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.12")); //$NON-NLS-1$
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java b/crypto/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java
new file mode 100644
index 0000000..301cd49
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/EncryptedPrivateKeyInfo.java
@@ -0,0 +1,566 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.asn1.ASN1Any;
+import org.apache.harmony.security.asn1.ASN1Implicit;
+import org.apache.harmony.security.asn1.ASN1Integer;
+import org.apache.harmony.security.asn1.ASN1OctetString;
+import org.apache.harmony.security.asn1.ASN1Sequence;
+import org.apache.harmony.security.asn1.ASN1SetOf;
+import org.apache.harmony.security.asn1.ASN1Type;
+import org.apache.harmony.security.utils.AlgNameMapper;
+import org.apache.harmony.security.x509.AlgorithmIdentifier;
+
+
+/**
+ * This class implements the {@code EncryptedPrivateKeyInfo} ASN.1 type as
+ * specified in <a href="http://www.ietf.org/rfc/rfc5208.txt">PKCS
+ * #8 - Private-Key Information Syntax Standard</a>.
+ * <p>
+ * The definition of ASN.1 is as follows:
+ * </p>
+ * <dl>
+ * EncryptedPrivateKeyInfo ::= SEQUENCE {
+ * <dd>encryptionAlgorithm AlgorithmIdentifier,</dd>
+ * <dd>encryptedData OCTET STRING }</dd>
+ * </dl>
+ * <dl>
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * <dd>algorithm OBJECT IDENTIFIER,</dd>
+ * <dd>parameters ANY DEFINED BY algorithm OPTIONAL }</dd>
+ * </dl>
+ *
+ * @since Android 1.0
+ */
+public class EncryptedPrivateKeyInfo {
+ // Encryption algorithm name
+ private String algName;
+ // Encryption algorithm parameters
+ private final AlgorithmParameters algParameters;
+ // Encrypted private key data
+ private final byte[] encryptedData;
+ // Encryption algorithm OID
+ private String oid;
+ // This EncryptedPrivateKeyInfo ASN.1 DER encoding
+ private volatile byte[] encoded;
+
+ /**
+ * Creates an {@code EncryptedPrivateKeyInfo} instance from its encoded
+ * representation by parsing it.
+ *
+ * @param encoded
+ * the encoded representation of this object
+ * @throws IOException
+ * if parsing the encoded representation fails.
+ * @throws NullPointerException
+ * if {@code encoded} is {@code null}.
+ * @since Android 1.0
+ */
+ public EncryptedPrivateKeyInfo(byte[] encoded)
+ throws IOException {
+ if (encoded == null) {
+ throw new NullPointerException(Messages.getString("crypto.22")); //$NON-NLS-1$
+ }
+ this.encoded = new byte[encoded.length];
+ System.arraycopy(encoded, 0, this.encoded, 0, encoded.length);
+ Object[] values;
+
+ values = (Object[])asn1.decode(encoded);
+
+ AlgorithmIdentifier aId = (AlgorithmIdentifier) values[0];
+
+ algName = aId.getAlgorithm();
+ // algName == oid now
+ boolean mappingExists = mapAlgName();
+ // algName == name from map oid->name if mapping exists, or
+ // algName == oid if mapping does not exist
+
+ AlgorithmParameters aParams = null;
+ byte[] params = aId.getParameters();
+ if (params != null && !isNullValue(params)) {
+ try {
+ aParams = AlgorithmParameters.getInstance(algName);
+ aParams.init(aId.getParameters());
+ if (!mappingExists) {
+ algName = aParams.getAlgorithm();
+ }
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ algParameters = aParams;
+
+ encryptedData = (byte[]) values[1];
+ }
+
+ private static boolean isNullValue(byte[] toCheck) {
+ return toCheck[0] == 5 && toCheck[1] == 0;
+ }
+
+ /**
+ * Creates an {@code EncryptedPrivateKeyInfo} instance from an algorithm
+ * name and its encrypted data.
+ *
+ * @param encrAlgName
+ * the name of an algorithm.
+ * @param encryptedData
+ * the encrypted data.
+ * @throws NoSuchAlgorithmException
+ * if the {@code encrAlgName} is not a supported algorithm.
+ * @throws NullPointerException
+ * if {@code encrAlgName} or {@code encryptedData} is {@code
+ * null}.
+ * @throws IllegalArgumentException
+ * if {@code encryptedData} is empty.
+ * @since Android 1.0
+ */
+ public EncryptedPrivateKeyInfo(String encrAlgName, byte[] encryptedData)
+ throws NoSuchAlgorithmException {
+ if (encrAlgName == null) {
+ throw new NullPointerException(Messages.getString("crypto.23")); //$NON-NLS-1$
+ }
+ this.algName = encrAlgName;
+ if (!mapAlgName()) {
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.24", this.algName)); //$NON-NLS-1$
+ }
+ if (encryptedData == null) {
+ throw new NullPointerException(
+ Messages.getString("crypto.25")); //$NON-NLS-1$
+ }
+ if (encryptedData.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.26")); //$NON-NLS-1$
+ }
+ this.encryptedData = new byte[encryptedData.length];
+ System.arraycopy(encryptedData, 0,
+ this.encryptedData, 0, encryptedData.length);
+ this.algParameters = null;
+ }
+
+ /**
+ * Creates an {@code EncryptedPrivateKeyInfo} instance from the
+ * encryption algorithm parameters an its encrypted data.
+ *
+ * @param algParams
+ * the encryption algorithm parameters.
+ * @param encryptedData
+ * the encrypted data.
+ * @throws NoSuchAlgorithmException
+ * if the algorithm name of the specified {@code algParams}
+ * parameter is not supported.
+ * @throws NullPointerException
+ * if {@code algParams} or {@code encryptedData} is
+ * {@code null}.
+ * @since Android 1.0
+ */
+ public EncryptedPrivateKeyInfo(AlgorithmParameters algParams,
+ byte[] encryptedData)
+ throws NoSuchAlgorithmException {
+ if (algParams == null) {
+ throw new NullPointerException(Messages.getString("crypto.27")); //$NON-NLS-1$
+ }
+ this.algParameters = algParams;
+ if (encryptedData == null) {
+ throw new NullPointerException(
+ Messages.getString("crypto.25")); //$NON-NLS-1$
+ }
+ if (encryptedData.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.26")); //$NON-NLS-1$
+ }
+ this.encryptedData = new byte[encryptedData.length];
+ System.arraycopy(encryptedData, 0,
+ this.encryptedData, 0, encryptedData.length);
+ this.algName = this.algParameters.getAlgorithm();
+ if (!mapAlgName()) {
+ throw new NoSuchAlgorithmException(Messages.getString("crypto.24", this.algName)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Returns the name of the encryption algorithm.
+ *
+ * @return the name of the encryption algorithm.
+ * @since Android 1.0
+ */
+ public String getAlgName() {
+ return algName;
+ }
+
+ /**
+ * Returns the parameters used by the encryption algorithm.
+ *
+ * @return the parameters used by the encryption algorithm.
+ * @since Android 1.0
+ */
+ public AlgorithmParameters getAlgParameters() {
+ return algParameters;
+ }
+
+ /**
+ * Returns the encrypted data of this key.
+ *
+ * @return the encrypted data of this key, each time this method is called a
+ * new array is returned.
+ * @since Android 1.0
+ */
+ public byte[] getEncryptedData() {
+ byte[] ret = new byte[encryptedData.length];
+ System.arraycopy(encryptedData, 0, ret, 0, encryptedData.length);
+ return ret;
+ }
+
+ /**
+ * Returns the {@code PKCS8EncodedKeySpec} object extracted from the
+ * encrypted data.
+ * <p>
+ * The cipher must be initialize in either {@code Cipher.DECRYPT_MODE} or
+ * {@code Cipher.UNWRAP_MODE} with the same parameters and key used for
+ * encrypting this.
+ * </p>
+ *
+ * @param cipher
+ * the cipher initialized for decrypting the encrypted data.
+ * @return the extracted {@code PKCS8EncodedKeySpec}.
+ * @throws InvalidKeySpecException
+ * if the specified cipher is not suited to decrypt the
+ * encrypted data.
+ * @throws NullPointerException
+ * if {@code cipher} is {@code null}.
+ * @since Android 1.0
+ */
+ public PKCS8EncodedKeySpec getKeySpec(Cipher cipher)
+ throws InvalidKeySpecException {
+ if (cipher == null) {
+ throw new NullPointerException(Messages.getString("crypto.28")); //$NON-NLS-1$
+ }
+ try {
+ byte[] decryptedData = cipher.doFinal(encryptedData);
+ try {
+ ASN1PrivateKeyInfo.verify(decryptedData);
+ } catch (IOException e1) {
+ throw new InvalidKeySpecException(
+ Messages.getString("crypto.29")); //$NON-NLS-1$
+ }
+ return new PKCS8EncodedKeySpec(decryptedData);
+ } catch (IllegalStateException e) {
+ throw new InvalidKeySpecException(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new InvalidKeySpecException(e.getMessage());
+ } catch (BadPaddingException e) {
+ throw new InvalidKeySpecException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns the {@code PKCS8EncodedKeySpec} object extracted from the
+ * encrypted data.
+ *
+ * @param decryptKey
+ * the key to decrypt the encrypted data with.
+ * @return the extracted {@code PKCS8EncodedKeySpec}.
+ * @throws NoSuchAlgorithmException
+ * if no usable cipher can be found to decrypt the encrypted
+ * data.
+ * @throws InvalidKeyException
+ * if {@code decryptKey} is not usable to decrypt the encrypted
+ * data.
+ * @throws NullPointerException
+ * if {@code decryptKey} is {@code null}.
+ * @since Android 1.0
+ */
+ public PKCS8EncodedKeySpec getKeySpec(Key decryptKey)
+ throws NoSuchAlgorithmException,
+ InvalidKeyException {
+ if (decryptKey == null) {
+ throw new NullPointerException(Messages.getString("crypto.2A")); //$NON-NLS-1$
+ }
+ try {
+ Cipher cipher = Cipher.getInstance(algName);
+ if (algParameters == null) {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey);
+ } else {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey, algParameters);
+ }
+ byte[] decryptedData = cipher.doFinal(encryptedData);
+ try {
+ ASN1PrivateKeyInfo.verify(decryptedData);
+ } catch (IOException e1) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.29")); //$NON-NLS-1$
+ }
+ return new PKCS8EncodedKeySpec(decryptedData);
+ } catch (NoSuchPaddingException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (IllegalStateException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (BadPaddingException e) {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns the {@code PKCS8EncodedKeySpec} object extracted from the
+ * encrypted data.
+ *
+ * @param decryptKey
+ * the key to decrypt the encrypted data with.
+ * @param providerName
+ * the name of a provider whose cipher implementation should be
+ * used.
+ * @return the extracted {@code PKCS8EncodedKeySpec}.
+ * @throws NoSuchProviderException
+ * if no provider with {@code providerName} can be found.
+ * @throws NoSuchAlgorithmException
+ * if no usable cipher can be found to decrypt the encrypted
+ * data.
+ * @throws InvalidKeyException
+ * if {@code decryptKey} is not usable to decrypt the encrypted
+ * data.
+ * @throws NullPointerException
+ * if {@code decryptKey} or {@code providerName} is {@code null}
+ * .
+ * @since Android 1.0
+ */
+ public PKCS8EncodedKeySpec getKeySpec(Key decryptKey, String providerName)
+ throws NoSuchProviderException,
+ NoSuchAlgorithmException,
+ InvalidKeyException {
+ if (decryptKey == null) {
+ throw new NullPointerException(Messages.getString("crypto.2A")); //$NON-NLS-1$
+ }
+ if (providerName == null) {
+ throw new NullPointerException(
+ Messages.getString("crypto.2B")); //$NON-NLS-1$
+ }
+ try {
+ Cipher cipher = Cipher.getInstance(algName, providerName);
+ if (algParameters == null) {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey);
+ } else {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey, algParameters);
+ }
+ byte[] decryptedData = cipher.doFinal(encryptedData);
+ try {
+ ASN1PrivateKeyInfo.verify(decryptedData);
+ } catch (IOException e1) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.29")); //$NON-NLS-1$
+ }
+ return new PKCS8EncodedKeySpec(decryptedData);
+ } catch (NoSuchPaddingException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (IllegalStateException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (BadPaddingException e) {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns the {@code PKCS8EncodedKeySpec} object extracted from the
+ * encrypted data.
+ *
+ * @param decryptKey
+ * the key to decrypt the encrypted data with.
+ * @param provider
+ * the provider whose cipher implementation should be used.
+ * @return the extracted {@code PKCS8EncodedKeySpec}.
+ * @throws NoSuchAlgorithmException
+ * if no usable cipher can be found to decrypt the encrypted
+ * data.
+ * @throws InvalidKeyException
+ * if {@code decryptKey} is not usable to decrypt the encrypted
+ * data.
+ * @throws NullPointerException
+ * if {@code decryptKey} or {@code provider} is {@code null}.
+ * @since Android 1.0
+ */
+ public PKCS8EncodedKeySpec getKeySpec(Key decryptKey, Provider provider)
+ throws NoSuchAlgorithmException,
+ InvalidKeyException {
+ if (decryptKey == null) {
+ throw new NullPointerException(Messages.getString("crypto.2A")); //$NON-NLS-1$
+ }
+ if (provider == null) {
+ throw new NullPointerException(Messages.getString("crypto.2C")); //$NON-NLS-1$
+ }
+ try {
+ Cipher cipher = Cipher.getInstance(algName, provider);
+ if (algParameters == null) {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey);
+ } else {
+ cipher.init(Cipher.DECRYPT_MODE, decryptKey, algParameters);
+ }
+ byte[] decryptedData = cipher.doFinal(encryptedData);
+ try {
+ ASN1PrivateKeyInfo.verify(decryptedData);
+ } catch (IOException e1) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.29")); //$NON-NLS-1$
+ }
+ return new PKCS8EncodedKeySpec(decryptedData);
+ } catch (NoSuchPaddingException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new NoSuchAlgorithmException(e.getMessage());
+ } catch (IllegalStateException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new InvalidKeyException(e.getMessage());
+ } catch (BadPaddingException e) {
+ throw new InvalidKeyException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns the ASN.1 encoded representation of this object.
+ *
+ * @return the ASN.1 encoded representation of this object.
+ * @throws IOException
+ * if encoding this object fails.
+ * @since Android 1.0
+ */
+ public byte[] getEncoded() throws IOException {
+ if (encoded == null) {
+ // Generate ASN.1 encoding:
+ encoded = asn1.encode(this);
+ }
+ byte[] ret = new byte[encoded.length];
+ System.arraycopy(encoded, 0, ret, 0, encoded.length);
+ return ret;
+ }
+
+ // Performs all needed alg name mappings.
+ // Returns 'true' if mapping available 'false' otherwise
+ private boolean mapAlgName() {
+ if (AlgNameMapper.isOID(this.algName)) {
+ // OID provided to the ctor
+ // get rid of possible leading "OID."
+ this.oid = AlgNameMapper.normalize(this.algName);
+ // try to find mapping OID->algName
+ this.algName = AlgNameMapper.map2AlgName(this.oid);
+ // if there is no mapping OID->algName
+ // set OID as algName
+ if (this.algName == null) {
+ this.algName = this.oid;
+ }
+ } else {
+ String stdName = AlgNameMapper.getStandardName(this.algName);
+ // Alg name provided to the ctor
+ // try to find mapping algName->OID or
+ // (algName->stdAlgName)->OID
+ this.oid = AlgNameMapper.map2OID(this.algName);
+ if (this.oid == null) {
+ if (stdName == null) {
+ // no above mappings available
+ return false;
+ }
+ this.oid = AlgNameMapper.map2OID(stdName);
+ if (this.oid == null) {
+ return false;
+ }
+ this.algName = stdName;
+ } else if (stdName != null) {
+ this.algName = stdName;
+ }
+ }
+ return true;
+ }
+
+ //
+ // EncryptedPrivateKeyInfo DER encoder/decoder.
+ // EncryptedPrivateKeyInfo ASN.1 definition
+ // (as defined in PKCS #8: Private-Key Information Syntax Standard
+ // http://www.ietf.org/rfc/rfc2313.txt)
+ //
+ // EncryptedPrivateKeyInfo ::= SEQUENCE {
+ // encryptionAlgorithm AlgorithmIdentifier,
+ // encryptedData OCTET STRING }
+ //
+
+ private static final byte[] nullParam = new byte[] { 5, 0 };
+
+ private static final ASN1Sequence asn1 = new ASN1Sequence(new ASN1Type[] {
+ AlgorithmIdentifier.ASN1, ASN1OctetString.getInstance() }) {
+
+ @Override
+ protected void getValues(Object object, Object[] values) {
+
+ EncryptedPrivateKeyInfo epki = (EncryptedPrivateKeyInfo) object;
+
+ try {
+ byte[] algParmsEncoded = (epki.algParameters == null) ? nullParam
+ : epki.algParameters.getEncoded();
+ values[0] = new AlgorithmIdentifier(epki.oid, algParmsEncoded);
+ values[1] = epki.encryptedData;
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ };
+
+ // PrivateKeyInfo DER decoder.
+ // PrivateKeyInfo ASN.1 definition
+ // (as defined in PKCS #8: Private-Key Information Syntax Standard
+ // http://www.ietf.org/rfc/rfc2313.txt)
+ //
+ //
+ // PrivateKeyInfo ::= SEQUENCE {
+ // version Version,
+ // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ // privateKey PrivateKey,
+ // attributes [0] IMPLICIT Attributes OPTIONAL }
+ //
+ // Version ::= INTEGER
+ //
+ // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ //
+ // PrivateKey ::= OCTET STRING
+ //
+ // Attributes ::= SET OF Attribute
+
+ private static final ASN1SetOf ASN1Attributes = new ASN1SetOf(ASN1Any.getInstance());
+
+ private static final ASN1Sequence ASN1PrivateKeyInfo = new ASN1Sequence(
+ new ASN1Type[] { ASN1Integer.getInstance(), AlgorithmIdentifier.ASN1,
+ ASN1OctetString.getInstance(),
+ new ASN1Implicit(0, ASN1Attributes) }) {
+ {
+ setOptional(3); //attributes are optional
+ }
+ };
+}
diff --git a/crypto/src/main/java/javax/crypto/ExemptionMechanism.java b/crypto/src/main/java/javax/crypto/ExemptionMechanism.java
new file mode 100644
index 0000000..7c68d28
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/ExemptionMechanism.java
@@ -0,0 +1,396 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+/**
+ * This class implements the functionality of an exemption mechanism such as
+ * <i>key recovery</i>, <i>key weakening</i>, or <i>key escrow</i>.
+ *
+ * @since Android 1.0
+ */
+public class ExemptionMechanism {
+
+ // Used to access common engine functionality
+ private static final Engine engine = new Engine("ExemptionMechanism");
+
+ // Store used provider
+ private final Provider provider;
+
+ // Store used spi implementation
+ private final ExemptionMechanismSpi spiImpl;
+
+ // Store mechanism name
+ private final String mechanism;
+
+ // Store state (initialized or not)
+ private boolean isInit;
+
+ // Store initKey value
+ private Key initKey;
+
+ // Indicates if blob generated successfully
+ private boolean generated;
+
+ /**
+ * Creates a {@code ExemptionMechanism} instance.
+ *
+ * @param exmechSpi
+ * the implementation delegate.
+ * @param provider
+ * the associated provider.
+ * @param mechanism
+ * the name of the mechanism.
+ * @since Android 1.0
+ */
+ protected ExemptionMechanism(ExemptionMechanismSpi exmechSpi,
+ Provider provider, String mechanism) {
+ this.mechanism = mechanism;
+ this.spiImpl = exmechSpi;
+ this.provider = provider;
+ isInit = false;
+ }
+
+ /**
+ * Returns the name of this {@code ExemptionMechanism}.
+ *
+ * @return the name of this {@code ExemptionMechanism}.
+ * @since Android 1.0
+ */
+ public final String getName() {
+ return mechanism;
+ }
+
+ /**
+ * Returns a new {@code ExemptionMechanism} instance that provides the
+ * specified exemption mechanism algorithm.
+ *
+ * @param algorithm
+ * the name of the requested exemption mechanism.
+ * @return the new {@code ExemptionMechanism} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not available by any provider.
+ * @throws NullPointerException
+ * if the algorithm parameter is {@code null}.
+ * @since Android 1.0
+ */
+ public static final ExemptionMechanism getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, null);
+ return new ExemptionMechanism((ExemptionMechanismSpi) engine.spi,
+ engine.provider, algorithm);
+ }
+ }
+
+ /**
+ * Returns a new {@code ExemptionMechansm} instance that provides the
+ * specified exemption mechanism algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested exemption mechanism.
+ * @param provider
+ * the name of the provider that is providing the algorithm.
+ * @return the new {@code ExemptionMechanism} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws NoSuchProviderException
+ * if the specified provider is not available.
+ * @throws NullPointerException
+ * if the algorithm parameter is {@code null}.
+ * @throws IllegalArgumentException
+ * if the provider parameter is {@code null}.
+ * @since Android 1.0
+ */
+ public static final ExemptionMechanism getInstance(String algorithm,
+ String provider) throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ Provider impProvider = Security.getProvider(provider);
+ if (impProvider == null) {
+ throw new NoSuchProviderException(provider);
+ }
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ return getInstance(algorithm, impProvider);
+ }
+
+ /**
+ * Returns a new {@code ExemptionMechanism} instance that provides the
+ * specified exemption mechanism algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested exemption mechanism.
+ * @param provider
+ * the provider that is providing the algorithm.
+ * @return the new {@code ExemptionMechanism} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws NullPointerException
+ * if the algorithm parameter is {@code null}.
+ * @throws IllegalArgumentException
+ * if the provider parameter is {@code null}.
+ * @since Android 1.0
+ */
+ public static final ExemptionMechanism getInstance(String algorithm,
+ Provider provider) throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, provider, null);
+ return new ExemptionMechanism((ExemptionMechanismSpi) engine.spi,
+ provider, algorithm);
+ }
+ }
+
+ /**
+ * Returns the provider of this {@code ExemptionMechanism} instance.
+ *
+ * @return the provider of this {@code ExemptionMechanism} instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Returns whether the result blob for this {@code ExemptionMechanism}
+ * instance has been generated successfully and that the specified key is
+ * the same as the one that was used to initialize and generate.
+ *
+ * @param key
+ * the key to verify.
+ * @return whether the result blob for this {@code ExemptionMechanism}
+ * instance has been generated successfully.
+ * @throws ExemptionMechanismException
+ * if an error occurs while determining whether the result blob
+ * has been generated successfully.
+ * @since Android 1.0
+ */
+ public final boolean isCryptoAllowed(Key key)
+ throws ExemptionMechanismException {
+
+ if (generated
+ && (initKey.equals(key) || Arrays.equals(initKey.getEncoded(),
+ key.getEncoded()))) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the size in bytes for the output buffer needed to hold the output
+ * of the next {@link #genExemptionBlob} call, given the specified {@code
+ * inputLen} (in bytes).
+ *
+ * @param inputLen
+ * the specified input length (in bytes).
+ * @return the size in bytes for the output buffer.
+ * @throws IllegalStateException
+ * if this {@code ExemptionMechanism} instance is not
+ * initialized.
+ * @since Android 1.0
+ */
+ public final int getOutputSize(int inputLen) throws IllegalStateException {
+ if (!isInit) {
+ throw new IllegalStateException(Messages.getString("crypto.2D"));
+ }
+ return spiImpl.engineGetOutputSize(inputLen);
+ }
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the
+ * specified key.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ public final void init(Key key) throws InvalidKeyException,
+ ExemptionMechanismException {
+ generated = false;
+ spiImpl.engineInit(key);
+ initKey = key;
+ isInit = true;
+ }
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the
+ * specified key and algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @param param
+ * the parameters for this exemption mechanism algorithm.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws InvalidAlgorithmParameterException
+ * if the parameters cannot be used to initialize this
+ * mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ public final void init(Key key, AlgorithmParameters param)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException {
+ generated = false;
+ spiImpl.engineInit(key, param);
+ initKey = key;
+ isInit = true;
+ }
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the
+ * specified key and algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @param param
+ * the parameters for this exemption mechanism algorithm.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws InvalidAlgorithmParameterException
+ * the the parameters cannot be used to initialize this
+ * mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ public final void init(Key key, AlgorithmParameterSpec param)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException {
+ generated = false;
+ spiImpl.engineInit(key, param);
+ initKey = key;
+ isInit = true;
+ }
+
+ /**
+ * Generates the result key blob for this exemption mechanism.
+ *
+ * @return the result key blob for this exemption mechanism.
+ * @throws IllegalStateException
+ * if this {@code ExemptionMechanism} instance is not
+ * initialized.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during generation.
+ * @since Android 1.0
+ */
+ public final byte[] genExemptionBlob() throws IllegalStateException,
+ ExemptionMechanismException {
+ if (!isInit) {
+ throw new IllegalStateException(Messages.getString("crypto.2D"));
+ }
+ generated = false;
+ byte[] result = spiImpl.engineGenExemptionBlob();
+ generated = true;
+ return result;
+ }
+
+ /**
+ * Generates the result key blob for this exemption mechanism and stores it
+ * into the {@code output} buffer.
+ *
+ * @param output
+ * the output buffer for the result key blob.
+ * @return the number of bytes written to the {@code output} buffer.
+ * @throws IllegalStateException
+ * if this {@code ExemptionMechanism} instance is not
+ * initialized.
+ * @throws ShortBufferException
+ * if the provided buffer is too small for the result key blob.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during generation.
+ * @since Android 1.0
+ */
+ public final int genExemptionBlob(byte[] output)
+ throws IllegalStateException, ShortBufferException,
+ ExemptionMechanismException {
+ return genExemptionBlob(output, 0);
+ }
+
+ /**
+ * Generates the result key blob for this exemption mechanism and stores it
+ * into the {@code output} buffer at offset {@code outputOffset}.
+ *
+ * @param output
+ * the output buffer for the result key blob.
+ * @param outputOffset
+ * the offset in the output buffer to start.
+ * @return the number of bytes written to the {@code output} buffer.
+ * @throws IllegalStateException
+ * if this {@code ExemptionMechanism} instance is not
+ * initialized.
+ * @throws ShortBufferException
+ * if the provided buffer is too small for the result key blob.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during generation.
+ * @since Android 1.0
+ */
+ public final int genExemptionBlob(byte[] output, int outputOffset)
+ throws IllegalStateException, ShortBufferException,
+ ExemptionMechanismException {
+ if (!isInit) {
+ throw new IllegalStateException(Messages.getString("crypto.2D"));
+ }
+ generated = false;
+ int len = spiImpl.engineGenExemptionBlob(output, outputOffset);
+ generated = true;
+ return len;
+ }
+
+ /**
+ * Frees the references to the key used to initialize this instance.
+ *
+ * @since Android 1.0
+ */
+ @Override
+ protected void finalize() {
+ initKey = null;
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/ExemptionMechanismException.java b/crypto/src/main/java/javax/crypto/ExemptionMechanismException.java
new file mode 100644
index 0000000..3af498b
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/ExemptionMechanismException.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * This is the base class for {@code ExemptionMechanismException}.
+ *
+ * @since Android 1.0
+ */
+public class ExemptionMechanismException extends GeneralSecurityException {
+
+ /**
+ * @serial
+ */
+ private static final long serialVersionUID = 1572699429277957109L;
+
+ /**
+ * Creates a new {@code ExemptionMechanismException} with the specified
+ * message.
+ *
+ * @param msg
+ * the exception message.
+ * @since Android 1.0
+ */
+ public ExemptionMechanismException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new {@code ExemptionMechanismException} with no message.
+ *
+ * @since Android 1.0
+ */
+ public ExemptionMechanismException() {
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/ExemptionMechanismSpi.java b/crypto/src/main/java/javax/crypto/ExemptionMechanismSpi.java
new file mode 100644
index 0000000..cef1516
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/ExemptionMechanismSpi.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>) definition for the {@code
+ * ExemptionMechanism} class.
+ *
+ * @since Android 1.0
+ */
+public abstract class ExemptionMechanismSpi {
+
+ /**
+ * Creates a new {@code ExemptionMechanismSpi} instance.
+ *
+ * @since Android 1.0
+ */
+ public ExemptionMechanismSpi() {
+ }
+
+ /**
+ * Generates the result key blob for this exemption mechanism.
+ *
+ * @return the result key blob for this exemption mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during generation.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineGenExemptionBlob()
+ throws ExemptionMechanismException;
+
+ /**
+ * Generates the result key blob for this exemption mechanism and stores it
+ * into the {@code output} buffer at offset {@code outputOffset}.
+ *
+ * @param output
+ * the output buffer for the result key blob.
+ * @param outputOffset
+ * the offset in the output buffer to start.
+ * @return the number of bytes written to the {@code output} buffer.
+ * @throws ShortBufferException
+ * if the provided buffer is too small for the result key blob.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during generation.
+ * @since Android 1.0
+ */
+ protected abstract int engineGenExemptionBlob(byte[] output,
+ int outputOffset) throws ShortBufferException,
+ ExemptionMechanismException;
+
+ /**
+ * Returns the size in bytes for the output buffer needed to hold the output
+ * of the next {@link #engineGenExemptionBlob} call, given the specified
+ * {@code inputLen} (in bytes).
+ *
+ * @param inputLen
+ * the specified input length (in bytes).
+ * @return the size in bytes for the output buffer.
+ */
+ protected abstract int engineGetOutputSize(int inputLen);
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the specified
+ * key.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key) throws InvalidKeyException,
+ ExemptionMechanismException;
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the specified
+ * key and algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @param params
+ * the parameters for this exemption mechanism algorithm.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws InvalidAlgorithmParameterException
+ * if the parameters cannot be used to initialize this
+ * mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameters params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException;
+
+ /**
+ * Initializes this {@code ExemptionMechanism} instance with the specified
+ * key and algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this instance with.
+ * @param params
+ * the parameters for this exemption mechanism algorithm.
+ * @throws InvalidKeyException
+ * if the key cannot be used to initialize this mechanism.
+ * @throws InvalidAlgorithmParameterException
+ * the the parameters cannot be used to initialize this
+ * mechanism.
+ * @throws ExemptionMechanismException
+ * if error(s) occur during initialization.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException;
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/IllegalBlockSizeException.java b/crypto/src/main/java/javax/crypto/IllegalBlockSizeException.java
new file mode 100644
index 0000000..e376b85
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/IllegalBlockSizeException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * The exception, that is thrown when the data length provided to a block cipher
+ * does not match the block size of the cipher.
+ *
+ * @since Android 1.0
+ */
+public class IllegalBlockSizeException extends GeneralSecurityException {
+
+ /**
+ * @serial
+ */
+ private static final long serialVersionUID = -1965144811953540392L;
+
+ /**
+ * Creates a new {@code IllegalBlockSizeException} with the specified
+ * message.
+ *
+ * @param msg
+ * the message
+ * @since Android 1.0
+ */
+ public IllegalBlockSizeException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new {@code IllegalBlockSizeException}.
+ *
+ * @since Android 1.0
+ */
+ public IllegalBlockSizeException() {
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/KeyAgreement.java b/crypto/src/main/java/javax/crypto/KeyAgreement.java
new file mode 100644
index 0000000..ee1f195
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/KeyAgreement.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+/**
+ * This class provides the functionality for a key exchange protocol. This
+ * enables two or more parties to agree on a secret key for symmetric
+ * cryptography.
+ *
+ * @since Android 1.0
+ */
+public class KeyAgreement {
+
+ // Used to access common engine functionality
+ private static final Engine engine = new Engine("KeyAgreement"); //$NON-NLS-1$
+
+ // Store SecureRandom
+ private static final SecureRandom rndm = new SecureRandom();
+
+ // Store used provider
+ private final Provider provider;
+
+ // Store used spi implementation
+ private final KeyAgreementSpi spiImpl;
+
+ // Store used algorithm name
+ private final String algorithm;
+
+ /**
+ * Creates a new {@code KeyAgreement} instance.
+ *
+ * @param keyAgreeSpi
+ * the <b>SPI</b> delegate.
+ * @param provider
+ * the provider providing this KeyAgreement.
+ * @param algorithm
+ * the name of the key agreement algorithm.
+ * @since Android 1.0
+ */
+ protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
+ String algorithm) {
+ this.provider = provider;
+ this.algorithm = algorithm;
+ this.spiImpl = keyAgreeSpi;
+ }
+
+ /**
+ * Returns the name of the key agreement algorithm.
+ *
+ * @return the name of the key agreement algorithm.
+ * @since Android 1.0
+ */
+ public final String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Returns the provider for this {@code KeyAgreement} instance.
+ *
+ * @return the provider for this {@code KeyAgreement} instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Creates a new {@code KeyAgreement} for the specified algorithm.
+ *
+ * @param algorithm
+ * the name of the key agreement algorithm to create.
+ * @return a key agreement for the specified algorithm.
+ * @throws NoSuchAlgorithmException
+ * if no installed provider can provide the requested algorithm.
+ * @throws NullPointerException
+ * if the specified algorithm is {@code null}.
+ * @since Android 1.0
+ */
+ public static final KeyAgreement getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, null);
+ return new KeyAgreement((KeyAgreementSpi) engine.spi, engine.provider,
+ algorithm);
+ }
+ }
+
+ /**
+ * Creates a new {@code KeyAgreement} for the specified algorithm from the
+ * specified provider.
+ *
+ * @param algorithm
+ * the name of the key agreement algorithm to create.
+ * @param provider
+ * the name of the provider that provides the requested
+ * algorithm.
+ * @return a key agreement for the specified algorithm from the specified
+ * provider.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider cannot provide the requested
+ * algorithm.
+ * @throws NoSuchProviderException
+ * if the specified provider does not exist.
+ * @throws IllegalArgumentException
+ * if the specified provider name is {@code null} or empty.
+ * @since Android 1.0
+ */
+ public static final KeyAgreement getInstance(String algorithm,
+ String provider) throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if ((provider == null) || (provider.length() == 0)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.03")); //$NON-NLS-1$
+ }
+ Provider impProvider = Security.getProvider(provider);
+ if (impProvider == null) {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, impProvider);
+ }
+
+ /**
+ * Create a new {@code KeyAgreement} for the specified algorithm from the
+ * specified provider.
+ *
+ * @param algorithm
+ * the name of the key agreement algorithm to create.
+ * @param provider
+ * the provider that provides the requested algorithm.
+ * @return a key agreement for the specified algorithm from the specified
+ * provider.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider cannot provide the requested
+ * algorithm.
+ * @throws IllegalArgumentException
+ * if the specified provider is {@code null}.
+ * @throws NullPointerException
+ * if the specified algorithm name is {@code null}.
+ */
+ public static final KeyAgreement getInstance(String algorithm,
+ Provider provider) throws NoSuchAlgorithmException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, provider, null);
+ return new KeyAgreement((KeyAgreementSpi) engine.spi, provider,
+ algorithm);
+ }
+ }
+
+ /**
+ * Initializes this {@code KeyAgreement} with the specified key.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @since Android 1.0
+ */
+ public final void init(Key key) throws InvalidKeyException {
+ spiImpl.engineInit(key, rndm);//new SecureRandom());
+ }
+
+ /**
+ * Initializes this {@code KeyAgreement} with the specified key and the
+ * specified randomness source.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @param random
+ * the source for any randomness needed.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @since Android 1.0
+ */
+ public final void init(Key key, SecureRandom random)
+ throws InvalidKeyException {
+ spiImpl.engineInit(key, random);
+ }
+
+ /**
+ * Initializes this {@code KeyAgreement} with the specified key and the
+ * algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @param params
+ * the parameters for this key agreement algorithm.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are invalid for this key
+ * agreement algorithm.
+ * @since Android 1.0
+ */
+ public final void init(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ spiImpl.engineInit(key, params, rndm);//new SecureRandom());
+ }
+
+ /**
+ * Initializes this {@code KeyAgreement} with the specified key, algorithm
+ * parameters and randomness source.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @param params
+ * the parameters for this key agreement algorithm.
+ * @param random
+ * the source for any randomness needed.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are invalid for this key
+ * agreement algorithm.
+ * @since Android 1.0
+ */
+ public final void init(Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ spiImpl.engineInit(key, params, random);
+ }
+
+ /**
+ * Does the next (or the last) phase of the key agreement, using the
+ * specified key.
+ *
+ * @param key
+ * the key received from the other party for this phase.
+ * @param lastPhase
+ * set to {@code true} if this is the last phase of this key
+ * agreement.
+ * @return the intermediate key from this phase or {@code null} if there is
+ * no intermediate key for this phase.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used in this key agreement or
+ * this phase,
+ * @throws IllegalStateException
+ * if this instance has not been initialized.
+ * @since Android 1.0
+ */
+ public final Key doPhase(Key key, boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException {
+ return spiImpl.engineDoPhase(key, lastPhase);
+ }
+
+ /**
+ * Generates the shared secret.
+ *
+ * @return the generated shared secret.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @since Android 1.0
+ */
+ public final byte[] generateSecret() throws IllegalStateException {
+ return spiImpl.engineGenerateSecret();
+ }
+
+ /**
+ * Generates the shared secret and stores it into the buffer {@code
+ * sharedSecred} at {@code offset}.
+ *
+ * @param sharedSecret
+ * the buffer to store the shared secret.
+ * @param offset
+ * the offset in the buffer.
+ * @return the number of bytes stored in the buffer.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @throws ShortBufferException
+ * if the specified buffer is too small for the shared secret.
+ * @since Android 1.0
+ */
+ public final int generateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
+ return spiImpl.engineGenerateSecret(sharedSecret, offset);
+ }
+
+ /**
+ * Generates the shared secret.
+ *
+ * @param algorithm
+ * the algorithm to for the {@code SecretKey}
+ * @return the shared secret as a {@code SecretKey} of the specified
+ * algorithm.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm for the secret key does not
+ * exists.
+ * @throws InvalidKeyException
+ * if a {@code SecretKey} with the specified algorithm cannot be
+ * created using the generated shared secret.
+ * @since Android 1.0
+ */
+ public final SecretKey generateSecret(String algorithm)
+ throws IllegalStateException, NoSuchAlgorithmException,
+ InvalidKeyException {
+ return spiImpl.engineGenerateSecret(algorithm);
+ }
+
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/KeyAgreementSpi.java b/crypto/src/main/java/javax/crypto/KeyAgreementSpi.java
new file mode 100644
index 0000000..fa9f377
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/KeyAgreementSpi.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>) definition for the
+ * {@code KeyAgreement} class.
+ *
+ * @since Android 1.0
+ */
+public abstract class KeyAgreementSpi {
+
+ /**
+ * Creates a new {@code KeyAgreementSpi} instance.
+ *
+ * @since Android 1.0
+ */
+ public KeyAgreementSpi() {
+ }
+
+ /**
+ * Does the next (or the last) phase of the key agreement, using the
+ * specified key.
+ *
+ * @param key
+ * the key received from the other party for this phase.
+ * @param lastPhase
+ * set to {@code true} if this is the last phase of this key
+ * agreement.
+ * @return the intermediate key from this phase or null if there is no
+ * intermediate key for this phase.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used in this key agreement or
+ * this phase,
+ * @throws IllegalStateException
+ * if this instance has not been initialized.
+ * @since Android 1.0
+ */
+ protected abstract Key engineDoPhase(Key key, boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException;
+
+ /**
+ * Generates the shared secret.
+ *
+ * @return the generated shared secret.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineGenerateSecret()
+ throws IllegalStateException;
+
+ /**
+ * Generates the shared secret and stores it into the buffer {@code
+ * sharedSecred} at {@code offset}.
+ *
+ * @param sharedSecret
+ * the buffer to store the shared secret.
+ * @param offset
+ * the offset in the buffer.
+ * @return the number of bytes stored in the buffer.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @throws ShortBufferException
+ * if the specified buffer is too small for the shared secret.
+ * @since Android 1.0
+ */
+ protected abstract int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException;
+
+ /**
+ * Generates the shared secret.
+ *
+ * @param algorithm
+ * the algorithm to for the {@code SecretKey}
+ * @return the shared secret as a {@code SecretKey} of the specified
+ * algorithm.
+ * @throws IllegalStateException
+ * if this key agreement is not complete.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm for the secret key does not
+ * exists.
+ * @throws InvalidKeyException
+ * if a {@code SecretKey} with the specified algorithm cannot be
+ * created using the generated shared secret.
+ * @since Android 1.0
+ */
+ protected abstract SecretKey engineGenerateSecret(String algorithm)
+ throws IllegalStateException, NoSuchAlgorithmException,
+ InvalidKeyException;
+
+ /**
+ * Initializes this {@code KeyAgreementSpi} with the specified key and the
+ * specified randomness source.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @param random
+ * the source for any randomness needed.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key, SecureRandom random)
+ throws InvalidKeyException;
+
+ /**
+ * Initializes this {@code KeyAgreementSpi} with the specified key,
+ * algorithm parameters and randomness source.
+ *
+ * @param key
+ * the key to initialize this key agreement.
+ * @param params
+ * the parameters for this key agreement algorithm.
+ * @param random
+ * the source for any randomness needed.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this key
+ * agreement.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are invalid for this key
+ * agreement algorithm.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException;
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/KeyGenerator.java b/crypto/src/main/java/javax/crypto/KeyGenerator.java
new file mode 100644
index 0000000..3243b39
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/KeyGenerator.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+
+/**
+ * This class provides the public API for generating symmetric cryptographic
+ * keys.
+ *
+ * @since Android 1.0
+ */
+public class KeyGenerator {
+
+ // Used to access common engine functionality
+ private static final Engine engine = new Engine("KeyGenerator"); //$NON-NLS-1$
+
+ // Store SecureRandom
+ private static final SecureRandom rndm = new SecureRandom();
+
+ // Store used provider
+ private final Provider provider;
+
+ // Store used spi implementation
+ private final KeyGeneratorSpi spiImpl;
+
+ // Store used algorithm name
+ private final String algorithm;
+
+ /**
+ * Creates a new {@code KeyGenerator} instance.
+ *
+ * @param keyGenSpi
+ * the implementation delegate.
+ * @param provider
+ * the implementation provider.
+ * @param algorithm
+ * the name of the algorithm.
+ * @since Android 1.0
+ */
+ protected KeyGenerator(KeyGeneratorSpi keyGenSpi, Provider provider,
+ String algorithm) {
+ this.provider = provider;
+ this.algorithm = algorithm;
+ this.spiImpl = keyGenSpi;
+ }
+
+ /**
+ * Returns the name of the key generation algorithm.
+ *
+ * @return the name of the key generation algorithm.
+ * @since Android 1.0
+ */
+ public final String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Returns the provider of this {@code KeyGenerator} instance.
+ *
+ * @return the provider of this {@code KeyGenerator} instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Creates a new {@code KeyGenerator} instance that provides the specified
+ * key algorithm,
+ *
+ * @param algorithm
+ * the name of the requested key algorithm
+ * @return the new {@code KeyGenerator} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not available by any provider.
+ * @throws NullPointerException
+ * if {@code algorithm} is {@code null}.
+ * @since Android 1.0
+ */
+ public static final KeyGenerator getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, null);
+ return new KeyGenerator((KeyGeneratorSpi) engine.spi, engine.provider,
+ algorithm);
+ }
+ }
+
+ /**
+ * Creates a new {@code KeyGenerator} instance that provides the specified
+ * key algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested key algorithm.
+ * @param provider
+ * the name of the provider that is providing the algorithm.
+ * @return the new {@code KeyGenerator} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws NoSuchProviderException
+ * if the specified provider is not available.
+ * @throws IllegalArgumentException
+ * if the specified provider is name is {@code null} or empty.
+ * @throws NullPointerException
+ * if the specified algorithm name is {@code null}.
+ * @since Android 1.0
+ */
+ public static final KeyGenerator getInstance(String algorithm,
+ String provider) throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if ((provider == null) || (provider.length() == 0)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.03")); //$NON-NLS-1$
+ }
+ Provider impProvider = Security.getProvider(provider);
+ if (impProvider == null) {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, impProvider);
+ }
+
+ /**
+ * Creates a new {@code KeyGenerator} instance that provides the specified
+ * key algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested key algorithm.
+ * @param provider
+ * the provider that is providing the algorithm
+ * @return the new {@code KeyGenerator} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws IllegalArgumentException
+ * if the specified provider is {@code null}.
+ * @throws NullPointerException
+ * if the specified algorithm name is {@code null}.
+ * @since Android 1.0
+ */
+ public static final KeyGenerator getInstance(String algorithm,
+ Provider provider) throws NoSuchAlgorithmException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, provider, null);
+ return new KeyGenerator((KeyGeneratorSpi) engine.spi, provider,
+ algorithm);
+ }
+ }
+
+ /**
+ * Generates a secret key.
+ *
+ * @return the generated secret key.
+ * @since Android 1.0
+ */
+ public final SecretKey generateKey() {
+ return spiImpl.engineGenerateKey();
+ }
+
+ /**
+ * Initializes this {@code KeyGenerator} instance with the specified
+ * algorithm parameters.
+ *
+ * @param params
+ * the parameters for the key generation algorithm.
+ * @throws InvalidAlgorithmParameterException
+ * if the parameters cannot be used to initialize this key
+ * generator algorithm.
+ * @since Android 1.0
+ */
+ public final void init(AlgorithmParameterSpec params)
+ throws InvalidAlgorithmParameterException {
+ spiImpl.engineInit(params, rndm);//new SecureRandom());
+ }
+
+ /**
+ * Initializes this {@code KeyGenerator} instance with the specified
+ * algorithm parameters and randomness source.
+ *
+ * @param params
+ * the parameters for the key generation algorithm.
+ * @param random
+ * the randomness source for any random bytes.
+ * @throws InvalidAlgorithmParameterException
+ * if the parameters cannot be uses to initialize this key
+ * generator algorithm.
+ * @since Android 1.0
+ */
+ public final void init(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ spiImpl.engineInit(params, random);
+ }
+
+ /**
+ * Initializes this {@code KeyGenerator} instance for the specified key size
+ * (in bits).
+ *
+ * @param keysize
+ * the size of the key (in bits).
+ * @since Android 1.0
+ */
+ public final void init(int keysize) {
+ spiImpl.engineInit(keysize, rndm);//new SecureRandom());
+ }
+
+ /**
+ * Initializes this {@code KeyGenerator} instance for the specified key size
+ * (in bits) using the specified randomness source.
+ *
+ * @param keysize
+ * the size of the key (in bits).
+ * @param random
+ * the randomness source for any random bytes.
+ * @since Android 1.0
+ */
+ public final void init(int keysize, SecureRandom random) {
+ spiImpl.engineInit(keysize, random);
+ }
+
+ /**
+ * Initializes this {@code KeyGenerator} with the specified randomness
+ * source.
+ *
+ * @param random
+ * the randomness source for any random bytes.
+ * @since Android 1.0
+ */
+ public final void init(SecureRandom random) {
+ spiImpl.engineInit(random);
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/KeyGeneratorSpi.java b/crypto/src/main/java/javax/crypto/KeyGeneratorSpi.java
new file mode 100644
index 0000000..165db69
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/KeyGeneratorSpi.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>) definition for the
+ * {@code KeyGenerator} class.
+ *
+ * @see KeyGenerator
+ * @since Android 1.0
+ */
+public abstract class KeyGeneratorSpi {
+
+ /**
+ * Creates a new {@code KeyGeneratorSpi} instance.
+ *
+ * @since Android 1.0
+ */
+ public KeyGeneratorSpi() {
+ }
+
+ /**
+ * Generates a secret key.
+ *
+ * @return the generated secret key.
+ * @since Android 1.0
+ */
+ protected abstract SecretKey engineGenerateKey();
+
+ /**
+ * Initializes this {@code KeyGeneratorSpi} instance with the specified
+ * algorithm parameters and randomness source.
+ *
+ * @param params
+ * the parameters for the key generation algorithm.
+ * @param random
+ * the randomness source for any random bytes.
+ * @throws InvalidAlgorithmParameterException
+ * if the parameters cannot be uses to initialize this key
+ * generator algorithm.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidAlgorithmParameterException;
+
+ /**
+ * Initializes this {@code KeyGenerator} instance for the specified key
+ * size (in bits) using the specified randomness source.
+ *
+ * @param keysize
+ * the size of the key (in bits).
+ * @param random
+ * the randomness source for any random bytes.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(int keysize, SecureRandom random);
+
+ /**
+ * Initializes this {@code KeyGenerator} with the specified randomness
+ * source.
+ *
+ * @param random
+ * the randomness source for any random bytes.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(SecureRandom random);
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/Mac.java b/crypto/src/main/java/javax/crypto/Mac.java
new file mode 100644
index 0000000..95f4539
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/Mac.java
@@ -0,0 +1,452 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+
+/**
+ * This class provides the public API for <i>Message Authentication Code</i>
+ * (MAC) algorithms.
+ *
+ * @since Android 1.0
+ */
+public class Mac implements Cloneable {
+
+ //Used to access common engine functionality
+ private static final Engine engine = new Engine("Mac"); //$NON-NLS-1$
+
+ // Store used provider
+ private final Provider provider;
+
+ // Store used spi implementation
+ private final MacSpi spiImpl;
+
+ // Store used algorithm name
+ private final String algorithm;
+
+ // Store Mac state (initialized or not initialized)
+ private boolean isInitMac;
+
+ /**
+ * Creates a new {@code Mac} instance.
+ *
+ * @param macSpi
+ * the implementation delegate.
+ * @param provider
+ * the implementation provider.
+ * @param algorithm
+ * the name of the MAC algorithm.
+ * @since Android 1.0
+ */
+ protected Mac(MacSpi macSpi, Provider provider, String algorithm) {
+ this.provider = provider;
+ this.algorithm = algorithm;
+ this.spiImpl = macSpi;
+ this.isInitMac = false;
+ }
+
+ /**
+ * Returns the name of the MAC algorithm.
+ *
+ * @return the name of the MAC algorithm.
+ * @since Android 1.0
+ */
+ public final String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Returns the provider of this {@code Mac} instance.
+ *
+ * @return the provider of this {@code Mac} instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Creates a new {@code Mac} instance that provides the specified MAC
+ * algorithm.
+ *
+ * @param algorithm
+ * the name of the requested MAC algorithm.
+ * @return the new {@code Mac} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not available by any provider.
+ * @throws NullPointerException
+ * if {@code algorithm} is {@code null}.
+ * @since Android 1.0
+ */
+ public static final Mac getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, null);
+ return new Mac((MacSpi) engine.spi, engine.provider, algorithm);
+ }
+ }
+
+ /**
+ * Creates a new {@code Mac} instance that provides the specified MAC
+ * algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested MAC algorithm.
+ * @param provider
+ * the name of the provider that is providing the algorithm.
+ * @return the new {@code Mac} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws NoSuchProviderException
+ * if the specified provider is not available.
+ * @throws IllegalArgumentException
+ * if the specified provider name is {@code null} or empty.
+ * @throws NullPointerException
+ * if {@code algorithm} is {@code null}
+ * @since Android 1.0.
+ */
+ public static final Mac getInstance(String algorithm, String provider)
+ throws NoSuchAlgorithmException, NoSuchProviderException {
+ if ((provider == null) || (provider.length() == 0)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.03")); //$NON-NLS-1$
+ }
+ Provider impProvider = Security.getProvider(provider);
+ if (impProvider == null) {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, impProvider);
+ }
+
+ /**
+ * Creates a new {@code Mac} instance that provides the specified MAC
+ * algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the requested MAC algorithm.
+ * @param provider
+ * the provider that is providing the algorithm.
+ * @return the new {@code Mac} instance.
+ * @throws NoSuchAlgorithmException
+ * if the specified algorithm is not provided by the specified
+ * provider.
+ * @throws IllegalArgumentException
+ * if {@code provider} is {@code null}.
+ * @throws NullPointerException
+ * if {@code algorithm} is {@code null}.
+ * @since Android 1.0
+ */
+ public static final Mac getInstance(String algorithm, Provider provider)
+ throws NoSuchAlgorithmException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, provider, null);
+ return new Mac((MacSpi) engine.spi, provider, algorithm);
+ }
+ }
+
+ /**
+ * Returns the length of this MAC (in bytes).
+ *
+ * @return the length of this MAC (in bytes).
+ */
+ public final int getMacLength() {
+ return spiImpl.engineGetMacLength();
+ }
+
+ /**
+ * Initializes this {@code Mac} instance with the specified key and
+ * algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this algorithm.
+ * @param params
+ * the parameters for this algorithm.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this
+ * algorithm, or it is null.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters cannot be used to initialize this
+ * algorithm.
+ * @since Android 1.0
+ */
+ public final void init(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (key == null) {
+ throw new InvalidKeyException(Messages.getString("crypto.05")); //$NON-NLS-1$
+ }
+ spiImpl.engineInit(key, params);
+ isInitMac = true;
+ }
+
+ /**
+ * Initializes this {@code Mac} instance with the specified key.
+ *
+ * @param key
+ * the key to initialize this algorithm.
+ * @throws InvalidKeyException
+ * if initialization fails because the provided key is {@code
+ * null}.
+ * @throws RuntimeException
+ * if the specified key cannot be used to initialize this
+ * algorithm.
+ * @since Android 1.0
+ */
+ public final void init(Key key) throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException(Messages.getString("crypto.05")); //$NON-NLS-1$
+ }
+ try {
+ spiImpl.engineInit(key, null);
+ isInitMac = true;
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Updates this {@code Mac} instance with the specified byte.
+ *
+ * @param input
+ * the byte
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final void update(byte input) throws IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ spiImpl.engineUpdate(input);
+ }
+
+ /**
+ * Updates this {@code Mac} instance with the data from the specified buffer
+ * {@code input} from the specified {@code offset} and length {@code len}.
+ *
+ * @param input
+ * the buffer.
+ * @param offset
+ * the offset in the buffer.
+ * @param len
+ * the length of the data in the buffer.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @throws IllegalArgumentException
+ * if {@code offset} and {@code len} do not specified a valid
+ * chunk in {@code input} buffer.
+ * @since Android 1.0
+ */
+ public final void update(byte[] input, int offset, int len)
+ throws IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ if (input == null) {
+ return;
+ }
+ if ((offset < 0) || (len < 0) || ((offset + len) > input.length)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.06")); //$NON-NLS-1$
+ }
+ spiImpl.engineUpdate(input, offset, len);
+ }
+
+ /**
+ * Copies the buffer provided as input for further processing.
+ *
+ * @param input
+ * the buffer.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final void update(byte[] input) throws IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ if (input != null) {
+ spiImpl.engineUpdate(input, 0, input.length);
+ }
+ }
+
+ /**
+ * Updates this {@code Mac} instance with the data from the specified
+ * buffer, starting at {@link ByteBuffer#position()}, including the next
+ * {@link ByteBuffer#remaining()} bytes.
+ *
+ * @param input
+ * the buffer.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final void update(ByteBuffer input) {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ if (input != null) {
+ spiImpl.engineUpdate(input);
+ } else {
+ throw new IllegalArgumentException(Messages.getString("crypto.07")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Computes the digest of this MAC based on the data previously specified in
+ * {@link #update} calls.
+ * <p>
+ * This {@code Mac} instance is reverted to its initial state and can be
+ * used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @return the generated digest.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final byte[] doFinal() throws IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ return spiImpl.engineDoFinal();
+ }
+
+ /**
+ * Computes the digest of this MAC based on the data previously specified in
+ * {@link #update} calls and stores the digest in the specified {@code
+ * output} buffer at offset {@code outOffset}.
+ * <p>
+ * This {@code Mac} instance is reverted to its initial state and can be
+ * used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @param output
+ * the output buffer
+ * @param outOffset
+ * the offset in the output buffer
+ * @throws ShortBufferException
+ * if the specified output buffer is either too small for the
+ * digest to be stored, the specified output buffer is {@code
+ * null}, or the specified offset is negative or past the length
+ * of the output buffer.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final void doFinal(byte[] output, int outOffset)
+ throws ShortBufferException, IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.01"));
+ }
+ if (output == null) {
+ throw new ShortBufferException(Messages.getString("crypto.08")); //$NON-NLS-1$
+ }
+ if ((outOffset < 0) || (outOffset >= output.length)) {
+ throw new ShortBufferException(Messages.getString("crypto.09", //$NON-NLS-1$
+ Integer.toString(outOffset)));
+ }
+ int t = spiImpl.engineGetMacLength();
+ if (t > (output.length - outOffset)) {
+ throw new ShortBufferException(
+ Messages.getString("crypto.0A", //$NON-NLS-1$
+ Integer.toString(t)));
+ }
+ byte[] result = spiImpl.engineDoFinal();
+ System.arraycopy(result, 0, output, outOffset, result.length);
+
+ }
+
+ /**
+ * Computes the digest of this MAC based on the data previously specified on
+ * {@link #update} calls and on the final bytes specified by {@code input}
+ * (or based on those bytes only).
+ * <p>
+ * This {@code Mac} instance is reverted to its initial state and can be
+ * used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @param input
+ * the final bytes.
+ * @return the generated digest.
+ * @throws IllegalStateException
+ * if this MAC is not initialized.
+ * @since Android 1.0
+ */
+ public final byte[] doFinal(byte[] input) throws IllegalStateException {
+ if (!isInitMac) {
+ throw new IllegalStateException(Messages.getString("crypto.0B")); //$NON-NLS-1$
+ }
+ if (input != null) {
+ spiImpl.engineUpdate(input, 0, input.length);
+ }
+ return spiImpl.engineDoFinal();
+ }
+
+ /**
+ * Resets this {@code Mac} instance to its initial state.
+ * <p>
+ * This {@code Mac} instance is reverted to its initial state and can be
+ * used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+ public final void reset() {
+ spiImpl.engineReset();
+ }
+
+ /**
+ * Clones this {@code Mac} instance and the underlying implementation.
+ *
+ * @return the cloned instance.
+ * @throws CloneNotSupportedException
+ * if the underlying implementation does not support cloning.
+ * @since Android 1.0
+ */
+ @Override
+ public final Object clone() throws CloneNotSupportedException {
+ MacSpi newSpiImpl = (MacSpi)spiImpl.clone();
+ Mac mac = new Mac(newSpiImpl, this.provider, this.algorithm);
+ mac.isInitMac = this.isInitMac;
+ return mac;
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/MacSpi.java b/crypto/src/main/java/javax/crypto/MacSpi.java
new file mode 100644
index 0000000..4756184
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/MacSpi.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.Key;
+import java.security.InvalidKeyException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.nio.ByteBuffer;
+
+/**
+ * The <i>Service-Provider Interface</i> (<b>SPI</b>) definition for the {@code
+ * Mac} class.
+ *
+ * @see Mac
+ * @since Android 1.0
+ */
+public abstract class MacSpi {
+
+ /**
+ * Creates a new {@code MacSpi} instance.
+ *
+ * @since Android 1.0
+ */
+ public MacSpi() {
+ }
+
+ /**
+ * Returns the length of this MAC (in bytes).
+ *
+ * @return the length of this MAC (in bytes).
+ * @since Android 1.0
+ */
+ protected abstract int engineGetMacLength();
+
+ /**
+ * Initializes this {@code MacSpi} instance with the specified key and
+ * algorithm parameters.
+ *
+ * @param key
+ * the key to initialize this algorithm.
+ * @param params
+ * the parameters for this algorithm.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this
+ * algorithm, or it is {@code null}.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters cannot be used to initialize this
+ * algorithm.
+ * @since Android 1.0
+ */
+ protected abstract void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Updates this {@code MacSpi} instance with the specified byte.
+ *
+ * @param input
+ * the byte.
+ * @since Android 1.0
+ */
+ protected abstract void engineUpdate(byte input);
+
+ /**
+ * Updates this {@code MacSpi} instance with the data from the specified
+ * buffer {@code input} from the specified {@code offset} and length {@code
+ * len}.
+ *
+ * @param input
+ * the buffer.
+ * @param offset
+ * the offset in the buffer.
+ * @param len
+ * the length of the data in the buffer.
+ * @since Android 1.0
+ */
+ protected abstract void engineUpdate(byte[] input, int offset, int len);
+
+ /**
+ * Updates this {@code MacSpi} instance with the data from the specified
+ * buffer, starting at {@link ByteBuffer#position()}, including the next
+ * {@link ByteBuffer#remaining()} bytes.
+ *
+ * @param input
+ * the buffer.
+ * @since Android 1.0
+ */
+ protected void engineUpdate(ByteBuffer input) {
+ if (!input.hasRemaining()) {
+ return;
+ }
+ byte[] bInput;
+ if (input.hasArray()) {
+ bInput = input.array();
+ int offset = input.arrayOffset();
+ int position = input.position();
+ int limit = input.limit();
+ engineUpdate(bInput, offset + position, limit - position);
+ input.position(limit);
+ } else {
+ bInput = new byte[input.limit() - input.position()];
+ input.get(bInput);
+ engineUpdate(bInput, 0, bInput.length);
+ }
+ }
+
+ /**
+ * Computes the digest of this MAC based on the data previously specified in
+ * {@link #engineUpdate} calls.
+ * <p>
+ * This {@code MacSpi} instance is reverted to its initial state and
+ * can be used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @return the generated digest.
+ * @since Android 1.0
+ */
+ protected abstract byte[] engineDoFinal();
+
+ /**
+ * Resets this {@code MacSpi} instance to its initial state.
+ * <p>
+ * This {@code MacSpi} instance is reverted to its initial state and can be
+ * used to start the next MAC computation with the same parameters or
+ * initialized with different parameters.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+ protected abstract void engineReset();
+
+ /**
+ * Clones this {@code MacSpi} instance.
+ *
+ * @return the cloned instance.
+ * @throws CloneNotSupportedException
+ * if cloning is not supported.
+ * @since Android 1.0
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/NoSuchPaddingException.java b/crypto/src/main/java/javax/crypto/NoSuchPaddingException.java
new file mode 100644
index 0000000..4afb8ab
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/NoSuchPaddingException.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * The exception that is thrown when the requested padding mechanism is not
+ * supported.
+ *
+ * @since Android 1.0
+ */
+public class NoSuchPaddingException extends GeneralSecurityException {
+
+ /**
+ * @serial
+ */
+ private static final long serialVersionUID = -4572885201200175466L;
+
+ /**
+ * Creates a new {@code NoSuchPaddingException} with the specified
+ * message.
+ *
+ * @param msg
+ * the message.
+ * @since Android 1.0
+ */
+ public NoSuchPaddingException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new {@code NoSuchPaddingException}.
+ *
+ * @since Android 1.0
+ */
+ public NoSuchPaddingException() {
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/NullCipher.java b/crypto/src/main/java/javax/crypto/NullCipher.java
new file mode 100644
index 0000000..49f96c2
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/NullCipher.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Boris V. Kuznetsov
+* @version $Revision$
+*/
+
+package javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.SecureRandom;
+
+import org.apache.harmony.crypto.internal.NullCipherSpi;
+
+
+/**
+ * This class provides an identity cipher that does not transform the input data
+ * in any way. The <i>encrypted</i> data is identical to the <i>plain text</i>.
+ *
+ * @since Android 1.0
+ */
+public class NullCipher extends Cipher {
+
+ /**
+ * Creates a new {@code NullCipher} instance.
+ */
+ public NullCipher() {
+ super(new NullCipherSpi(), null, null);
+ try {
+ this.init(Cipher.ENCRYPT_MODE, (Key)null, (SecureRandom)null);
+ } catch (InvalidKeyException e) {
+ }
+ }
+
+}
diff --git a/crypto/src/main/java/javax/crypto/SealedObject.java b/crypto/src/main/java/javax/crypto/SealedObject.java
new file mode 100644
index 0000000..4e71453
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/SealedObject.java
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * A {@code SealedObject} is a wrapper around a {@code serializable} object
+ * instance and encrypts it using a cryptographic cipher.
+ * <p>
+ * Since a {@code SealedObject} instance is a serializable object itself it can
+ * either be stored or transmitted over an insecure channel.
+ * </p>
+ * The wrapped object can later be decrypted (unsealed) using the corresponding
+ * key and then be deserialized to retrieve the original object.The sealed
+ * object itself keeps track of the cipher and corresponding parameters.
+ *
+ * @since Android 1.0
+ */
+public class SealedObject implements Serializable {
+
+ // the value of this field was derived by using serialver utility
+ /**
+ * @com.intel.drl.spec_ref
+ */
+ private static final long serialVersionUID = 4482838265551344752L;
+
+ /**
+ * The {@link AlgorithmParameters} in encoded format.
+ */
+ protected byte[] encodedParams;
+ private byte[] encryptedContent;
+ private String sealAlg;
+ private String paramsAlg;
+
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ encodedParams = (byte []) s.readUnshared();
+ encryptedContent = (byte []) s.readUnshared();
+ sealAlg = (String) s.readUnshared();
+ paramsAlg = (String) s.readUnshared();
+ }
+
+ /**
+ * Creates a new {@code SealedObject} instance wrapping the specified object
+ * and sealing it using the specified cipher.
+ * <p>
+ * The cipher must be fully initialized.
+ * </p>
+ *
+ * @param object
+ * the object to seal, can be {@code null}.
+ * @param c
+ * the cipher to encrypt the object.
+ * @throws IOException
+ * if the serialization fails.
+ * @throws IllegalBlockSizeException
+ * if the specified cipher is a block cipher and the length of
+ * the serialized data is not a multiple of the ciphers block
+ * size.
+ * @throws NullPointerException
+ * if the cipher is {@code null}.
+ * @since Android 1.0
+ */
+ public SealedObject(Serializable object, Cipher c)
+ throws IOException, IllegalBlockSizeException {
+ if (c == null) {
+ throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$
+ }
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(object);
+ oos.flush();
+ AlgorithmParameters ap = c.getParameters();
+ this.encodedParams = (ap == null) ? null : ap.getEncoded();
+ this.paramsAlg = (ap == null) ? null : ap.getAlgorithm();
+ this.sealAlg = c.getAlgorithm();
+ this.encryptedContent = c.doFinal(bos.toByteArray());
+ } catch (BadPaddingException e) {
+ // should be never thrown because the cipher
+ // should be initialized for encryption
+ throw new IOException(e.toString());
+ }
+ }
+
+ /**
+ * Creates a new {@code SealedObject} instance by copying the data from
+ * the specified object.
+ *
+ * @param so
+ * the object to copy.
+ * @since Android 1.0
+ */
+ protected SealedObject(SealedObject so) {
+ if (so == null) {
+ throw new NullPointerException(Messages.getString("crypto.14")); //$NON-NLS-1$
+ }
+ this.encryptedContent = so.encryptedContent;
+ this.encodedParams = so.encodedParams;
+ this.sealAlg = so.sealAlg;
+ this.paramsAlg = so.paramsAlg;
+ }
+
+ /**
+ * Returns the algorithm this object was sealed with.
+ *
+ * @return the algorithm this object was sealed with.
+ * @since Android 1.0
+ */
+ public final String getAlgorithm() {
+ return sealAlg;
+ }
+
+ /**
+ * Returns the wrapped object, decrypting it using the specified key.
+ *
+ * @param key
+ * the key to decrypt the data with.
+ * @return the encapsulated object.
+ * @throws IOException
+ * if deserialization fails.
+ * @throws ClassNotFoundException
+ * if deserialization fails.
+ * @throws NoSuchAlgorithmException
+ * if the algorithm to decrypt the data is not available.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to decrypt the data.
+ * @since Android 1.0
+ */
+ public final Object getObject(Key key)
+ throws IOException, ClassNotFoundException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ // BEGIN android-added
+ if (key == null) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.05"));
+ }
+ // END android-added
+ try {
+ Cipher cipher = Cipher.getInstance(sealAlg);
+ if ((paramsAlg != null) && (paramsAlg.length() != 0)) {
+ AlgorithmParameters params =
+ AlgorithmParameters.getInstance(paramsAlg);
+ params.init(encodedParams);
+ cipher.init(Cipher.DECRYPT_MODE, key, params);
+ } else {
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ }
+ byte[] serialized = cipher.doFinal(encryptedContent);
+ ObjectInputStream ois =
+ new ObjectInputStream(
+ new ByteArrayInputStream(serialized));
+ return ois.readObject();
+ } catch (NoSuchPaddingException e) {
+ // should not be thrown because cipher text was made
+ // with existing padding
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (InvalidAlgorithmParameterException e) {
+ // should not be thrown because cipher text was made
+ // with correct algorithm parameters
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (IllegalBlockSizeException e) {
+ // should not be thrown because the cipher text
+ // was correctly made
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (BadPaddingException e) {
+ // should not be thrown because the cipher text
+ // was correctly made
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (IllegalStateException e) {
+ // should never be thrown because cipher is initialized
+ throw new NoSuchAlgorithmException(e.toString());
+ }
+ }
+
+ /**
+ * Returns the wrapped object, decrypting it using the specified
+ * cipher.
+ *
+ * @param c
+ * the cipher to decrypt the data.
+ * @return the encapsulated object.
+ * @throws IOException
+ * if deserialization fails.
+ * @throws ClassNotFoundException
+ * if deserialization fails.
+ * @throws IllegalBlockSizeException
+ * if the specified cipher is a block cipher and the length of
+ * the serialized data is not a multiple of the ciphers block
+ * size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @since Android 1.0
+ */
+ public final Object getObject(Cipher c)
+ throws IOException, ClassNotFoundException,
+ IllegalBlockSizeException, BadPaddingException {
+ if (c == null) {
+ throw new NullPointerException(Messages.getString("crypto.13")); //$NON-NLS-1$
+ }
+ byte[] serialized = c.doFinal(encryptedContent);
+ ObjectInputStream ois =
+ new ObjectInputStream(
+ new ByteArrayInputStream(serialized));
+ return ois.readObject();
+ }
+
+ /**
+ * Returns the wrapped object, decrypting it using the specified key. The
+ * specified provider is used to retrieve the cipher algorithm.
+ *
+ * @param key
+ * the key to decrypt the data.
+ * @param provider
+ * the name of the provider that provides the cipher algorithm.
+ * @return the encapsulated object.
+ * @throws IOException
+ * if deserialization fails.
+ * @throws ClassNotFoundException
+ * if deserialization fails.
+ * @throws NoSuchAlgorithmException
+ * if the algorithm used to decrypt the data is not available.
+ * @throws NoSuchProviderException
+ * if the specified provider is not available.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to decrypt the data.
+ * @since Android 1.0
+ */
+ public final Object getObject(Key key, String provider)
+ throws IOException, ClassNotFoundException,
+ NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidKeyException {
+ if ((provider == null) || (provider.length() == 0)) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.15")); //$NON-NLS-1$
+ }
+ try {
+ Cipher cipher = Cipher.getInstance(sealAlg, provider);
+ if ((paramsAlg != null) && (paramsAlg.length() != 0)) {
+ AlgorithmParameters params =
+ AlgorithmParameters.getInstance(paramsAlg);
+ params.init(encodedParams);
+ cipher.init(Cipher.DECRYPT_MODE, key, params);
+ } else {
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ }
+ byte[] serialized = cipher.doFinal(encryptedContent);
+ ObjectInputStream ois =
+ new ObjectInputStream(
+ new ByteArrayInputStream(serialized));
+ return ois.readObject();
+ } catch (NoSuchPaddingException e) {
+ // should not be thrown because cipher text was made
+ // with existing padding
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (InvalidAlgorithmParameterException e) {
+ // should not be thrown because cipher text was made
+ // with correct algorithm parameters
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (IllegalBlockSizeException e) {
+ // should not be thrown because the cipher text
+ // was correctly made
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (BadPaddingException e) {
+ // should not be thrown because the cipher text
+ // was correctly made
+ throw new NoSuchAlgorithmException(e.toString());
+ } catch (IllegalStateException e) {
+ // should never be thrown because cipher is initialized
+ throw new NoSuchAlgorithmException(e.toString());
+ }
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/SecretKey.java b/crypto/src/main/java/javax/crypto/SecretKey.java
new file mode 100644
index 0000000..102f888
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/SecretKey.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.Key;
+
+/**
+ * A cryptographic secret (symmetric) key.
+ * <p>
+ * This interface is a <i>marker interface</i> to group secret keys and to
+ * provide type safety for.
+ * </p>
+ * Implementations of this interface have to overwrite the
+ * {@link Object#equals(Object) equals} and {@link Object#hashCode() hashCode}
+ * from {@link java.lang.Object} so comparison is done using the actual key data
+ * and not the object reference.
+ *
+ * @since Android 1.0
+ */
+public interface SecretKey extends Key {
+
+ /**
+ * The serialization version identifier.
+ *
+ * @serial
+ * @since Android 1.0
+ */
+ public static final long serialVersionUID = -4795878709595146952L;
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/SecretKeyFactory.java b/crypto/src/main/java/javax/crypto/SecretKeyFactory.java
new file mode 100644
index 0000000..a420dab
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/SecretKeyFactory.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+import org.apache.harmony.security.fortress.Engine;
+
+
+/**
+ * The public API for {@code SecretKeyFactory} implementations.
+ * <p>
+ * Secret key factories provide the following functionality:
+ * <ul>
+ * <li>convert {@link SecretKey} objects to and from {@link KeySpec} objects</li>
+ * <li>translate {@link SecretKey} objects from one provider implementation to
+ * another</li>
+ * </ul>
+ * Which key specifications are supported by the {@link #generateSecret} and
+ * {@link #getKeySpec} is provider dependent.
+ * </p>
+ *
+ * @since Android 1.0
+ */
+public class SecretKeyFactory {
+
+ // Used to access common engine functionality
+ private static final Engine engine = new Engine("SecretKeyFactory"); //$NON-NLS-1$
+
+ // Store used provider
+ private final Provider provider;
+
+ // Store used spi implementation
+ private final SecretKeyFactorySpi spiImpl;
+
+ // Store used algorithm name
+ private final String algorithm;
+
+ /**
+ * Creates a new {@code SecretKeyFactory}
+ *
+ * @param keyFacSpi
+ * the SPI delegate.
+ * @param provider
+ * the provider providing this key factory.
+ * @param algorithm
+ * the algorithm name for the secret key.
+ * @since Android 1.0
+ */
+ protected SecretKeyFactory(SecretKeyFactorySpi keyFacSpi,
+ Provider provider, String algorithm) {
+ this.provider = provider;
+ this.algorithm = algorithm;
+ this.spiImpl = keyFacSpi;
+ }
+
+ /**
+ * Returns the name of the secret key algorithm.
+ *
+ * @return the name of the secret key algorithm.
+ * @since Android 1.0
+ */
+ public final String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Returns the provider for this {@code SecretKeyFactory} instance.
+ *
+ * @return the provider for this {@code SecretKeyFactory} instance.
+ * @since Android 1.0
+ */
+ public final Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * Creates a new {@code SecretKeyFactory} instance for the specified key
+ * algorithm.
+ *
+ * @param algorithm
+ * the name of the key algorithm.
+ * @return a secret key factory for the specified key algorithm.
+ * @throws NoSuchAlgorithmException
+ * if no installed provider can provide the requested algorithm.
+ * @throws NullPointerException
+ * if the specified algorithm is {@code null}.
+ * @since Android 1.0
+ */
+ public static final SecretKeyFactory getInstance(String algorithm)
+ throws NoSuchAlgorithmException {
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, null);
+ return new SecretKeyFactory((SecretKeyFactorySpi) engine.spi,
+ engine.provider, algorithm);
+ }
+ }
+
+ /**
+ * Creates a new {@code SecretKeyFactory} instance for the specified key
+ * algorithm from the specified {@code provider}.
+ *
+ * @param algorithm
+ * the name of the key algorithm.
+ * @param provider
+ * the name of the provider that provides the requested
+ * algorithm.
+ * @return a secret key factory for the specified key algorithm from the
+ * specified provider.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider cannot provide the requested
+ * algorithm.
+ * @throws NoSuchProviderException
+ * if the specified provider does not exist.
+ * @throws IllegalArgumentException
+ * if the specified provider name is {@code null} or empty.
+ * @since Android 1.0
+ */
+ public static final SecretKeyFactory getInstance(String algorithm,
+ String provider) throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if ((provider == null) || (provider.length() == 0)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.03")); //$NON-NLS-1$
+ }
+ Provider impProvider = Security.getProvider(provider);
+ if (impProvider == null) {
+ throw new NoSuchProviderException(provider);
+ }
+ return getInstance(algorithm, impProvider);
+ }
+
+ /**
+ * Creates a new {@code SecretKeyFactory} instance for the specified key
+ * algorithm from the specified provider.
+ *
+ * @param algorithm
+ * the name of the key algorithm.
+ * @param provider
+ * the provider that provides the requested algorithm.
+ * @return a secret key factory for the specified key algorithm from the
+ * specified provider.
+ * @throws NoSuchAlgorithmException
+ * if the specified provider cannot provider the requested
+ * algorithm.
+ * @throws IllegalArgumentException
+ * if the specified provider is {@code null}.
+ * @throws NullPointerException
+ * is the specified algorithm name is {@code null}.
+ * @since Android 1.0
+ */
+ public static final SecretKeyFactory getInstance(String algorithm,
+ Provider provider) throws NoSuchAlgorithmException {
+ if (provider == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.04")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new NullPointerException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ synchronized (engine) {
+ engine.getInstance(algorithm, provider, null);
+ return new SecretKeyFactory((SecretKeyFactorySpi) engine.spi, provider,
+ algorithm);
+ }
+ }
+
+ /**
+ * Generate a secret key from the specified key specification.
+ *
+ * @param keySpec
+ * the key specification.
+ * @return a secret key.
+ * @throws InvalidKeySpecException
+ * if the specified key specification cannot be used to generate
+ * a secret key.
+ * @since Android 1.0
+ */
+ public final SecretKey generateSecret(KeySpec keySpec)
+ throws InvalidKeySpecException {
+ return spiImpl.engineGenerateSecret(keySpec);
+ }
+
+ /**
+ * Returns the key specification of the specified secret key.
+ *
+ * @param key
+ * the secret key to get the specification from.
+ * @param keySpec
+ * the target key specification class.
+ * @return an instance of the specified key specification class.
+ * @throws InvalidKeySpecException
+ * if the specified secret key cannot be transformed into the
+ * requested key specification.
+ * @since Android 1.0
+ */
+ @SuppressWarnings("unchecked")
+ public final KeySpec getKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException {
+ return spiImpl.engineGetKeySpec(key, keySpec);
+ }
+
+ /**
+ * Translates the specified secret key into an instance of the corresponding
+ * key from the provider of this key factory.
+ *
+ * @param key
+ * the secret key to translate.
+ * @return the corresponding translated key.
+ * @throws InvalidKeyException
+ * if the specified key cannot be translated using this key
+ * factory.
+ * @since Android 1.0
+ */
+ public final SecretKey translateKey(SecretKey key)
+ throws InvalidKeyException {
+ return spiImpl.engineTranslateKey(key);
+
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/SecretKeyFactorySpi.java b/crypto/src/main/java/javax/crypto/SecretKeyFactorySpi.java
new file mode 100644
index 0000000..f834dbb
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/SecretKeyFactorySpi.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+/**
+ * The <i>Service Provider Interface</i> (<b>SPI</b>) definition for the {@code
+ * SecretKeyFactory} class.
+ *
+ * @since Android 1.0
+ */
+public abstract class SecretKeyFactorySpi {
+
+ /**
+ * Creates a new {@code SecretKeyFactorySpi} instance.
+ * @since Android 1.0
+ */
+ public SecretKeyFactorySpi() {
+ }
+
+ /**
+ * Generate a secret key from the specified key specification.
+ *
+ * @param keySpec
+ * the key specification.
+ * @return a secret key.
+ * @throws InvalidKeySpecException
+ * if the specified key specification cannot be used to generate
+ * a secret key.
+ * @since Android 1.0
+ */
+ protected abstract SecretKey engineGenerateSecret(KeySpec keySpec)
+ throws InvalidKeySpecException;
+
+ /**
+ * Returns the key specification of the specified secret key.
+ *
+ * @param key
+ * the secret key to get the specification from.
+ * @param keySpec
+ * the target key specification class.
+ * @return an instance of the specified key specification class.
+ * @throws InvalidKeySpecException
+ * if the specified secret key cannot be transformed into the
+ * requested key specification.
+ * @since Android 1.0
+ */
+ @SuppressWarnings("unchecked")
+ protected abstract KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException;
+
+ /**
+ * Translates the specified secret key into an instance of the corresponding
+ * key from the provider of this key factory.
+ *
+ * @param key
+ * the secret key to translate.
+ * @return the corresponding translated key.
+ * @throws InvalidKeyException
+ * if the specified key cannot be translated using this key
+ * factory.
+ * @since Android 1.0
+ */
+ protected abstract SecretKey engineTranslateKey(SecretKey key)
+ throws InvalidKeyException;
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/ShortBufferException.java b/crypto/src/main/java/javax/crypto/ShortBufferException.java
new file mode 100644
index 0000000..593a31e
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/ShortBufferException.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package javax.crypto;
+
+import java.security.GeneralSecurityException;
+
+/**
+ * The exception that is thrown when the result of an operation is attempted to
+ * store in a user provided buffer that is too small.
+ *
+ * @since Android 1.0
+ */
+public class ShortBufferException extends GeneralSecurityException {
+
+ /**
+ * @serial
+ */
+ private static final long serialVersionUID = 8427718640832943747L;
+
+ /**
+ * Creates a new instance of {@code ShortBufferException} with the
+ * specified message
+ *
+ * @param msg
+ * the exception message.
+ * @since Android 1.0
+ */
+ public ShortBufferException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Creates a new instance of {@code ShortBufferException}.
+ *
+ * @since Android 1.0
+ */
+ public ShortBufferException() {
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/interfaces/DHKey.java b/crypto/src/main/java/javax/crypto/interfaces/DHKey.java
new file mode 100644
index 0000000..f686844
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/interfaces/DHKey.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.interfaces;
+
+import javax.crypto.spec.DHParameterSpec;
+
+/**
+ * The interface for a Diffie-Hellman key.
+ *
+ * @since Android 1.0
+ */
+public interface DHKey {
+
+ /**
+ * Returns the parameters for this key.
+ *
+ * @return the parameters for this key.
+ */
+ public DHParameterSpec getParams();
+}
+
diff --git a/crypto/src/main/java/javax/crypto/interfaces/DHPrivateKey.java b/crypto/src/main/java/javax/crypto/interfaces/DHPrivateKey.java
new file mode 100644
index 0000000..d39268b
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/interfaces/DHPrivateKey.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.interfaces;
+
+import java.math.BigInteger;
+import java.security.PrivateKey;
+
+/**
+ * The interface for a private key in the Diffie-Hellman key exchange protocol.
+ *
+ * @since Android 1.0
+ */
+public interface DHPrivateKey extends DHKey, PrivateKey {
+
+ /**
+ * The serialization version identifier.
+ */
+ public static final long serialVersionUID = 2211791113380396553L;
+
+ /**
+ * Returns this key's private value x.
+ * @return this key's private value x.
+ */
+ public BigInteger getX();
+
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/interfaces/DHPublicKey.java b/crypto/src/main/java/javax/crypto/interfaces/DHPublicKey.java
new file mode 100644
index 0000000..75201a7
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/interfaces/DHPublicKey.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.interfaces;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+
+/**
+ * The interface for a public key in the Diffie-Hellman key exchange protocol.
+ *
+ * @since Android 1.0
+ */
+public interface DHPublicKey extends DHKey, PublicKey {
+
+ /**
+ * The serial version identifier.
+ */
+ public static final long serialVersionUID = -6628103563352519193L;
+
+ /**
+ * Returns this key's public value Y.
+ * @return this key's public value Y.
+ */
+ public BigInteger getY();
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/interfaces/PBEKey.java b/crypto/src/main/java/javax/crypto/interfaces/PBEKey.java
new file mode 100644
index 0000000..4612ad2
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/interfaces/PBEKey.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.interfaces;
+
+import javax.crypto.SecretKey;
+
+/**
+ * The interface to a <i>password-based-encryption</i> key.
+ *
+ * @since Android 1.0
+ */
+public interface PBEKey extends SecretKey {
+
+ /**
+ * The serial version identifier.
+ */
+ public static final long serialVersionUID = -1430015993304333921L;
+
+ /**
+ * Returns the iteration count, 0 if not specified.
+ *
+ * @return the iteration count, 0 if not specified.
+ */
+ public int getIterationCount();
+
+ /**
+ * Returns a copy of the salt data or null if not specified.
+ *
+ * @return a copy of the salt data or null if not specified.
+ */
+ public byte[] getSalt();
+
+ /**
+ * Returns a copy to the password.
+ *
+ * @return a copy to the password.
+ */
+ public char[] getPassword();
+
+} \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/interfaces/package.html b/crypto/src/main/java/javax/crypto/interfaces/package.html
new file mode 100644
index 0000000..04a7c0b
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/interfaces/package.html
@@ -0,0 +1,12 @@
+<html>
+ <body>
+ <p>
+ This package provides the interfaces needed to implement the
+ Diffie-Hellman (DH) key agreement's algorithm as specified by PKCS#3.
+
+ The parameters for the DH algorithm must be accessed without unduly
+ restriction as for example hardware repository for the parameters material.
+ </p>
+ @since Android 1.0
+ </body>
+</html> \ No newline at end of file
diff --git a/crypto/src/main/java/javax/crypto/package.html b/crypto/src/main/java/javax/crypto/package.html
new file mode 100644
index 0000000..3f3bb47
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/package.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+</head>
+<html>
+<body>
+<p>
+This package provides the classes and interfaces for cryptographic applications implementing algorithms for encryption, decryption, or
+key agreement.
+</p><p>
+Stream ciphers are supported as well as asymmetric, symmetric and block ciphers. Cipher implementations from different providers are easily integratable thanks
+to the SPI (Security Provider Interface) abstract classes. With class {@link javax.crypto.SealedObject} a programmer can secure an object by
+encrypting it with a cipher.
+</p><p>
+Authentication may be based on MAC (Message Authentication Code) such as HMAC (Hash MAC, i.e. with a SHA-1 hash function).
+</p>
+@since Android 1.0
+</body>
+</html>
diff --git a/crypto/src/main/java/javax/crypto/spec/DESKeySpec.java b/crypto/src/main/java/javax/crypto/spec/DESKeySpec.java
new file mode 100644
index 0000000..2a994d5
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DESKeySpec.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.InvalidKeyException;
+import java.security.spec.KeySpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The key specification for a DES key.
+ *
+ * @since Android 1.0
+ */
+public class DESKeySpec implements KeySpec {
+
+ /**
+ * The length of a DES key in bytes.
+ */
+ public static final int DES_KEY_LEN = 8;
+
+ private final byte[] key;
+
+ // DES weak and semi-weak keys
+ // Got from:
+ // FIP PUB 74
+ // FEDERAL INFORMATION PROCESSING STANDARDS PUBLICATION 1981
+ // GUIDELINES FOR IMPLEMENTING AND USING THE NBS DATA ENCRYPTION STANDARD
+ // http://www.dice.ucl.ac.be/crypto/standards/fips/fip74/fip74-1.pdf
+ private static final byte[][] SEMIWEAKS = {
+ {(byte) 0xE0, (byte) 0x01, (byte) 0xE0, (byte) 0x01,
+ (byte) 0xF1, (byte) 0x01, (byte) 0xF1, (byte) 0x01},
+
+ {(byte) 0x01, (byte) 0xE0, (byte) 0x01, (byte) 0xE0,
+ (byte) 0x01, (byte) 0xF1, (byte) 0x01, (byte) 0xF1},
+
+ {(byte) 0xFE, (byte) 0x1F, (byte) 0xFE, (byte) 0x1F,
+ (byte) 0xFE, (byte) 0x0E, (byte) 0xFE, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0xFE, (byte) 0x1F, (byte) 0xFE,
+ (byte) 0x0E, (byte) 0xFE, (byte) 0x0E, (byte) 0xFE},
+
+ {(byte) 0xE0, (byte) 0x1F, (byte) 0xE0, (byte) 0x1F,
+ (byte) 0xF1, (byte) 0x0E, (byte) 0xF1, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0xE0, (byte) 0x1F, (byte) 0xE0,
+ (byte) 0x0E, (byte) 0xF1, (byte) 0x0E, (byte) 0xF1},
+
+ {(byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE,
+ (byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE},
+
+ {(byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01,
+ (byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01},
+
+ {(byte) 0x01, (byte) 0x1F, (byte) 0x01, (byte) 0x1F,
+ (byte) 0x01, (byte) 0x0E, (byte) 0x01, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0x01, (byte) 0x1F, (byte) 0x01,
+ (byte) 0x0E, (byte) 0x01, (byte) 0x0E, (byte) 0x01},
+
+ {(byte) 0xE0, (byte) 0xFE, (byte) 0xE0, (byte) 0xFE,
+ (byte) 0xF1, (byte) 0xFE, (byte) 0xF1, (byte) 0xFE},
+
+ {(byte) 0xFE, (byte) 0xE0, (byte) 0xFE, (byte) 0xE0,
+ (byte) 0xFE, (byte) 0xF1, (byte) 0xFE, (byte) 0xF1},
+
+ {(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01},
+
+ {(byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE,
+ (byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE},
+
+ {(byte) 0xE0, (byte) 0xE0, (byte) 0xE0, (byte) 0xE0,
+ (byte) 0xF1, (byte) 0xF1, (byte) 0xF1, (byte) 0xF1},
+
+ {(byte) 0x1F, (byte) 0x1F, (byte) 0x1F, (byte) 0x1F,
+ (byte) 0x0E, (byte) 0x0E, (byte) 0x0E, (byte) 0x0E},
+
+ };
+
+ /**
+ * Creates a new <code>DESKeySpec</code> from the first 8 bytes of the
+ * specified key data.
+ *
+ * @param key
+ * the key data.
+ * @throws InvalidKeyException
+ * if the length of the specified key data is less than 8.
+ */
+ public DESKeySpec(byte[] key) throws InvalidKeyException {
+ this(key, 0);
+ }
+
+ /**
+ * Creates a new <code>DESKeySpec</code> from the first 8 bytes of the
+ * specified key data starting at <code>offset</code>.
+ *
+ * @param key
+ * the key data
+ * @param offset
+ * the offset to start at.
+ * @throws InvalidKeyException
+ * if the length of the specified key data starting at offset is
+ * less than 8.
+ */
+ public DESKeySpec(byte[] key, int offset)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new NullPointerException(Messages.getString("crypto.2F")); //$NON-NLS-1$
+ }
+ if (key.length - offset < DES_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.40")); //$NON-NLS-1$
+ }
+ this.key = new byte[DES_KEY_LEN];
+ System.arraycopy(key, offset, this.key, 0, DES_KEY_LEN);
+ }
+
+ /**
+ * Returns a copy of the key.
+ *
+ * @return a copy of the key.
+ */
+ public byte[] getKey() {
+ byte[] result = new byte[DES_KEY_LEN];
+ System.arraycopy(this.key, 0, result, 0, DES_KEY_LEN);
+ return result;
+ }
+
+ /**
+ * Returns whether the specified key data starting at <code>offset</code> is
+ * <i>parity-adjusted</i>.
+ *
+ * @param key
+ * the key data.
+ * @param offset
+ * the offset to start checking at.
+ * @return {@code true} if the specified key data is parity-adjusted,
+ * {@code false} otherwise.
+ * @throws InvalidKeyException
+ * if the length of the key data starting at offset is less than
+ * 8, or the key is null.
+ */
+ public static boolean isParityAdjusted(byte[] key, int offset)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException(Messages.getString("crypto.2F")); //$NON-NLS-1$
+ }
+ if (key.length - offset < DES_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.40")); //$NON-NLS-1$
+ }
+
+ int byteKey = 0;
+
+ for (int i = offset; i < DES_KEY_LEN; i++) {
+ byteKey = key[i];
+
+ byteKey ^= byteKey >> 1;
+ byteKey ^= byteKey >> 2;
+ byteKey ^= byteKey >> 4;
+
+ if ((byteKey & 1) == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns whether the specified key data starting at <code>offset</code> is
+ * weak or semi-weak.
+ *
+ * @param key
+ * the key data.
+ * @param offset
+ * the offset to start checking at.
+ * @return {@code true} if the specified key data is weak or semi-weak.
+ * @throws InvalidKeyException
+ * if the length of the key data starting at offset is less than
+ * 8, or it is null.
+ */
+ public static boolean isWeak(byte[] key, int offset)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new InvalidKeyException(Messages.getString("crypto.2F")); //$NON-NLS-1$
+ }
+ if (key.length - offset < DES_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.40")); //$NON-NLS-1$
+ }
+ I:
+ for (int i=0; i<SEMIWEAKS.length; i++) {
+ for (int j=0; j<DES_KEY_LEN; j++) {
+ if (SEMIWEAKS[i][j] != key[offset+j]) {
+ continue I;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/DESedeKeySpec.java b/crypto/src/main/java/javax/crypto/spec/DESedeKeySpec.java
new file mode 100644
index 0000000..186f07d
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DESedeKeySpec.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.InvalidKeyException;
+import java.security.spec.KeySpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The key specification for a triple-DES (DES-EDE) key.
+ *
+ * @since Android 1.0
+ */
+public class DESedeKeySpec implements KeySpec {
+
+ /**
+ * The length of a DES-EDE key in bytes.
+ */
+ public static final int DES_EDE_KEY_LEN = 24;
+
+ private final byte[] key;
+
+ /**
+ * Creates a new <code>DESedeKeySpec</code> instance from the first 24 (
+ * {@link #DES_EDE_KEY_LEN}) bytes of the specified key data.
+ *
+ * @param key
+ * the key data.
+ * @throws InvalidKeyException
+ * if the length of the key data is less than 24.
+ * @throws NullPointerException
+ * if the key data is null.
+ */
+ public DESedeKeySpec(byte[] key)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new NullPointerException(Messages.getString("crypto.2F")); //$NON-NLS-1$
+ }
+ if (key.length < DES_EDE_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.30")); //$NON-NLS-1$
+ }
+ this.key = new byte[DES_EDE_KEY_LEN];
+ System.arraycopy(key, 0, this.key, 0, DES_EDE_KEY_LEN);
+ }
+
+ /**
+ * Creates a new <code>DESedeKeySpec</code> instance from the first 24 (
+ * {@link #DES_EDE_KEY_LEN} ) bytes of the specified key data starting at
+ * <code>offset</code>.
+ *
+ * @param key
+ * the key data
+ * @param offset
+ * the offset to start at.
+ * @throws InvalidKeyException
+ * if the length of the key data starting at offset is less than
+ * 24.
+ * @throws NullPointerException
+ * if the key data is null.
+ */
+ public DESedeKeySpec(byte[] key, int offset)
+ throws InvalidKeyException {
+ if (key == null) {
+ throw new NullPointerException(Messages.getString("crypto.2F")); //$NON-NLS-1$
+ }
+ if (key.length - offset < DES_EDE_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.30")); //$NON-NLS-1$
+ }
+ this.key = new byte[DES_EDE_KEY_LEN];
+ System.arraycopy(key, offset, this.key, 0, DES_EDE_KEY_LEN);
+ }
+
+ /**
+ * Returns a copy of the key.
+ *
+ * @return a copy of the key.
+ */
+ public byte[] getKey() {
+ byte[] result = new byte [DES_EDE_KEY_LEN];
+ System.arraycopy(this.key, 0, result, 0, DES_EDE_KEY_LEN);
+ return result;
+ }
+
+ /**
+ * Returns whether the specified key data starting at <code>offset</code> is
+ * <i>parity-adjusted</i>.
+ *
+ * @param key
+ * the key data.
+ * @param offset
+ * the offset to start checking at.
+ * @return {@code true} if the specified key data is parity-adjusted,
+ * {@code false} otherwise.
+ * @throws InvalidKeyException
+ * if the length of the key data starting at offset is less than
+ * 24.
+ */
+ public static boolean isParityAdjusted(byte[] key, int offset)
+ throws InvalidKeyException {
+ if (key.length - offset < DES_EDE_KEY_LEN) {
+ throw new InvalidKeyException(
+ Messages.getString("crypto.30")); //$NON-NLS-1$
+ }
+ for (int i=offset; i<DES_EDE_KEY_LEN+offset; i++) {
+ int b = key[i];
+ if ((((b & 1) + ((b & 2) >> 1) + ((b & 4) >> 2)
+ + ((b & 8) >> 3) + ((b & 16) >> 4) + ((b & 32) >> 5)
+ + ((b & 64) >> 6)) & 1) == ((b & 128) >> 7)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/DHGenParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/DHGenParameterSpec.java
new file mode 100644
index 0000000..a149318
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DHGenParameterSpec.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The algorithm parameter specification for generating Diffie-Hellman
+ * parameters used in Diffie-Hellman key agreement.
+ *
+ * @since Android 1.0
+ */
+public class DHGenParameterSpec implements AlgorithmParameterSpec {
+
+ private final int primeSize;
+ private final int exponentSize;
+
+ /**
+ * Creates a new <code>DHGenParameterSpec</code> instance with the specified
+ * parameters.
+ *
+ * @param primeSize
+ * the size of the <i>prime modulus</i> in bits.
+ * @param exponentSize
+ * the size of the <i>random exponent</i> in bits.
+ */
+ public DHGenParameterSpec(int primeSize, int exponentSize) {
+ this.primeSize = primeSize;
+ this.exponentSize = exponentSize;
+ }
+
+ /**
+ * Returns the size of the <i>prime modulus</i> in bits.
+ *
+ * @return the size of the prime modulus in bits.
+ */
+ public int getPrimeSize() {
+ return primeSize;
+ }
+
+ /**
+ * Returns the size of the <i>random exponent</i> in bits.
+ *
+ * @return the size of the random exponent in bits.
+ */
+ public int getExponentSize() {
+ return exponentSize;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/DHParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/DHParameterSpec.java
new file mode 100644
index 0000000..9bb94b5
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DHParameterSpec.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+
+/**
+ * The algorithm parameter specification for the Diffie-Hellman algorithm.
+ *
+ * @since Android 1.0
+ */
+public class DHParameterSpec implements AlgorithmParameterSpec {
+
+ private final BigInteger p;
+ private final BigInteger g;
+ private final int l;
+
+ /**
+ * Creates a new <code>DHParameterSpec</code> instance with the specified
+ * <i>prime modulus</i> and <i>base generator</i>.
+ *
+ * @param p
+ * the prime modulus.
+ * @param g
+ * the base generator.
+ */
+ public DHParameterSpec(BigInteger p, BigInteger g) {
+ this.p = p;
+ this.g = g;
+ this.l = 0;
+ }
+
+ /**
+ * Creates a new <code>DHParameterSpec</code> instance with the specified
+ * <i>prime modulus</i>, <i>base generator</i> and size (in bits) of the
+ * <i>random exponent</i>.
+ *
+ * @param p
+ * the prime modulus.
+ * @param g
+ * the base generator.
+ * @param l
+ * the size of the random exponent (in bits).
+ */
+ public DHParameterSpec(BigInteger p, BigInteger g, int l) {
+ this.p = p;
+ this.g = g;
+ this.l = l;
+ }
+
+ /**
+ * Returns the <i>prime modulus</i> of this parameter specification.
+ *
+ * @return the prime modulus.
+ */
+ public BigInteger getP() {
+ return p;
+ }
+
+ /**
+ * Returns the <i>base generator</i> of this parameter specification.
+ *
+ * @return the base generator.
+ */
+ public BigInteger getG() {
+ return g;
+ }
+
+ /**
+ * Returns the size (in bits) of the <i>random exponent</i>.
+ *
+ * @return the size (in bits) of the random exponent.
+ */
+ public int getL() {
+ return l;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java b/crypto/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java
new file mode 100644
index 0000000..6652de8
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DHPrivateKeySpec.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.KeySpec;
+
+/**
+ * The key specification for a Diffie-Hellman private key.
+ *
+ * @since Android 1.0
+ */
+public class DHPrivateKeySpec implements KeySpec {
+
+ private final BigInteger x;
+ private final BigInteger p;
+ private final BigInteger g;
+
+ /**
+ * Creates a new <code>DHPrivateKeySpec</code> with the specified <i>private
+ * value</i> <code>x</code>. <i>prime modulus</i> <code>p</code> and <i>base
+ * generator</i> <code>g</code>.
+ *
+ * @param x
+ * the private value.
+ * @param p
+ * the prime modulus.
+ * @param g
+ * the base generator.
+ */
+ public DHPrivateKeySpec(BigInteger x, BigInteger p, BigInteger g) {
+ this.x = x;
+ this.p = p;
+ this.g = g;
+ }
+
+ /**
+ * Returns the <i>private value</i> <code>x</code>.
+ *
+ * @return the private value <code>x</code>.
+ */
+ public BigInteger getX() {
+ return x;
+ }
+
+ /**
+ * Returns the <i>prime modulus</i> <code>p</code>.
+ *
+ * @return the prime modulus <code>p</code>.
+ */
+ public BigInteger getP() {
+ return p;
+ }
+
+ /**
+ * Returns the <i>base generator</i> <code>g</code>.
+ *
+ * @return the base generator <code>g</code>.
+ */
+ public BigInteger getG() {
+ return g;
+ }
+}
diff --git a/crypto/src/main/java/javax/crypto/spec/DHPublicKeySpec.java b/crypto/src/main/java/javax/crypto/spec/DHPublicKeySpec.java
new file mode 100644
index 0000000..68d3267
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/DHPublicKeySpec.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.math.BigInteger;
+import java.security.spec.KeySpec;
+
+/**
+ * The key specification for a Diffie-Hellman public key.
+ *
+ * @since Android 1.0
+ */
+public class DHPublicKeySpec implements KeySpec {
+
+ private final BigInteger y;
+ private final BigInteger p;
+ private final BigInteger g;
+
+ /**
+ * Creates a new <code>DHPublicKeySpec</code> instance with the specified
+ * <i>public value</i> <code>y</code>, the <i>prime modulus</i>
+ * <code>p</code> and the <i>base generator</i> <code>g</code>.
+ *
+ * @param y
+ * the public value.
+ * @param p
+ * the prime modulus.
+ * @param g
+ * the base generator.
+ */
+ public DHPublicKeySpec(BigInteger y, BigInteger p, BigInteger g) {
+ this.y = y;
+ this.p = p;
+ this.g = g;
+ }
+
+ /**
+ * Returns the <i>public value</i> <code>y</code>.
+ *
+ * @return the public value <code>y</code>.
+ */
+ public BigInteger getY() {
+ return y;
+ }
+
+ /**
+ * Returns the <i>prime modulus</i> <code>p</code>.
+ *
+ * @return the prime modulus <code>p</code>.
+ */
+ public BigInteger getP() {
+ return p;
+ }
+
+ /**
+ * Returns the <i>base generator</i> <code>g</code>;
+ *
+ * @return the base generator <code>g</code>;
+ */
+ public BigInteger getG() {
+ return g;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/IvParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/IvParameterSpec.java
new file mode 100644
index 0000000..2f532a8
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/IvParameterSpec.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The algorithm parameter specification for an <i>initialization vector</i>.
+ */
+public class IvParameterSpec implements AlgorithmParameterSpec {
+
+ private final byte[] iv;
+
+ /**
+ * Creates a new <code>IvParameterSpec</code> instance with the bytes from
+ * the specified buffer <i>iv</i> used as <i>initialization vector</i>.
+ *
+ * @param iv
+ * the buffer used as initialization vector.
+ * @throws NullPointerException
+ * if the specified buffer is null.
+ */
+ public IvParameterSpec(byte[] iv) {
+ if (iv == null) {
+ throw new NullPointerException(Messages.getString("crypto.38")); //$NON-NLS-1$
+ }
+ this.iv = new byte[iv.length];
+ System.arraycopy(iv, 0, this.iv, 0, iv.length);
+ }
+
+ /**
+ * Creates a new <code>IvParameterSpec</code> instance with <code>len</code>
+ * bytes from the specified buffer <code>iv</code> starting at
+ * <code>offset</code>.
+ *
+ * @param iv
+ * the buffer used as initialization vector.
+ * @param offset
+ * the offset to start in the buffer.
+ * @param len
+ * the length of the data.
+ * @throws IllegalArgumentException
+ * if the specified buffer is null or <code>offset</code> and
+ * <code>len</code> do not specify a valid chunk in the
+ * specified buffer.
+ * @throws ArrayIndexOutOfBoundsException
+ * if <code>offset</code> or <code>len</code> are negative.
+ */
+ public IvParameterSpec(byte[] iv, int offset, int len) {
+ if ((iv == null) || (iv.length - offset < len)) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.39")); //$NON-NLS-1$
+ }
+ if (offset < 0 || len < 0) {
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.3A")); //$NON-NLS-1$
+ }
+ this.iv = new byte[len];
+ System.arraycopy(iv, offset, this.iv, 0, len);
+ }
+
+ /**
+ * Returns a copy of the <i>initialization vector</i> data.
+ *
+ * @return a copy of the initialization vector data.
+ */
+ public byte[] getIV() {
+ byte[] res = new byte[iv.length];
+ System.arraycopy(iv, 0, res, 0, iv.length);
+ return res;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/OAEPParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/OAEPParameterSpec.java
new file mode 100644
index 0000000..ebb6cce
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/OAEPParameterSpec.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.spec.PSource;
+
+/**
+ * The algorithm parameter specification for the <i>OAEP Padding</i> algorithm.
+ * <p>
+ * This padding algorithm is defined in the <a
+ * href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a> standard.
+ *
+ * @since Android 1.0
+ */
+public class OAEPParameterSpec implements AlgorithmParameterSpec {
+
+ private final String mdName;
+ private final String mgfName;
+ private final AlgorithmParameterSpec mgfSpec;
+ private final PSource pSrc;
+
+ /**
+ * The algorithm parameter instance with default values.
+ * <p>
+ * It uses the following parameters:
+ * <ul><li>message digest : <code>"SHA-1"</code></li>
+ * <li>mask generation function (<i>mgf</i>) : <code>"MGF1"</code></li>
+ * <li>parameters for the <i>mgf</i> : "SHA-1" {@link MGF1ParameterSpec#SHA1}</li>
+ * <li>the source of the label <code>L</code>: {@link PSource.PSpecified#DEFAULT}</li>
+ * </ul>
+ */
+ public static final OAEPParameterSpec DEFAULT = new OAEPParameterSpec();
+
+ private OAEPParameterSpec() {
+ this.mdName = "SHA-1"; //$NON-NLS-1$
+ this.mgfName = "MGF1"; //$NON-NLS-1$
+ this.mgfSpec = MGF1ParameterSpec.SHA1;
+ this.pSrc = PSource.PSpecified.DEFAULT;
+ }
+
+ /**
+ * Creates a new <code>OAEPParameterSpec</code> instance with the specified
+ * <i>message digest</i> algorithm name, <i>mask generation function</i>
+ * (<i>mgf</i>) algorithm name, <i>parameters</i> for the <i>mgf</i>
+ * algorithm and the <i>source of the label <code>L</code></i>.
+ *
+ * @param mdName
+ * the message digest algorithm name.
+ * @param mgfName
+ * the mask generation function algorithm name.
+ * @param mgfSpec
+ * the algorithm parameter specification for the mask generation
+ * function algorithm.
+ * @param pSrc
+ * the source of the label <code>L</code>.
+ * @throws NullPointerException
+ * if one of <code>mdName</code>, <code>mgfName</code> or
+ * <code>pSrc</code> is null.
+ */
+ public OAEPParameterSpec(String mdName, String mgfName,
+ AlgorithmParameterSpec mgfSpec, PSource pSrc) {
+ if ((mdName == null) || (mgfName == null) || (pSrc == null)) {
+ throw new NullPointerException();
+ }
+ this.mdName = mdName;
+ this.mgfName = mgfName;
+ this.mgfSpec = mgfSpec;
+ this.pSrc = pSrc;
+ }
+
+ /**
+ * Returns the algorithm name of the <i>message digest</i>.
+ *
+ * @return the algorithm name of the message digest.
+ */
+ public String getDigestAlgorithm() {
+ return mdName;
+ }
+
+ /**
+ * Returns the algorithm name of the <i>mask generation function</i>.
+ *
+ * @return the algorithm name of the mask generation function.
+ */
+ public String getMGFAlgorithm() {
+ return mgfName;
+ }
+
+ /**
+ * Returns the algorithm parameter specification for the mask generation
+ * function algorithm.
+ *
+ * @return the algorithm parameter specification for the mask generation
+ * function algorithm.
+ */
+ public AlgorithmParameterSpec getMGFParameters() {
+ return mgfSpec;
+ }
+
+ /**
+ * Returns the source of the label <code>L</code>.
+ *
+ * @return the source of the label <code>L</code>.
+ */
+ public PSource getPSource() {
+ return pSrc;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/PBEKeySpec.java b/crypto/src/main/java/javax/crypto/spec/PBEKeySpec.java
new file mode 100644
index 0000000..c46617e
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/PBEKeySpec.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The key specification for a <i>password based encryption</i> key.
+ * <p>
+ * Password based encryption is described in <a
+ * href="http://www.ietf.org/rfc/rfc2898.txt">PKCS #5</a>.
+ *
+ * @since Android 1.0
+ */
+public class PBEKeySpec implements KeySpec {
+
+ private char[] password;
+ private final byte[] salt;
+ private final int iterationCount;
+ private final int keyLength;
+
+ /**
+ * Creates a new <code>PBEKeySpec</code> with the specified password.
+ *
+ * @param password
+ * the password.
+ */
+ public PBEKeySpec(char[] password) {
+ if (password == null) {
+ this.password = new char[0];
+ } else {
+ this.password = new char[password.length];
+ System.arraycopy(password, 0, this.password, 0, password.length);
+ }
+ salt = null;
+ iterationCount = 0;
+ keyLength = 0;
+ }
+
+ /**
+ * Creates a new <code>PBEKeySpec</code> with the specified password, salt,
+ * iteration count and the desired length of the derived key.
+ *
+ * @param password
+ * the password.
+ * @param salt
+ * the salt.
+ * @param iterationCount
+ * the iteration count.
+ * @param keyLength
+ * the desired key length of the derived key,
+ * @throws NullPointerException
+ * if the salt is null.
+ * @throws IllegalArgumentException
+ * if the salt is empty, iteration count is zero or negative or
+ * the key length is zero or negative.
+ */
+ public PBEKeySpec(char[] password, byte[] salt, int iterationCount,
+ int keyLength) {
+ if (salt == null) {
+ throw new NullPointerException(Messages.getString("crypto.3B")); //$NON-NLS-1$
+ }
+ if (salt.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.3C")); //$NON-NLS-1$
+ }
+ if (iterationCount <= 0) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.3D")); //$NON-NLS-1$
+ }
+ if (keyLength <= 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.3E")); //$NON-NLS-1$
+ }
+
+ if (password == null) {
+ this.password = new char[0];
+ } else {
+ this.password = new char[password.length];
+ System.arraycopy(password, 0, this.password, 0, password.length);
+ }
+ this.salt = new byte[salt.length];
+ System.arraycopy(salt, 0, this.salt, 0, salt.length);
+ this.iterationCount = iterationCount;
+ this.keyLength = keyLength;
+ }
+
+ /**
+ * Creates a new <code>PBEKeySpec</code> with the specified password, salt
+ * and iteration count.
+ *
+ * @param password
+ * the password.
+ * @param salt
+ * the salt.
+ * @param iterationCount
+ * the iteration count.
+ * @throws NullPointerException
+ * if salt is null.
+ * @throws IllegalArgumentException
+ * if the salt is empty or iteration count is zero or negative.
+ */
+ public PBEKeySpec(char[] password, byte[] salt, int iterationCount) {
+ if (salt == null) {
+ throw new NullPointerException(Messages.getString("crypto.3B")); //$NON-NLS-1$
+ }
+ if (salt.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.3C")); //$NON-NLS-1$
+ }
+ if (iterationCount <= 0) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.3D")); //$NON-NLS-1$
+ }
+
+ if (password == null) {
+ this.password = new char[0];
+ } else {
+ this.password = new char[password.length];
+ System.arraycopy(password, 0, this.password, 0, password.length);
+ }
+ this.salt = new byte[salt.length];
+ System.arraycopy(salt, 0, this.salt, 0, salt.length);
+ this.iterationCount = iterationCount;
+ this.keyLength = 0;
+ }
+
+ /**
+ * Clears the password by overwriting it.
+ */
+ public final void clearPassword() {
+ Arrays.fill(password, '?');
+ password = null;
+ }
+
+ /**
+ * Returns a copy of the password of this key specification.
+ *
+ * @return a copy of the password of this key specification.
+ * @throws IllegalStateException
+ * if the password has been cleared before.
+ */
+ public final char[] getPassword() {
+ if (password == null) {
+ throw new IllegalStateException(Messages.getString("crypto.3F")); //$NON-NLS-1$
+ }
+ char[] result = new char[password.length];
+ System.arraycopy(password, 0, result, 0, password.length);
+ return result;
+ }
+
+ /**
+ * Returns a copy of the salt of this key specification.
+ *
+ * @return a copy of the salt of this key specification or null if none is
+ * specified.
+ */
+ public final byte[] getSalt() {
+ if (salt == null) {
+ return null;
+ }
+ byte[] result = new byte[salt.length];
+ System.arraycopy(salt, 0, result, 0, salt.length);
+ return result;
+ }
+
+ /**
+ * Returns the iteration count of this key specification.
+ *
+ * @return the iteration count of this key specification.
+ */
+ public final int getIterationCount() {
+ return iterationCount;
+ }
+
+ /**
+ * Returns the desired key length of the derived key.
+ *
+ * @return the desired key length of the derived key.
+ */
+ public final int getKeyLength() {
+ return keyLength;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/PBEParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/PBEParameterSpec.java
new file mode 100644
index 0000000..190986e
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/PBEParameterSpec.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The algorithm parameter specification for a <i>password based encryption</i>
+ * algorithm.
+ * <p>
+ * Password based encryption is described in <a
+ * href="http://www.ietf.org/rfc/rfc2898.txt">PKCS #5</a>.
+ *
+ * @since Android 1.0
+ *
+ */
+public class PBEParameterSpec implements AlgorithmParameterSpec {
+
+ private final byte[] salt;
+ private final int iterationCount;
+
+ /**
+ * Creates a new <code>PBEParameterSpec</code> with the specified salt and
+ * iteration count.
+ *
+ * @param salt
+ * the salt.
+ * @param iterationCount
+ * the iteration count.
+ * @throws NullPointerException
+ * if salt is null.
+ */
+ public PBEParameterSpec(byte[] salt, int iterationCount) {
+ if (salt == null) {
+ throw new NullPointerException(Messages.getString("crypto.3B")); //$NON-NLS-1$
+ }
+ this.salt = new byte[salt.length];
+ System.arraycopy(salt, 0, this.salt, 0, salt.length);
+ this.iterationCount = iterationCount;
+ }
+
+ /**
+ * Returns a copy to the salt.
+ *
+ * @return a copy to the salt.
+ */
+ public byte[] getSalt() {
+ byte[] result = new byte[salt.length];
+ System.arraycopy(salt, 0, result, 0, salt.length);
+ return result;
+ }
+
+ /**
+ * Returns the iteration count.
+ *
+ * @return the iteration count.
+ */
+ public int getIterationCount() {
+ return iterationCount;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/PSource.java b/crypto/src/main/java/javax/crypto/spec/PSource.java
new file mode 100644
index 0000000..d5bdf1b
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/PSource.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The source of the label <code>L</code> as specified in <a
+ * href="http://www.ietf.org/rfc/rfc3447.txt"> PKCS #1</a>.
+ *
+ * @since Android 1.0
+ */
+public class PSource {
+
+ private String pSrcName;
+
+ private PSource() {}
+
+ /**
+ * Creates a new <code>PSource</code> instance with the specified source
+ * algorithm identifier.
+ *
+ * @param pSrcName
+ * the source algorithm identifier.
+ * @throws NullPointerException
+ * if pSrcName is null.
+ */
+ protected PSource(String pSrcName) {
+ if (pSrcName == null) {
+ throw new NullPointerException(Messages.getString("crypto.42")); //$NON-NLS-1$
+ }
+ this.pSrcName = pSrcName;
+ }
+
+ /**
+ * Returns the source algorithm identifier.
+ *
+ * @return the source algorithm identifier.
+ */
+ public String getAlgorithm() {
+ return pSrcName;
+ }
+
+ /**
+ * The explicit specification of the parameter <code>P</code> used in the
+ * source algorithm.
+ *
+ * @since Android 1.0
+ */
+ public static final class PSpecified extends PSource {
+
+ private final byte[] p;
+
+ /**
+ * The instance of <code>PSpecified</code> with the default value <code>byte[0]</code> for <code>P</code>
+ */
+ public static final PSpecified DEFAULT = new PSpecified();
+
+ private PSpecified() {
+ super("PSpecified"); //$NON-NLS-1$
+ p = new byte[0];
+ }
+
+ /**
+ * Creates a new instance of <code>PSpecified</code> with the specified
+ * parameter <code>P</code>.
+ *
+ * @param p
+ * the parameter <code>P</code>.
+ * @throws NullPointerException
+ * if <code>p</code> is null.
+ */
+ public PSpecified(byte[] p) {
+ super("PSpecified"); //$NON-NLS-1$
+ if (p == null) {
+ throw new NullPointerException(Messages.getString("crypto.43")); //$NON-NLS-1$
+ }
+ //TODO: It is unknown which name should be used!
+ //super("");
+ this.p = new byte[p.length];
+ System.arraycopy(p, 0, this.p, 0, p.length);
+ }
+
+ /**
+ * Returns a copy of the value of the parameter <code>P</code>.
+ *
+ * @return a copy of the value of the parameter <code>P</code>
+ */
+ public byte[] getValue() {
+ byte[] result = new byte[p.length];
+ System.arraycopy(p, 0, result, 0, p.length);
+ return result;
+ }
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/RC2ParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/RC2ParameterSpec.java
new file mode 100644
index 0000000..bd76cf4
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/RC2ParameterSpec.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The algorithm parameter specification for the <a
+ * href="http://www.ietf.org/rfc/rfc2268.txt">RC2</a> algorithm.
+ *
+ * @since Android 1.0
+ */
+public class RC2ParameterSpec implements AlgorithmParameterSpec {
+
+ private final int effectiveKeyBits;
+ private final byte[] iv;
+
+ /**
+ * Creates a new <code>RC2ParameterSpec</code> instance with the specified
+ * effective key length (in bits),
+ *
+ * @param effectiveKeyBits
+ * the effective key length (in bits).
+ */
+ public RC2ParameterSpec(int effectiveKeyBits) {
+ this.effectiveKeyBits = effectiveKeyBits;
+ iv = null;
+ }
+
+ /**
+ * Creates a new <code>RC2ParameterSpec</code> instance with the specified
+ * effective key length (in bits) and <i>initialization vector</i>.
+ * <p>
+ * The size of the <i>initialization vector</i> must be at least 8 bytes
+ * which are copied to protect them against modification.
+ *
+ * @param effectiveKeyBits
+ * the effective key length (in bits).
+ * @param iv
+ * the initialization vector.
+ * @throws IllegalArgumentException
+ * if the initialization vector is null or shorter than 8 bytes.
+ */
+ public RC2ParameterSpec(int effectiveKeyBits, byte[] iv) {
+ if (iv == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
+ }
+ if (iv.length < 8) {
+ throw new IllegalArgumentException(Messages.getString("crypto.41")); //$NON-NLS-1$
+ }
+ this.effectiveKeyBits = effectiveKeyBits;
+ this.iv = new byte[8];
+ System.arraycopy(iv, 0, this.iv, 0, 8);
+ }
+
+ /**
+ * Creates a new <code>RC2ParameterSpec</code> instance with the specified
+ * effective key length (in bits) and <i>initialization vector<i>.
+ * <p>
+ * The size of the <i>initialization vector</i> starting at
+ * <code>offset</code> must be at least 8 bytes which are copied to protect
+ * them against modification.
+ *
+ * @param effectiveKeyBits
+ * the effective key length (in bits).
+ * @param iv
+ * the initialization vector.
+ * @param offset
+ * the offset in the initialization vector to start at.
+ * @throws IllegalArgumentException
+ * if the initialization vector is null or starting at
+ * <code>offset</code> is shorter than 8 bytes.
+ */
+ public RC2ParameterSpec(int effectiveKeyBits, byte[] iv, int offset) {
+ if (iv == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
+ }
+ if (iv.length - offset < 8) {
+ throw new IllegalArgumentException(Messages.getString("crypto.41")); //$NON-NLS-1$
+ }
+ this.effectiveKeyBits = effectiveKeyBits;
+ this.iv = new byte[8];
+ System.arraycopy(iv, offset, this.iv, 0, 8);
+ }
+
+ /**
+ * Returns the effective key length (in bits).
+ *
+ * @return the effective key length (in bits).
+ */
+ public int getEffectiveKeyBits() {
+ return effectiveKeyBits;
+ }
+
+ /**
+ * Returns a copy of the initialization vector.
+ *
+ * @return a copy of the initialization vector, or null if none specified.
+ */
+ public byte[] getIV() {
+ if (iv == null) {
+ return null;
+ }
+ byte[] result = new byte[iv.length];
+ System.arraycopy(iv, 0, result, 0, iv.length);
+ return result;
+ }
+
+ /**
+ * Compares the specified object to this <code>RC2ParameterSpec</code>
+ * instance.
+ *
+ * @param obj
+ * the object to compare.
+ * @return true if the effective key length and the initialization vector of
+ * both objects are equal, otherwise false.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof RC2ParameterSpec)) {
+ return false;
+ }
+ RC2ParameterSpec ps = (RC2ParameterSpec) obj;
+ return (effectiveKeyBits == ps.effectiveKeyBits)
+ && (Arrays.equals(iv, ps.iv));
+ }
+
+ /**
+ * Returns the hash code of this <code>RC2ParameterSpec</code> instance.
+ *
+ * @return the hash code.
+ */
+ @Override
+ public int hashCode() {
+ int result = effectiveKeyBits;
+ if (iv == null) {
+ return result;
+ }
+ for (byte element : iv) {
+ result += element;
+ }
+ return result;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/RC5ParameterSpec.java b/crypto/src/main/java/javax/crypto/spec/RC5ParameterSpec.java
new file mode 100644
index 0000000..f711f41
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/RC5ParameterSpec.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * The algorithm parameter specification for the <a
+ * href="http://www.ietf.org/rfc/rfc2040.txt">RC5</a> algorithm.
+ *
+ * @since Android 1.0
+ */
+public class RC5ParameterSpec implements AlgorithmParameterSpec {
+
+ private final int version;
+ private final int rounds;
+ private final int wordSize;
+ private final byte[] iv;
+
+ /**
+ * Creates a new <code>RC5ParameterSpec</code> instance with the specified
+ * version, round count an word size (in bits).
+ *
+ * @param version
+ * the version.
+ * @param rounds
+ * the round count.
+ * @param wordSize
+ * the word size (in bits).
+ */
+ public RC5ParameterSpec(int version, int rounds, int wordSize) {
+ this.version = version;
+ this.rounds = rounds;
+ this.wordSize = wordSize;
+ this.iv = null;
+ }
+
+ /**
+ * Creates a new <code>RC5ParameterSpec</code> instance with the specified
+ * version, round count, word size (in bits) and an <i>initialization
+ * vector</i>.
+ * <p>
+ * The size of the <i>initialization vector</i> must be at least
+ * <code>2 * (wordSize / 8)</code> bytes which are copied to protect them
+ * against modification.
+ *
+ * @param version
+ * the version.
+ * @param rounds
+ * the round count.
+ * @param wordSize
+ * the word size (in bits).
+ * @param iv
+ * the initialization vector.
+ * @throws IllegalArgumentException
+ * if the initialization vector is null or shorter than <code>2
+ * * (wordSize / 8)</code>.
+ */
+ public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) {
+ if (iv == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
+ }
+ if (iv.length < 2 * (wordSize / 8)) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.32")); //$NON-NLS-1$
+ }
+ this.version = version;
+ this.rounds = rounds;
+ this.wordSize = wordSize;
+ this.iv = new byte[2*(wordSize/8)];
+ System.arraycopy(iv, 0, this.iv, 0, 2*(wordSize/8));
+ }
+
+ /**
+ * Creates a new <code>RC5ParameterSpec</code> instance with the specified
+ * version, round count, wordSize (in bits), an <i>initialization vector</i>
+ * and an offset.
+ * <p>
+ * The size of the <i>initialization vector</i> must be at least
+ * <code>offset + (2 * (wordSize / 8))</code> bytes. The bytes starting at
+ * <code>offset</code> are copied to protect them against modification.
+ *
+ * @param version
+ * the version.
+ * @param rounds
+ * the round count.
+ * @param wordSize
+ * the word size (in bits).
+ * @param iv
+ * the initialization vector.
+ * @param offset
+ * the offset in the initialization vector.
+ * @throws IllegalArgumentException
+ * if the initialization vector is null of shorter than
+ * <code>offset + (2 * (wordSize / 8))</code>.
+ * @throws ArrayIndexOutOfBoundsException
+ * if <code>offset</code> is negative.
+ */
+ public RC5ParameterSpec(int version, int rounds,
+ int wordSize, byte[] iv, int offset) {
+ if (iv == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
+ }
+ if (offset < 0) {
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.33")); //$NON-NLS-1$
+ }
+ if (iv.length - offset < 2 * (wordSize / 8)) {
+ throw new IllegalArgumentException(
+ Messages.getString("crypto.34")); //$NON-NLS-1$
+ }
+ this.version = version;
+ this.rounds = rounds;
+ this.wordSize = wordSize;
+ this.iv = new byte[offset+2*(wordSize/8)];
+ System.arraycopy(iv, offset, this.iv, 0, 2*(wordSize/8));
+ }
+
+ /**
+ * Returns the version.
+ *
+ * @return the version.
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Returns the round count.
+ *
+ * @return the round count.
+ */
+ public int getRounds() {
+ return rounds;
+ }
+
+ /**
+ * Returns the word size (in bits).
+ *
+ * @return the word size (in bits).
+ */
+ public int getWordSize() {
+ return wordSize;
+ }
+
+ /**
+ * Returns a copy of the initialization vector.
+ *
+ * @return a copy of the initialization vector, or null if none specified.
+ */
+ public byte[] getIV() {
+ if (iv == null) {
+ return null;
+ }
+ byte[] result = new byte[iv.length];
+ System.arraycopy(iv, 0, result, 0, iv.length);
+ return result;
+ }
+
+ /**
+ * Compares the specified object with this <code>RC5ParameterSpec</code>
+ * instance.
+ *
+ * @param obj
+ * the object to compare.
+ * @return true if version, round count, word size and initializaion vector
+ * of both objects are equal, otherwise false.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof RC5ParameterSpec)) {
+ return false;
+ }
+ RC5ParameterSpec ps = (RC5ParameterSpec) obj;
+ return (version == ps.version)
+ && (rounds == ps.rounds)
+ && (wordSize == ps.wordSize)
+ && (Arrays.equals(iv, ps.iv));
+ }
+
+ /**
+ * Returns the hash code of this <code>RC5ParameterSpec</code> instance.
+ *
+ * @return the hash code.
+ */
+ @Override
+ public int hashCode() {
+ int result = version + rounds + wordSize;
+ if (iv == null) {
+ return result;
+ }
+ for (byte element : iv) {
+ result += element & 0xFF;
+ }
+ return result;
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/SecretKeySpec.java b/crypto/src/main/java/javax/crypto/spec/SecretKeySpec.java
new file mode 100644
index 0000000..897948c
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/SecretKeySpec.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package javax.crypto.spec;
+
+import java.io.Serializable;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import javax.crypto.SecretKey;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * A key specification for a <code>SecretKey</code> and also a secret key
+ * implementation that is provider-independent. It can be used for raw secret
+ * keys that can be specified as <code>byte[]</code>.
+ *
+ * @since Android 1.0
+ */
+public class SecretKeySpec implements SecretKey, KeySpec, Serializable {
+
+ // The 5.0 spec. doesn't declare this serialVersionUID field
+ // In order to be compatible it is explicitly declared here
+ // for details see HARMONY-233
+ private static final long serialVersionUID = 6577238317307289933L;
+
+ private final byte[] key;
+ private final String algorithm;
+ private final String format = "RAW"; //$NON-NLS-1$
+
+ /**
+ * Creates a new <code>SecretKeySpec</code> for the specified key data and
+ * algorithm name.
+ *
+ * @param key
+ * the key data.
+ * @param algorithm
+ * the algorithm name.
+ * @throws IllegalArgumentException
+ * if the key data or the algorithm name is null or if the key
+ * data is empty.
+ */
+ public SecretKeySpec(byte[] key, String algorithm) {
+ if (key == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.05")); //$NON-NLS-1$
+ }
+ if (key.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.35")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+
+ this.algorithm = algorithm;
+ this.key = new byte[key.length];
+ System.arraycopy(key, 0, this.key, 0, key.length);
+ }
+
+ /**
+ * Creates a new <code>SecretKeySpec</code> for the key data from the
+ * specified buffer <code>key</code> starting at <code>offset</code> with
+ * length <code>len</code> and the specified <code>algorithm</code> name.
+ *
+ * @param key
+ * the key data.
+ * @param offset
+ * the offset.
+ * @param len
+ * the size of the key data.
+ * @param algorithm
+ * the algorithm name.
+ * @throws IllegalArgumentException
+ * if the key data or the algorithm name is null, the key data
+ * is empty or <code>offset</code> and <code>len</code> do not
+ * specify a valid chunk in the buffer <code>key</code>.
+ * @throws ArrayIndexOutOfBoundsException
+ * if <code>offset</code> or <code>len</code> is negative.
+ */
+ public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
+ if (key == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.05")); //$NON-NLS-1$
+ }
+ if (key.length == 0) {
+ throw new IllegalArgumentException(Messages.getString("crypto.35")); //$NON-NLS-1$
+ }
+ // BEGIN android-changed
+ if (len < 0 || offset < 0) {
+ throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.36")); //$NON-NLS-1$
+ }
+ // END android-changed
+ if ((key.length - offset < len)) {
+ throw new IllegalArgumentException(Messages.getString("crypto.37")); //$NON-NLS-1$
+ }
+ if (algorithm == null) {
+ throw new IllegalArgumentException(Messages.getString("crypto.02")); //$NON-NLS-1$
+ }
+ this.algorithm = algorithm;
+ this.key = new byte[len];
+ System.arraycopy(key, offset, this.key, 0, len);
+ }
+
+ /**
+ * Returns the algorithm name.
+ *
+ * @return the algorithm name.
+ */
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Returns the name of the format used to encode the key.
+ *
+ * @return the format name "RAW".
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ /**
+ * Returns the encoded form of this secret key.
+ *
+ * @return the encoded form of this secret key.
+ */
+ public byte[] getEncoded() {
+ byte[] result = new byte[key.length];
+ System.arraycopy(key, 0, result, 0, key.length);
+ return result;
+ }
+
+ /**
+ * Returns the hash code of this <code>SecretKeySpec</code> object.
+ *
+ * @return the hash code.
+ */
+ @Override
+ public int hashCode() {
+ int result = algorithm.length();
+ for (byte element : key) {
+ result += element;
+ }
+ return result;
+ }
+
+ /**
+ * Compares the specified object with this <code>SecretKeySpec</code>
+ * instance.
+ *
+ * @param obj
+ * the object to compare.
+ * @return true if the algorithm name and key of both object are equal,
+ * otherwise false.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof SecretKeySpec)) {
+ return false;
+ }
+ SecretKeySpec ks = (SecretKeySpec) obj;
+ return (algorithm.equalsIgnoreCase(ks.algorithm))
+ && (Arrays.equals(key, ks.key));
+ }
+}
+
diff --git a/crypto/src/main/java/javax/crypto/spec/package.html b/crypto/src/main/java/javax/crypto/spec/package.html
new file mode 100644
index 0000000..f647f75
--- /dev/null
+++ b/crypto/src/main/java/javax/crypto/spec/package.html
@@ -0,0 +1,17 @@
+<html>
+ <body>
+ <p>
+ This package provides the classes and interfaces needed to specify keys
+ and parameter for encryption. Following standards are supported:
+ (1) PKCS#3 Diffie-Hellman ekey agreement's standard;
+ (2) FIPS-46-2 Data Encryption Standard (DES);
+ (3) PKCS#5 Password Based Encryption (PBE) standard.
+ Keys may be specified via algorithm or in a more abstract and general way
+ with ASN.1.
+
+ Keys and algorithm parameters are specified for the following procedures:
+ (i) DH, (ii) DES, (iii) TripleDES, (iv) PBE, (v) RC2 and (vi) RC5.
+ </p>
+ @since Android 1.0
+ </body>
+</html> \ No newline at end of file
diff --git a/crypto/src/main/java/org/apache/harmony/crypto/internal/NullCipherSpi.java b/crypto/src/main/java/org/apache/harmony/crypto/internal/NullCipherSpi.java
new file mode 100644
index 0000000..d6b2619
--- /dev/null
+++ b/crypto/src/main/java/org/apache/harmony/crypto/internal/NullCipherSpi.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Boris V. Kuznetsov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.internal;
+
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * CipherSpi implementation for javax.crypto.NullCipher
+ *
+ */
+public class NullCipherSpi extends CipherSpi {
+
+ @Override
+ public void engineSetMode(String arg0) throws NoSuchAlgorithmException {
+ // Do nothing
+ }
+
+ @Override
+ public void engineSetPadding(String arg0) throws NoSuchPaddingException {
+ // Do nothing
+ }
+
+ @Override
+ public int engineGetBlockSize() {
+ return 1;
+ }
+
+ @Override
+ public int engineGetOutputSize(int inputLen) {
+ return inputLen;
+ }
+
+ @Override
+ public byte[] engineGetIV() {
+ return new byte[8]; // compatible with RI
+ }
+
+ @Override
+ public AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ @Override
+ public void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ // Do nothing
+ }
+
+ @Override
+ public void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ // Do nothing
+ }
+
+ @Override
+ public void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ // Do nothing
+ }
+
+ @Override
+ public byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ if (input == null) {
+ return null;
+ }
+ byte[] result = new byte[inputLen];
+ System.arraycopy(input, inputOffset, result, 0, inputLen);
+ return result;
+ }
+
+ @Override
+ public int engineUpdate(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException {
+ if (input == null) {
+ return 0;
+ }
+ System.arraycopy(input, inputOffset, output, outputOffset, inputLen);
+ return inputLen;
+ }
+
+ @Override
+ public int engineUpdate(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ if (input == null || output == null) {
+ throw new NullPointerException();
+ }
+ int result = input.limit() - input.position();
+ try {
+ output.put(input);
+ } catch (java.nio.BufferOverflowException e) {
+ throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
+ }
+ return result;
+ }
+
+ @Override
+ public byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ if (input == null) {
+ return null;
+ }
+ return engineUpdate(input, inputOffset, inputLen);
+ }
+
+ @Override
+ public int engineDoFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ int result = engineUpdate(input, inputOffset, inputLen, output,
+ outputOffset);
+ return result;
+ }
+
+ @Override
+ public int engineDoFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ return engineUpdate(input, output);
+ }
+
+ @Override
+ public byte[] engineWrap(Key key) throws IllegalBlockSizeException,
+ InvalidKeyException {
+ throw new UnsupportedOperationException(Messages.getString("crypto.44")); //$NON-NLS-1$
+ }
+
+ @Override
+ public Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType) throws InvalidKeyException,
+ NoSuchAlgorithmException {
+ throw new UnsupportedOperationException(Messages.getString("crypto.45")); //$NON-NLS-1$
+ }
+
+ @Override
+ public int engineGetKeySize(Key key) throws InvalidKeyException {
+ throw new UnsupportedOperationException(Messages.getString("crypto.46")); //$NON-NLS-1$
+ }
+} \ No newline at end of file
diff --git a/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/Messages.java b/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/Messages.java
new file mode 100644
index 0000000..b61a5cf
--- /dev/null
+++ b/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/Messages.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * THE FILE HAS BEEN AUTOGENERATED BY MSGTOOL TOOL.
+ * All changes made to this file manually will be overwritten
+ * if this tool runs again. Better make changes in the template file.
+ */
+
+// BEGIN android-note
+// Redundant code has been removed and is now called from MsgHelp.
+// END android-note
+
+package org.apache.harmony.crypto.internal.nls;
+
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+// BEGIN android-changed
+import org.apache.harmony.luni.util.MsgHelp;
+// END android-changed
+
+/**
+ * This class retrieves strings from a resource bundle and returns them,
+ * formatting them with MessageFormat when required.
+ * <p>
+ * It is used by the system classes to provide national language support, by
+ * looking up messages in the <code>
+ * org.apache.harmony.crypto.internal.nls.messages
+ * </code>
+ * resource bundle. Note that if this file is not available, or an invalid key
+ * is looked up, or resource bundle support is not available, the key itself
+ * will be returned as the associated message. This means that the <em>KEY</em>
+ * should a reasonable human-readable (english) string.
+ *
+ */
+public class Messages {
+
+ // BEGIN android-changed
+ private static final String sResource =
+ "org.apache.harmony.crypto.internal.nls.messages"; //$NON-NLS-1$
+ // END android-changed
+
+ /**
+ * Retrieves a message which has no arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg) {
+ // BEGIN android-changed
+ return MsgHelp.getString(sResource, msg);
+ // END android-changed
+ }
+
+ /**
+ * Retrieves a message which takes 1 argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * Object the object to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object arg) {
+ return getString(msg, new Object[] { arg });
+ }
+
+ /**
+ * Retrieves a message which takes 1 integer argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * int the integer to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, int arg) {
+ return getString(msg, new Object[] { Integer.toString(arg) });
+ }
+
+ /**
+ * Retrieves a message which takes 1 character argument.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg
+ * char the character to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, char arg) {
+ return getString(msg, new Object[] { String.valueOf(arg) });
+ }
+
+ /**
+ * Retrieves a message which takes 2 arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param arg1
+ * Object an object to insert in the formatted output.
+ * @param arg2
+ * Object another object to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object arg1, Object arg2) {
+ return getString(msg, new Object[] { arg1, arg2 });
+ }
+
+ /**
+ * Retrieves a message which takes several arguments.
+ *
+ * @param msg
+ * String the key to look up.
+ * @param args
+ * Object[] the objects to insert in the formatted output.
+ * @return String the message for that key in the system message bundle.
+ */
+ static public String getString(String msg, Object[] args) {
+ // BEGIN android-changed
+ return MsgHelp.getString(sResource, msg, args);
+ // END android-changed
+ }
+
+ // BEGIN android-note
+ // Duplicate code was dropped in favor of using MsgHelp.
+ // END android-note
+}
diff --git a/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/messages.properties b/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/messages.properties
new file mode 100644
index 0000000..509e100
--- /dev/null
+++ b/crypto/src/main/java/org/apache/harmony/crypto/internal/nls/messages.properties
@@ -0,0 +1,87 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# messages for EN locale
+crypto.01=MAC was not initialized
+crypto.02=Algorithm is null
+crypto.03=Provider is null or empty
+crypto.04=Provider is null
+crypto.05=key is null
+crypto.06=Incorrect arguments
+crypto.07=input is null
+crypto.08=Output buffer is null
+crypto.09=Incorrect outOffset parameter: {0}
+crypto.0A=Output buffer is short. It is needed {0} bytes
+crypto.0B=Not initialized Mac
+crypto.0C=input byte buffer is null
+crypto.0D=output byte buffer is null
+crypto.0E=Output is small
+crypto.0F=Output buffer is too small: {0}
+crypto.10=engineWrap(Key key) is not supported
+crypto.11=engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) is not supported
+crypto.12=engineGetKeySize(Key key) is not supported
+crypto.13=Cipher is null\!
+crypto.14=Specified sealed object is null\!
+crypto.15=The provider name is empty or null
+crypto.16=Provider {0} is not available
+crypto.17=Invalid transformation {0}
+crypto.18=Cipher has not yet been initialized
+crypto.19=Invalid mode
+crypto.1A=The public key in the certificate cannot be used for ENCRYPT_MODE
+crypto.1B=The public key in the certificate cannot be used for DECRYPT_MODE
+crypto.1C=Cipher has not yet been initialized properly
+crypto.1D=The input parameter is null
+crypto.1E=Incorrect inputOffset/inputLen parameters
+crypto.1F=The output parameter is null
+crypto.20=Incorrect outputOffset parameter
+crypto.21=Incorrect inputOffset/inputLen parameters
+crypto.22=the encoded parameter is null
+crypto.23=the algName parameter is null
+crypto.24={0} not supported
+crypto.25=the encryptedData parameter is null
+crypto.26=the encryptedData is empty
+crypto.27=the algParams parameter is null
+crypto.28=the cipher parameter is null
+crypto.29=Decrypted data does not represent valid PKCS\#8 PrivateKeyInfo
+crypto.2A=the decryptKey parameter is null
+crypto.2B=the providerName parameter is null
+crypto.2C=the provider parameter is null
+crypto.2D=ExemptionMechanism is not initialized
+crypto.2E=Input and output are the same object
+crypto.2F=Specified key material is null.
+crypto.30=The key material is shorter than 24 bytes.
+crypto.31=iv is null
+crypto.32=iv.length < 2 * (wordSize / 8)
+crypto.33=offset is negative
+crypto.34=iv.length - offset < 2 * (wordSize / 8)
+crypto.35=key is empty
+crypto.36=len is negative
+crypto.37=key is too short
+crypto.38=Specified IV is null.
+crypto.39=iv is null or (iv.length - offset < len)
+crypto.3A=offset < 0 or len < 0
+crypto.3B=Specified salt is null.
+crypto.3C=salt is empty
+crypto.3D=iterationCount is not positive.
+crypto.3E=keyLength is not positive.
+crypto.3F=The password has been cleared.
+crypto.40=The key material is shorter than 8 bytes
+crypto.41=iv is shorter than 8 bytes
+crypto.42=pSrcName is null\!
+crypto.43=encoding input is null\!
+crypto.44=Wrap
+crypto.45=Unwrap
+crypto.46=GetKeySize
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java
new file mode 100644
index 0000000..5050fc8
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/AllTests.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.apache.harmony.crypto.tests.javax.crypto;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(BadPaddingExceptionTest.class);
+ suite.addTestSuite(CipherInputStream1Test.class);
+ suite.addTestSuite(CipherInputStreamTest.class);
+ suite.addTestSuite(CipherOutputStream1Test.class);
+ suite.addTestSuite(CipherOutputStreamTest.class);
+ suite.addTestSuite(CipherSpiTest.class);
+ suite.addTestSuite(CipherTest.class);
+ suite.addTestSuite(EncryptedPrivateKeyInfoTest.class);
+ suite.addTestSuite(ExemptionMechanismExceptionTest.class);
+ suite.addTestSuite(ExemptionMechanismSpiTest.class);
+ suite.addTestSuite(ExemptionMechanismTest.class);
+ suite.addTestSuite(IllegalBlockSizeExceptionTest.class);
+ suite.addTestSuite(KeyAgreementSpiTest.class);
+ suite.addTestSuite(KeyAgreementTest.class);
+ suite.addTestSuite(KeyGeneratorSpiTest.class);
+ suite.addTestSuite(KeyGeneratorTest.class);
+ suite.addTestSuite(MacSpiTest.class);
+ suite.addTestSuite(MacTest.class);
+ suite.addTestSuite(NoSuchPaddingExceptionTest.class);
+ suite.addTestSuite(NullCipherTest.class);
+ suite.addTestSuite(SealedObjectTest.class);
+ suite.addTestSuite(SecretKeyFactorySpiTest.class);
+ suite.addTestSuite(SecretKeyFactoryTest.class);
+ suite.addTestSuite(SecretKeyTest.class);
+ suite.addTestSuite(ShortBufferExceptionTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java
new file mode 100644
index 0000000..6297392
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/BadPaddingExceptionTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.BadPaddingException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests for <code>BadPaddingException</code> class constructors and methods.
+ *
+ */
+@TestTargetClass(BadPaddingException.class)
+public class BadPaddingExceptionTest extends TestCase {
+
+ static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+ static Throwable tCause = new Throwable("Throwable for exception");
+
+ /**
+ * Test for <code>BadPaddingException()</code> constructor Assertion:
+ * constructs BadPaddingException with no detail message
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "BadPaddingException",
+ args = {}
+ )
+ public void testBadPaddingException01() {
+ BadPaddingException tE = new BadPaddingException();
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+
+ /**
+ * Test for <code>BadPaddingException(String)</code> constructor
+ * Assertion: constructs BadPaddingException with detail message msg.
+ * Parameter <code>msg</code> is not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "BadPaddingException",
+ args = {java.lang.String.class}
+ )
+ public void testBadPaddingException02() {
+ BadPaddingException tE;
+ for (int i = 0; i < msgs.length; i++) {
+ tE = new BadPaddingException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), tE
+ .getMessage(), msgs[i]);
+ assertNull("getCause() must return null", tE.getCause());
+ }
+ }
+
+ /**
+ * Test for <code>BadPaddingException(String)</code> constructor
+ * Assertion: constructs BadPaddingException when <code>msg</code> is null
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "BadPaddingException",
+ args = {java.lang.String.class}
+ )
+ public void testBadPaddingException03() {
+ String msg = null;
+ BadPaddingException tE = new BadPaddingException(msg);
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStream1Test.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStream1Test.java
new file mode 100644
index 0000000..98ea555
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStream1Test.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.ByteArrayInputStream;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.NullCipher;
+import javax.crypto.CipherInputStream;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(CipherInputStream.class)
+/**
+ */
+
+public class CipherInputStream1Test extends TestCase {
+
+ private static class TestInputStream extends ByteArrayInputStream {
+ private boolean closed = false;
+
+ public TestInputStream(byte[] data) {
+ super(data);
+ }
+
+ public void close() {
+ closed = true;
+ }
+
+ public boolean wasClosed() {
+ return closed;
+ }
+ }
+
+ /**
+ * CipherInputStream(InputStream is) method testing. Tests that
+ * CipherInputStream uses NullCipher if Cipher is not specified
+ * in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "CipherInputStream",
+ args = {java.io.InputStream.class}
+ )
+ public void testCipherInputStream() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis){};
+
+ for (int i = 0; i < data.length; i++) {
+ if ((byte) cis.read() != data[i]) {
+ fail("NullCipher should be used "
+ + "if Cipher is not specified.");
+ }
+ }
+ if (cis.read() != -1) {
+ fail("NullCipher should be used if Cipher is not specified.");
+ }
+ }
+
+ /**
+ * read() method testing. Tests that method returns the correct value
+ * (related to the InputStream) and that it returns -1 at the end of stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "read",
+ args = {}
+ )
+ public void testRead1() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+ byte res;
+ for (int i = 0; i < data.length; i++) {
+ if ((res = (byte) cis.read()) != data[i]) {
+ fail("read() returned the incorrect value. " + "Expected: "
+ + data[i] + ", Got: " + res + ".");
+ }
+ }
+ if (cis.read() != -1) {
+ fail("read() should return -1 at the end of the stream.");
+ }
+ }
+
+ /**
+ * read(byte[] b) method testing. Tests that method returns the correct
+ * value (related to the InputStream) and that it returns -1 at the end of
+ * stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "read",
+ args = {byte[].class}
+ )
+ public void testRead2() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+
+ int expected = data.length;
+ byte[] result = new byte[expected];
+
+ int ind = 0; // index into the data array (to check the got data)
+ int got = cis.read(result); // the number of got bytes
+ while (true) {
+ for (int j = 0; j < got - ind; j++) {
+ if (result[j] != data[ind + j]) {
+ fail("read(byte[] b) returned incorrect data.");
+ }
+ }
+ if (got == expected) {
+ break;
+ } else if (got > expected) {
+ fail("The data returned by read(byte[] b) "
+ + "is larger than expected.");
+ } else {
+ ind = got;
+ got += cis.read(result);
+ }
+ }
+ if (cis.read(result) != -1) {
+ fail("read(byte[] b) should return -1 "
+ + "at the end of the stream.");
+ }
+ }
+
+ /**
+ * read(byte[] b, int off, int len) method testing. Tests that method
+ * returns the correct value (related to the InputStream), that it discards
+ * bytes in the case of null buffer, and that it returns -1 at the end of
+ * stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testRead3() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+
+ int expected = data.length;
+ byte[] result = new byte[expected];
+
+ int skip = 2;
+ int ind = skip; // index into the data array (to check the got data)
+ // should read and discard bytes;
+ cis.read(null, 0, skip);
+ int got = skip + cis.read(result, 0, 1); // the number of got bytes
+ while (true) {
+ for (int j = 0; j < got - ind; j++) {
+ assertEquals("read(byte[] b, int off, int len) "
+ + "returned incorrect data.", result[j], data[ind + j]);
+ }
+ if (got == expected) {
+ break;
+ } else if (got > expected) {
+ fail("The data returned by "
+ + "read(byte[] b, int off, int len) "
+ + "is larger than expected.");
+ } else {
+ ind = got;
+ got += cis.read(result, 0, 3);
+ }
+ }
+ if (cis.read(result, 0, 1) != -1) {
+ fail("read() should return -1 at the end of the stream.");
+ }
+ }
+
+ /**
+ * skip(long n) method testing. Tests that the method correctly skips the
+ * bytes.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "skip",
+ args = {long.class}
+ )
+ public void testSkip() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+ int expected = data.length;
+ byte[] result = new byte[expected];
+
+ int skipped = (int) cis.skip(2);
+ int ind = skipped;
+ int got = skipped + cis.read(result, 0, 1); // the number of got bytes
+ while (true) {
+ for (int j = 0; j < got - ind; j++) {
+ if (result[j] != data[ind + j]) {
+ fail("read(byte[] b, int off, int len) "
+ + "returned incorrect data: Expected "
+ + data[ind + j] + ", got: " + result[j]);
+ }
+ }
+ if (got == expected) {
+ break;
+ } else if (got > expected) {
+ fail("The data returned by "
+ + "read(byte[] b, int off, int len) "
+ + "is larger than expected.");
+ } else {
+ ind = got;
+ got += cis.read(result, 0, 1);
+ }
+ }
+ if ((got = cis.read(result, 0, 1)) != -1) {
+ fail("read() should return -1 at the end of the stream. "
+ + "Output is: " + got + ".");
+ }
+ }
+
+ /**
+ * available() method testing. Tests that the method always return 0.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "available",
+ args = {}
+ )
+ public void testAvailable() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+ assertEquals("The returned by available() method value "
+ + "should be 0.", cis.available(), 0);
+ }
+
+ /**
+ * close() method testing. Tests that the method calls the close()
+ * method of the underlying input stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "close",
+ args = {}
+ )
+ public void testClose() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+ cis.close();
+ assertTrue("The close() method should call the close() method "
+ + "of its underlying input stream.", tis.wasClosed());
+ }
+
+ /**
+ * markSupported() method testing. Tests that mark is not supported.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "markSupported",
+ args = {}
+ )
+ public void testMarkSupported() {
+ byte[] data = new byte[] {-127, -100, -50, -10, -1, 0, 1, 10, 50, 127};
+ TestInputStream tis = new TestInputStream(data);
+ CipherInputStream cis = new CipherInputStream(tis, new NullCipher());
+ assertFalse("The returned by markSupported() method value "
+ + "should be false.", cis.markSupported());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "CipherInputStream",
+ args = {java.io.InputStream.class, javax.crypto.Cipher.class}
+ )
+ public void test_ConstructorLjava_io_InputStreamLjavax_crypto_Cipher () throws
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(new byte[100]);
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ kg.init(56, new SecureRandom());
+ Key key = kg.generateKey();
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, key);
+
+ CipherInputStream cis = new CipherInputStream(bais, c);
+
+ assertNotNull(cis);
+ }
+
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStreamTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStreamTest.java
new file mode 100644
index 0000000..64562bb
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherInputStreamTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.NullCipher;
+
+@TestTargetClass(CipherInputStream.class)
+public class CipherInputStreamTest extends TestCase {
+
+ /**
+ * @tests javax.crypto.CipherInputStream#read(byte[] b, int off, int len)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test. Checks NullPointerException",
+ method = "read",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testReadBII() throws Exception {
+ // Regression for HARMONY-1080
+ CipherInputStream stream = new CipherInputStream(null, new NullCipher());
+ try {
+ stream.read(new byte[1], 1, 0);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.CipherInputStream#close()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test. Checks IllegalStateException",
+ method = "close",
+ args = {}
+ )
+ public void testClose() throws Exception {
+ // Regression for HARMONY-1087
+ try {
+ new CipherInputStream(new ByteArrayInputStream(new byte[] { 1 }),
+ Cipher.getInstance("DES/CBC/PKCS5Padding")).close();
+ fail("IllegalStateException expected!");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ try {
+ new CipherInputStream(new BufferedInputStream((InputStream) null),
+ Cipher.getInstance("DES/CBC/PKCS5Padding")).close();
+ fail("IllegalStateException expected!");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStream1Test.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStream1Test.java
new file mode 100644
index 0000000..237af28
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStream1Test.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.NullCipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.Cipher;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(CipherOutputStream.class)
+/**
+ */
+
+public class CipherOutputStream1Test extends TestCase {
+
+ private static class TestOutputStream extends ByteArrayOutputStream {
+ private boolean closed = false;
+
+ public void close() {
+ closed = true;
+ }
+
+ public boolean wasClosed() {
+ return closed;
+ }
+ }
+
+ /**
+ * CipherOutputStream(OutputStream os) method testing. Tests that
+ * CipherOutputStream uses NullCipher if Cipher is not specified
+ * in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "CipherOutputStream",
+ args = {java.io.OutputStream.class}
+ )
+ public void testCipherOutputStream() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos){};
+ cos.write(data);
+ cos.flush();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("NullCipher should be used " + "if Cipher is not specified.");
+ }
+ }
+
+ /**
+ * write(int b) method testing. Tests that method writes correct values to
+ * the underlying output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "write",
+ args = {int.class}
+ )
+ public void testWrite1() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
+ for (int i = 0; i < data.length; i++) {
+ cos.write(data[i]);
+ }
+ cos.flush();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("CipherOutputStream wrote incorrect data.");
+ }
+ }
+
+ /**
+ * write(byte[] b) method testing. Tests that method writes correct values
+ * to the underlying output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "write",
+ args = {byte[].class}
+ )
+ public void testWrite2() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
+ cos.write(data);
+ cos.flush();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("CipherOutputStream wrote incorrect data.");
+ }
+
+ try {
+ cos.write(null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * write(byte[] b, int off, int len) method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "write",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testWrite3() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
+ for (int i = 0; i < data.length; i++) {
+ cos.write(data, i, 1);
+ }
+ cos.flush();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("CipherOutputStream wrote incorrect data.");
+ }
+ }
+
+ /**
+ * @tests write(byte[] b, int off, int len)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test. IllegalArgumentException checked.",
+ method = "write",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testWrite4() throws Exception {
+ //Regression for HARMONY-758
+ try {
+ new CipherOutputStream(new BufferedOutputStream((OutputStream) null), new NullCipher()).write(new byte[] {0}, 1, Integer.MAX_VALUE);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /**
+ * @tests write(byte[] b, int off, int len)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "write",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testWrite5() throws Exception {
+ //Regression for HARMONY-758
+ Cipher cf = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ NullCipher nc = new NullCipher();
+ CipherOutputStream stream1 = new CipherOutputStream(new BufferedOutputStream((OutputStream) null), nc);
+ CipherOutputStream stream2 = new CipherOutputStream(stream1, cf);
+ CipherOutputStream stream3 = new CipherOutputStream(stream2, nc);
+ stream3.write(new byte[] {0}, 0, 0);
+ //no exception expected
+ }
+
+ /**
+ * flush() method testing. Tests that method flushes the data to the
+ * underlying output stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "flush",
+ args = {}
+ )
+ public void testFlush() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos){};
+ cos.write(data);
+ cos.flush();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("CipherOutputStream did not flush the data.");
+ }
+ }
+
+ /**
+ * close() method testing. Tests that the method calls the close() method of
+ * the underlying input stream.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Can not check IOException.",
+ method = "close",
+ args = {}
+ )
+ public void testClose() throws Exception {
+ byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
+ TestOutputStream tos = new TestOutputStream();
+ CipherOutputStream cos = new CipherOutputStream(tos){};
+ cos.write(data);
+ cos.close();
+ byte[] result = tos.toByteArray();
+ if (!Arrays.equals(result, data)) {
+ fail("CipherOutputStream did not flush the data.");
+ }
+ assertTrue("The close() method should call the close() method "
+ + "of its underlying output stream.", tos.wasClosed());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "CipherOutputStream",
+ args = {java.io.OutputStream.class, javax.crypto.Cipher.class}
+ )
+ public void test_ConstructorLjava_io_OutputStreamLjavax_crypto_Cipher() throws
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ kg.init(56, new SecureRandom());
+ Key key = kg.generateKey();
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, key);
+
+ CipherOutputStream cos = new CipherOutputStream(baos, c);
+
+ assertNotNull(cos);
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStreamTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStreamTest.java
new file mode 100644
index 0000000..aadad1a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherOutputStreamTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.OutputStream;
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+
+@TestTargetClass(CipherOutputStream.class)
+public class CipherOutputStreamTest extends junit.framework.TestCase {
+
+ /**
+ * @tests javax.crypto.CipherOutputStream#close()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test. Checks IllegalStateException.",
+ method = "close",
+ args = {}
+ )
+ public void test_close() throws Exception {
+ // regression test for HARMONY-1139
+ try {
+ new CipherOutputStream((OutputStream) null, Cipher
+ .getInstance("DES/CBC/PKCS5Padding")).close();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ CipherOutputStream ch = new CipherOutputStream((OutputStream) null) {};
+ try {
+ new CipherOutputStream(ch, Cipher
+ .getInstance("DES/CBC/PKCS5Padding")).close();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
new file mode 100644
index 0000000..56e83c6
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherSpiTest.java
@@ -0,0 +1,455 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.AlgorithmParameters;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.CipherSpi;
+import java.nio.ByteBuffer;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(CipherSpi.class)
+/**
+ * Tests for <code>CipherSpi</code> class constructors and methods.
+ *
+ */
+public class CipherSpiTest extends TestCase {
+ class Mock_CipherSpi extends myCipherSpi {
+
+ @Override
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ return super.engineDoFinal(input, inputOffset, inputLen);
+ }
+
+ @Override
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ return super.engineDoFinal(input, inputOffset, inputLen, output, outputOffset);
+ }
+
+ @Override
+ protected int engineGetBlockSize() {
+ return super.engineGetBlockSize();
+ }
+
+ @Override
+ protected byte[] engineGetIV() {
+ return super.engineGetIV();
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ return super.engineGetOutputSize(inputLen);
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return super.engineGetParameters();
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ super.engineInit(opmode, key, random);
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(opmode, key, params, random);
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(opmode, key, params, random);
+ }
+
+ @Override
+ protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+ super.engineSetMode(mode);
+ }
+
+ @Override
+ protected void engineSetPadding(String padding) throws NoSuchPaddingException {
+ super.engineSetPadding(padding);
+ }
+
+ @Override
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ return super.engineUpdate(input, inputOffset, inputLen);
+ }
+
+ @Override
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
+ int outputOffset) throws ShortBufferException {
+ return super.engineUpdate(input, inputOffset, inputLen, output, outputOffset);
+ }
+
+ @Override
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+ return super.engineGetKeySize(key);
+ }
+
+ @Override
+ protected byte[] engineWrap(Key key) throws InvalidKeyException, IllegalBlockSizeException {
+ return super.engineWrap(key);
+ }
+
+ @Override
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
+ throws InvalidKeyException, NoSuchAlgorithmException {
+ return super.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
+ }
+ }
+
+ /**
+ * Test for <code>CipherSpi</code> constructor
+ * Assertion: constructs CipherSpi
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "CipherSpi",
+ args = {}
+ )
+ public void testCipherSpiTests01() throws IllegalBlockSizeException,
+ BadPaddingException, ShortBufferException {
+
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ assertEquals("BlockSize is not 0", cSpi.engineGetBlockSize(), 0);
+ assertEquals("OutputSize is not 0", cSpi.engineGetOutputSize(1), 0);
+ byte[] bb = cSpi.engineGetIV();
+ assertEquals("Length of result byte array is not 0", bb.length, 0);
+ assertNull("Not null result", cSpi.engineGetParameters());
+ byte[] bb1 = new byte[10];
+ byte[] bb2 = new byte[10];
+ bb = cSpi.engineUpdate(bb1, 1, 2);
+ assertEquals("Incorrect result of engineUpdate(byte, int, int)",
+ bb.length, 2);
+ bb = cSpi.engineDoFinal(bb1, 1, 2);
+ assertEquals("Incorrect result of engineDoFinal(byte, int, int)", 2,
+ bb.length);
+ assertEquals(
+ "Incorrect result of engineUpdate(byte, int, int, byte, int)",
+ cSpi.engineUpdate(bb1, 1, 2, bb2, 7), 2);
+ assertEquals(
+ "Incorrect result of engineDoFinal(byte, int, int, byte, int)",
+ 2, cSpi.engineDoFinal(bb1, 1, 2, bb2, 0));
+ }
+
+ /**
+ * Test for <code>engineGetKeySize(Key)</code> method
+ * Assertion: It throws UnsupportedOperationException if it is not overridden
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "engineGetKeySize",
+ args = {java.security.Key.class}
+ )
+ public void testCipherSpi02() throws Exception {
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ try {
+ cSpi.engineGetKeySize(null);
+ fail("UnsupportedOperationException must be thrown");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ /**
+ * Test for <code>engineWrap(Key)</code> method
+ * Assertion: It throws UnsupportedOperationException if it is not overridden
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Functionality not tested.",
+ method = "engineWrap",
+ args = {java.security.Key.class}
+ )
+ public void testCipherSpi03() throws Exception {
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ try {
+ cSpi.engineWrap(null);
+ fail("UnsupportedOperationException must be thrown");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ /**
+ * Test for <code>engineUnwrap(byte[], String, int)</code> method
+ * Assertion: It throws UnsupportedOperationException if it is not overridden
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Functionality not tested.",
+ method = "engineUnwrap",
+ args = {byte[].class, java.lang.String.class, int.class}
+ )
+ public void testCipherSpi04() throws Exception {
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ try {
+ cSpi.engineUnwrap(new byte[0], "", 0);
+ fail("UnsupportedOperationException must be thrown");
+ } catch (UnsupportedOperationException e) {
+ }
+ }
+
+ /**
+ * Test for <code>engineUpdate(ByteBuffer, ByteBuffer)</code> method
+ * Assertions:
+ * throws NullPointerException if one of these buffers is null;
+ * throws ShortBufferException is there is no space in output to hold result
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "engineUpdate",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ )
+ public void testCipherSpi05() throws ShortBufferException {
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ byte[] bb = { (byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 4,
+ (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10 };
+ int pos = 5;
+ int len = bb.length;
+ ByteBuffer bbNull = null;
+ ByteBuffer bb1 = ByteBuffer.allocate(len);
+ bb1.put(bb);
+ bb1.position(0);
+ try {
+ cSpi.engineUpdate(bbNull, bb1);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ try {
+ cSpi.engineUpdate(bb1, bbNull);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ ByteBuffer bb2 = ByteBuffer.allocate(bb.length);
+ bb1.position(len);
+ assertEquals("Incorrect number of stored bytes", 0, cSpi.engineUpdate(
+ bb1, bb2));
+
+ bb1.position(0);
+ bb2.position(len - 2);
+ try {
+ cSpi.engineUpdate(bb1, bb2);
+ fail("ShortBufferException bust be thrown. Output buffer remaining: "
+ .concat(Integer.toString(bb2.remaining())));
+ } catch (ShortBufferException e) {
+ }
+ bb1.position(10);
+ bb2.position(0);
+ assertTrue("Incorrect number of stored bytes", cSpi.engineUpdate(bb1,
+ bb2) > 0);
+ bb1.position(bb.length);
+ cSpi.engineUpdate(bb1, bb2);
+
+ bb1.position(pos);
+ bb2.position(0);
+ int res = cSpi.engineUpdate(bb1, bb2);
+ assertTrue("Incorrect result", res > 0);
+ }
+
+ /**
+ * Test for <code>engineDoFinal(ByteBuffer, ByteBuffer)</code> method
+ * Assertions:
+ * throws NullPointerException if one of these buffers is null;
+ * throws ShortBufferException is there is no space in output to hold result
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "BadPaddingException & IllegalBlockSizeException checking missed.",
+ method = "engineDoFinal",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ )
+ public void testCipherSpi06() throws BadPaddingException,
+ ShortBufferException, IllegalBlockSizeException {
+ Mock_CipherSpi cSpi = new Mock_CipherSpi();
+ int len = 10;
+ byte[] bbuf = new byte[len];
+ for (int i = 0; i < bbuf.length; i++) {
+ bbuf[i] = (byte) i;
+ }
+ ByteBuffer bb1 = ByteBuffer.wrap(bbuf);
+ ByteBuffer bbNull = null;
+ try {
+ cSpi.engineDoFinal(bbNull, bb1);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ try {
+ cSpi.engineDoFinal(bb1, bbNull);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ ByteBuffer bb2 = ByteBuffer.allocate(len);
+ bb1.position(bb1.limit());
+ assertEquals("Incorrect result", 0, cSpi.engineDoFinal(bb1, bb2));
+
+ bb1.position(0);
+ bb2.position(len - 2);
+ try {
+ cSpi.engineDoFinal(bb1, bb2);
+ fail("ShortBufferException must be thrown. Output buffer remaining: "
+ .concat(Integer.toString(bb2.remaining())));
+ } catch (ShortBufferException e) {
+ }
+ int pos = 5;
+ bb1.position(pos);
+ bb2.position(0);
+ assertTrue("Incorrect result", cSpi.engineDoFinal(bb1, bb2) > 0);
+ }
+}
+/**
+ *
+ * Additional class for CipherGeneratorSpi constructor verification
+ */
+
+class myCipherSpi extends CipherSpi {
+ private byte[] initV;
+
+ private static byte[] resV = { (byte) 7, (byte) 6, (byte) 5, (byte) 4,
+ (byte) 3, (byte) 2, (byte) 1, (byte) 0 };
+
+ public myCipherSpi() {
+ this.initV = new byte[0];
+ }
+
+ protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+ }
+
+ protected void engineSetPadding(String padding)
+ throws NoSuchPaddingException {
+ }
+
+ protected int engineGetBlockSize() {
+ return 0;
+ }
+
+ protected int engineGetOutputSize(int inputLen) {
+ return 0;
+ }
+
+ protected byte[] engineGetIV() {
+ return new byte[0];
+ }
+
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ }
+
+ protected void engineInit(int opmode, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ }
+
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ }
+
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ if (initV.length < inputLen) {
+ initV = new byte[inputLen];
+ }
+ for (int i = 0; i < inputLen; i++) {
+ initV[i] = input[inputOffset + i];
+ }
+ return initV;
+ }
+
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException {
+ byte []res = engineUpdate(input, inputOffset, inputLen);
+ int t = res.length;
+ if ((output.length - outputOffset) < t) {
+ throw new ShortBufferException("Update");
+ }
+ for (int i = 0; i < t; i++) {
+ output[i + outputOffset] = initV[i];
+ }
+ return t;
+ }
+
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ if (resV.length > inputLen) {
+ byte[] bb = new byte[inputLen];
+ for (int i = 0; i < inputLen; i++) {
+ bb[i] = resV[i];
+ }
+ return bb;
+ }
+ return resV;
+ }
+
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ byte[] res = engineDoFinal(input, inputOffset, inputLen);
+
+ int t = res.length;
+ if ((output.length - outputOffset) < t) {
+ throw new ShortBufferException("DoFinal");
+ }
+ for (int i = 0; i < t; i++) {
+ output[i + outputOffset] = res[i];
+ }
+ return t;
+ }
+
+
+ protected int engineUpdate(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ return super.engineUpdate(input, output);
+ }
+ protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ return super.engineDoFinal(input, output);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
new file mode 100644
index 0000000..1245eb3
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java
@@ -0,0 +1,1684 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import org.apache.harmony.crypto.tests.support.MyCipher;
+
+import tests.support.resource.Support_Resources;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.IvParameterSpec;
+
+@TestTargetClass(Cipher.class)
+public class CipherTest extends junit.framework.TestCase {
+
+ static Key cipherKey;
+ static final String algorithm = "DESede";
+ static final int keyLen = 168;
+
+ static Key cipherKeyDES;
+ static final String algorithmDES = "DES";
+ static final int keyLenDES = 56;
+
+ static {
+ try {
+ KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+ kg.init(keyLen, new SecureRandom());
+ cipherKey = kg.generateKey();
+
+ kg = KeyGenerator.getInstance(algorithmDES);
+ kg.init(keyLenDES, new SecureRandom());
+ cipherKeyDES = kg.generateKey();
+ } catch (Exception e) {
+ fail("No key " + e);
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getInstance(java.lang.String)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetMode",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetPadding",
+ args = {java.lang.String.class}
+ )
+ })
+ public void test_getInstanceLjava_lang_String() throws Exception {
+ Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
+ assertNotNull("Received a null Cipher instance", cipher);
+
+ try {
+ Cipher.getInstance("WrongAlgorithmName");
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+// RI throws NoSuchAlgorithmException for wrong padding.
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getInstance(java.lang.String,
+ * java.lang.String)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetMode",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetPadding",
+ args = {java.lang.String.class}
+ )
+ })
+ public void test_getInstanceLjava_lang_StringLjava_lang_String()
+ throws Exception {
+
+ Provider[] providers = Security.getProviders("Cipher.DES");
+
+ assertNotNull("No installed providers support Cipher.DES", providers);
+
+ for (int i = 0; i < providers.length; i++) {
+ Cipher cipher = Cipher.getInstance("DES", providers[i].getName());
+ assertNotNull("Cipher.getInstance() returned a null value", cipher);
+
+ // Exception case
+ try {
+ cipher = Cipher.getInstance("DoBeDoBeDo", providers[i]);
+ fail("Should have thrown an NoSuchAlgorithmException");
+ } catch (NoSuchAlgorithmException e) {
+ // Expected
+ }
+ }
+
+ // Exception case
+ try {
+ Cipher.getInstance("DES", (String) null);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // Exception case
+ try {
+ Cipher.getInstance("DES", "IHaveNotBeenConfigured");
+ fail("Should have thrown an NoSuchProviderException");
+ } catch (NoSuchProviderException e) {
+ // Expected
+ }
+// RI throws NoSuchAlgorithmException for wrong padding.
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getInstance(java.lang.String,
+ * java.security.Provider)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetMode",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineSetPadding",
+ args = {java.lang.String.class}
+ )
+ })
+ public void test_getInstanceLjava_lang_StringLjava_security_Provider()
+ throws Exception {
+
+ Provider[] providers = Security.getProviders("Cipher.DES");
+
+ assertNotNull("No installed providers support Cipher.DES", providers);
+
+ for (int i = 0; i < providers.length; i++) {
+ Cipher cipher = Cipher.getInstance("DES", providers[i]);
+ assertNotNull("Cipher.getInstance() returned a null value", cipher);
+ }
+
+ // Exception case
+ try {
+ Cipher.getInstance("DES", (Provider) null);
+ fail("Should have thrown an IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ // Exception case
+ try {
+ Cipher.getInstance("WrongAlg", providers[0]);
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ // Expected
+ }
+// RI throws NoSuchAlgorithmException for wrong padding.
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getProvider()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider() throws Exception {
+
+ Provider[] providers = Security.getProviders("Cipher.AES");
+
+ assertNotNull("No providers support Cipher.AES", providers);
+
+ for (int i = 0; i < providers.length; i++) {
+ Provider provider = providers[i];
+ Cipher cipher = Cipher.getInstance("AES", provider.getName());
+ Provider cipherProvider = cipher.getProvider();
+ assertTrue("Cipher provider is not the same as that "
+ + "provided as parameter to getInstance()", cipherProvider
+ .equals(provider));
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getAlgorithm()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void test_getAlgorithm() throws Exception {
+ final String algorithm = "DESede/CBC/PKCS5Padding";
+
+ Cipher cipher = Cipher.getInstance(algorithm);
+ assertTrue("Cipher algorithm does not match", cipher.getAlgorithm()
+ .equals(algorithm));
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getBlockSize()
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getBlockSize",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineGetBlockSize",
+ args = {}
+ )
+ })
+ public void test_getBlockSize() throws Exception {
+ final String algorithm = "DESede/CBC/PKCS5Padding";
+
+ Cipher cipher = Cipher.getInstance(algorithm);
+ assertEquals("Block size does not match", 8, cipher.getBlockSize());
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#getOutputSize(int)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getOutputSize",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineGetOutputSize",
+ args = {int.class}
+ )
+ })
+ public void test_getOutputSizeI() throws Exception {
+
+ SecureRandom sr = new SecureRandom();
+ Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
+
+ try {
+ cipher.getOutputSize(25);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, sr);
+
+ // A 25-byte input could result in at least 4 8-byte blocks
+ int result = cipher.getOutputSize(25);
+ assertTrue("Output size too small", result > 31);
+
+ // A 8-byte input should result in 2 8-byte blocks
+ result = cipher.getOutputSize(8);
+ assertTrue("Output size too small", result > 15);
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#init(int, java.security.Key)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class}
+ )
+ public void test_initILjava_security_Key() throws Exception {
+ Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey);
+
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#init(int, java.security.Key,
+ * java.security.SecureRandom)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineInit",
+ args = {int.class, java.security.Key.class, java.security.SecureRandom.class}
+ )
+ })
+ public void test_initILjava_security_KeyLjava_security_SecureRandom()
+ throws Exception {
+ SecureRandom sr = new SecureRandom();
+ Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, sr);
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, sr);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#init(int, java.security.Key,
+ * java.security.spec.AlgorithmParameterSpec)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ )
+ public void test_initILjava_security_KeyLjava_security_spec_AlgorithmParameterSpec()
+ throws Exception {
+ SecureRandom sr = new SecureRandom();
+ Cipher cipher = null;
+
+ byte[] iv = null;
+ AlgorithmParameterSpec ap = null;
+
+ iv = new byte[8];
+ sr.nextBytes(iv);
+ ap = new IvParameterSpec(iv);
+
+ cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
+
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap);
+
+ byte[] cipherIV = cipher.getIV();
+
+ assertTrue("IVs differ", Arrays.equals(cipherIV, iv));
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ ap = new RSAKeyGenParameterSpec(10, new BigInteger("10"));
+
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKeyDES, ap);
+ fail("InvalidAlgorithmParameterException expected");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#init(int, java.security.Key,
+ * java.security.spec.AlgorithmParameterSpec,
+ * java.security.SecureRandom)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineInit",
+ args = {int.class, java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ )
+ })
+ public void test_initILjava_security_KeyLjava_security_spec_AlgorithmParameterSpecLjava_security_SecureRandom()
+ throws Exception {
+ SecureRandom sr = new SecureRandom();
+ Cipher cipher = null;
+
+ byte[] iv = null;
+ AlgorithmParameterSpec ap = null;
+
+ iv = new byte[8];
+ sr.nextBytes(iv);
+ ap = new IvParameterSpec(iv);
+
+ cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
+
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap, sr);
+
+ byte[] cipherIV = cipher.getIV();
+
+ assertTrue("IVs differ", Arrays.equals(cipherIV, iv));
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap, sr);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ ap = new RSAKeyGenParameterSpec(10, new BigInteger("10"));
+
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, cipherKeyDES, ap, sr);
+ fail("InvalidAlgorithmParameterException expected");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#update(byte[], int, int)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ )
+ })
+ public void test_update$BII() throws Exception {
+ for (int index = 1; index < 4; index++) {
+ Cipher c = Cipher.getInstance("DESEDE/CBC/PKCS5Padding");
+
+ byte[] keyMaterial = loadBytes("hyts_" + "des-ede3-cbc.test"
+ + index + ".key");
+ DESedeKeySpec keySpec = new DESedeKeySpec(keyMaterial);
+ SecretKeyFactory skf = SecretKeyFactory.getInstance("DESEDE");
+ Key k = skf.generateSecret(keySpec);
+
+ byte[] ivMaterial = loadBytes("hyts_" + "des-ede3-cbc.test" + index
+ + ".iv");
+ IvParameterSpec iv = new IvParameterSpec(ivMaterial);
+
+ c.init(Cipher.DECRYPT_MODE, k, iv);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] input = new byte[256];
+ String resPath = "hyts_" + "des-ede3-cbc.test" + index
+ + ".ciphertext";
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, resPath);
+ InputStream is = Support_Resources.getStream(resPath);
+
+ int bytesRead = is.read(input, 0, 256);
+ while (bytesRead > 0) {
+ byte[] output = c.update(input, 0, bytesRead);
+ if (output != null) {
+ baos.write(output);
+ }
+ bytesRead = is.read(input, 0, 256);
+ }
+
+ byte[] output = c.doFinal();
+ if (output != null) {
+ baos.write(output);
+ }
+
+ byte[] decipheredCipherText = baos.toByteArray();
+ is.close();
+
+ byte[] plaintextBytes = loadBytes("hyts_" + "des-ede3-cbc.test"
+ + index + ".plaintext");
+ assertTrue("Operation produced incorrect results", Arrays.equals(
+ plaintextBytes, decipheredCipherText));
+ }// end for
+
+ Cipher cipher = Cipher.getInstance("DESEDE/CBC/PKCS5Padding");
+ try {
+ cipher.update(new byte[64], 0, 32);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#doFinal()
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {}
+ )
+ public void test_doFinal() throws Exception {
+ for (int index = 1; index < 4; index++) {
+ Cipher c = Cipher.getInstance("DESEDE/CBC/PKCS5Padding");
+
+ byte[] keyMaterial = loadBytes("hyts_" + "des-ede3-cbc.test"
+ + index + ".key");
+ DESedeKeySpec keySpec = new DESedeKeySpec(keyMaterial);
+ SecretKeyFactory skf = SecretKeyFactory.getInstance("DESEDE");
+ Key k = skf.generateSecret(keySpec);
+
+ byte[] ivMaterial = loadBytes("hyts_" + "des-ede3-cbc.test" + index
+ + ".iv");
+ IvParameterSpec iv = new IvParameterSpec(ivMaterial);
+
+ c.init(Cipher.ENCRYPT_MODE, k, iv);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] input = new byte[256];
+ String resPath = "hyts_" + "des-ede3-cbc.test" + index
+ + ".plaintext";
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, resPath);
+ InputStream is = Support_Resources.getStream(resPath);
+
+ int bytesRead = is.read(input, 0, 256);
+ while (bytesRead > 0) {
+ byte[] output = c.update(input, 0, bytesRead);
+ if (output != null) {
+ baos.write(output);
+ }
+ bytesRead = is.read(input, 0, 256);
+ }
+ byte[] output = c.doFinal();
+ if (output != null) {
+ baos.write(output);
+ }
+ byte[] encryptedPlaintext = baos.toByteArray();
+ is.close();
+
+ byte[] cipherText = loadBytes("hyts_" + "des-ede3-cbc.test" + index
+ + ".ciphertext");
+ assertTrue("Operation produced incorrect results", Arrays.equals(
+ encryptedPlaintext, cipherText));
+ }// end for
+
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.update(b, 0, 10, b1, 5);
+ try {
+ c.doFinal();
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(b, 0, 16, b1, 0);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ c.update(b1, 0, 24, b, 0);
+ try {
+ c.doFinal();
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+ }
+
+ private byte[] loadBytes(String resPath) {
+ try {
+ File resources = Support_Resources.createTempFolder();
+ Support_Resources.copyFile(resources, null, resPath);
+ InputStream is = Support_Resources.getStream(resPath);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buff = new byte[1024];
+ int readlen;
+ while ((readlen = is.read(buff)) > 0) {
+ out.write(buff, 0, readlen);
+ }
+ is.close();
+ return out.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getParameters",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineGetParameters",
+ args = {}
+ )
+ })
+ public void testGetParameters() throws Exception {
+ Cipher c = Cipher.getInstance("DES");
+ assertNull(c.getParameters());
+ }
+
+ /*
+ * Class under test for int update(byte[], int, int, byte[], int)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "update",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ })
+ public void testUpdatebyteArrayintintbyteArrayint() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10};
+ byte[] b1 = new byte[6];
+ Cipher c = Cipher.getInstance("DESede");
+
+ try {
+ c.update(b, 0, 10, b1, 5);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ try {
+ c.update(b, 0, 10, b1, 5);
+ fail("ShortBufferException expected");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+
+ b1 = new byte[30];
+ c.update(b, 0, 10, b1, 5);
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[], int)
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineDoFinal",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ })
+ public void testDoFinalbyteArrayintintbyteArrayint() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ try {
+ c.doFinal(b, 0, 10, b1, 5);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(b, 0, 10, b1, 5);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(b, 0, 16, b1, 0);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ try {
+ c.doFinal(b1, 0, 24, new byte[42], 0);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+
+ b1 = new byte[6];
+ c = Cipher.getInstance("DESede");
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ try {
+ c.doFinal(b, 3, 6, b1, 5);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMaxAllowedKeyLength",
+ args = {java.lang.String.class}
+ )
+ public void testGetMaxAllowedKeyLength() throws NoSuchAlgorithmException {
+ try {
+ Cipher.getMaxAllowedKeyLength(null);
+ fail("No expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ Cipher.getMaxAllowedKeyLength("//CBC/PKCS5Paddin");
+ fail("No expected NoSuchAlgorithmException");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ try {
+ Cipher.getMaxAllowedKeyLength("/DES/CBC/PKCS5Paddin/1");
+ fail("No expected NoSuchAlgorithmException");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ assertTrue(Cipher.getMaxAllowedKeyLength("/DES/CBC/PKCS5Paddin") > 0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMaxAllowedParameterSpec",
+ args = {java.lang.String.class}
+ )
+ public void testGetMaxAllowedParameterSpec()
+ throws NoSuchAlgorithmException, Exception {
+ try {
+ Cipher.getMaxAllowedParameterSpec(null);
+ fail("No expected NullPointerException");
+ } catch (NullPointerException e) {
+ }
+ try {
+ Cipher.getMaxAllowedParameterSpec("/DES//PKCS5Paddin");
+ fail("No expected NoSuchAlgorithmException");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ try {
+ Cipher.getMaxAllowedParameterSpec("/DES/CBC/ /1");
+ fail("No expected NoSuchAlgorithmException");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ Cipher.getMaxAllowedParameterSpec("DES/CBC/PKCS5Paddin");
+ Cipher.getMaxAllowedParameterSpec("RSA");
+ }
+
+ /**
+ * @tests javax.crypto.Cipher#Cipher(CipherSpi cipherSpi, Provider provider,
+ * String transformation)
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "Cipher",
+ args = {javax.crypto.CipherSpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void test_Ctor() throws Exception {
+ // Regression for Harmony-1184
+ try {
+ new testCipher(null, null, "s");
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new testCipher(new MyCipher(), null, "s");
+ fail("NullPointerException expected for 'null' provider");
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ try {
+ new testCipher(null, new Provider("qwerty", 1.0, "qwerty") {}, "s");
+ fail("NullPointerException expected for 'null' cipherSpi");
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineDoFinal",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ )
+ })
+ public void test_doFinalLjava_nio_ByteBufferLjava_nio_ByteBuffer ()
+ throws NoSuchAlgorithmException, NoSuchPaddingException,
+ InvalidKeyException, ShortBufferException, BadPaddingException,
+ IllegalBlockSizeException, InvalidAlgorithmParameterException {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ ByteBuffer bInput = ByteBuffer.allocate(64);
+ ByteBuffer bOutput = ByteBuffer.allocate(64);
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 10);
+ try {
+ c.doFinal(bInput, bOutput);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(bInput, bOutput);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput = ByteBuffer.allocate(16);
+ bInput.put(b, 0, 16);
+ c.doFinal(bInput, bOutput);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+ bInput = ByteBuffer.allocate(64);
+
+ try {
+ c.doFinal(bOutput, bInput);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 16);
+ try {
+ c.doFinal(bInput, bInput);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 16);
+ try {
+ c.doFinal(bInput, bOutput.asReadOnlyBuffer());
+ fail("ReadOnlyBufferException expected");
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+
+ bInput.rewind();
+ bInput.put(b, 0, 16);
+ bOutput = ByteBuffer.allocate(8);
+ c = Cipher.getInstance("DESede");
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ try {
+ c.doFinal(bInput, bOutput);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.AlgorithmParameters.class}
+ )
+ public void test_initILjava_security_KeyLjava_security_AlgorithmParameters ()
+ throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+ assertNotNull(c.getParameters());
+
+ try {
+ c.init(Cipher.DECRYPT_MODE, cipherKey, ap);
+ fail("InvalidKeyException e");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, (AlgorithmParameters)null);
+ fail("InvalidAlgorithmParameterException e");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.AlgorithmParameters.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineInit",
+ args = {int.class, java.security.Key.class, java.security.AlgorithmParameters.class, java.security.SecureRandom.class}
+ )
+ })
+ public void test_initILjava_security_KeyLjava_security_AlgorithmParametersLjava_security_SecureRandom ()
+ throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap, sr);
+ assertNotNull(c.getParameters());
+
+ try {
+ c.init(Cipher.DECRYPT_MODE, cipherKey, ap, new SecureRandom());
+ fail("InvalidKeyException e");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, (AlgorithmParameters)null, sr);
+ fail("InvalidAlgorithmParameterException e");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap, (SecureRandom)null);
+ assertNotNull(c.getParameters());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.cert.Certificate.class}
+ )
+ public void test_initILjava_security_cert_Certificate ()
+ throws MalformedURLException, IOException, CertificateException,
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
+
+ /* Certificate creation notes: certificate should be valid 37273 starting
+ * from 13 Nov 2008
+ * If it brcomes invalidated regenerate it using following commands:
+ * 1. openssl genrsa -des3 -out test.key 1024
+ * 2. openssl req -new -key test.key -out test.csr
+ * 3. cp test.key test.key.org
+ * 4. openssl rsa -in test.key.org -out test.key
+ * 5. openssl x509 -req -days 37273 -in test.csr -signkey test.key -out test.cert
+ * */
+
+ String certName = Support_Resources.getURL("test.cert");
+ InputStream is = new URL(certName).openConnection().getInputStream();
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ Certificate cert = cf.generateCertificate(is);
+
+ Cipher c = Cipher.getInstance("RSA");
+
+ c.init(Cipher.ENCRYPT_MODE, cert);
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ try {
+ c.init(Cipher.ENCRYPT_MODE, cert);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.cert.Certificate.class, java.security.SecureRandom.class}
+ )
+ public void test_initILjava_security_cert_Certificate_java_security_SecureRandom ()
+ throws MalformedURLException, IOException, CertificateException,
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
+
+ /* Certificate creation notes: certificate should be valid 37273 starting
+ * from 13 Nov 2008
+ * If it brcomes invalidated regenerate it using following commands:
+ * 1. openssl genrsa -des3 -out test.key 1024
+ * 2. openssl req -new -key test.key -out test.csr
+ * 3. cp test.key test.key.org
+ * 4. openssl rsa -in test.key.org -out test.key
+ * 5. openssl x509 -req -days 37273 -in test.csr -signkey test.key -out test.cert
+ * */
+
+ String certName = Support_Resources.getURL("test.cert");
+ InputStream is = new URL(certName).openConnection().getInputStream();
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ Certificate cert = cf.generateCertificate(is);
+
+ Cipher c = Cipher.getInstance("RSA");
+
+ c.init(Cipher.ENCRYPT_MODE, cert, new SecureRandom());
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ try {
+ c.init(Cipher.ENCRYPT_MODE, cert, new SecureRandom());
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "unwrap",
+ args = {byte[].class, java.lang.String.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineUnwrap",
+ args = {byte[].class, java.lang.String.class, int.class}
+ )
+ })
+ public void test_unwrap$BLjava_lang_StringI () throws NoSuchAlgorithmException,
+ NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
+ IllegalBlockSizeException {
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+
+ c.init(Cipher.WRAP_MODE, cipherKeyDES, ap, sr);
+ byte[] arDES = c.wrap(cipherKeyDES);
+ byte[] ar = c.wrap(cipherKey);
+
+ try {
+ c.unwrap(arDES, "DES", Cipher.SECRET_KEY);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c.init(Cipher.UNWRAP_MODE, cipherKeyDES, ap, sr);
+ assertTrue(cipherKeyDES.equals(c.unwrap(arDES, "DES", Cipher.SECRET_KEY)));
+ assertFalse(cipherKeyDES.equals(c.unwrap(ar, "DES", Cipher.SECRET_KEY)));
+
+ try {
+ c.unwrap(arDES, "RSA38", Cipher.PUBLIC_KEY);
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
+ c.init(Cipher.UNWRAP_MODE, cipherKey, ap, sr);
+ try {
+ c.unwrap(arDES, "DESede", Cipher.SECRET_KEY);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "update",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineUpdate",
+ args = {java.nio.ByteBuffer.class, java.nio.ByteBuffer.class}
+ )
+ })
+ public void test_updateLjava_nio_ByteBufferLjava_nio_ByteBuffer () throws
+ NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
+ ShortBufferException, InvalidAlgorithmParameterException {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ ByteBuffer bInput = ByteBuffer.allocate(256);
+ ByteBuffer bOutput = ByteBuffer.allocate(256);
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 10);
+ bInput.rewind();
+ bOutput.rewind();
+ c.update(bInput, bOutput);
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.update(bInput, bOutput);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput = ByteBuffer.allocate(16);
+ bInput.put(b, 0, 16);
+ bInput.rewind();
+ bOutput.rewind();
+ c.update(bInput, bOutput);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+ bInput = ByteBuffer.allocate(64);
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 16);
+ bInput.rewind();
+ try {
+ c.update(bInput, bInput);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ bInput.put(b, 0, 16);
+ bInput.rewind();
+ bOutput.rewind();
+ try {
+ c.update(bInput, bOutput.asReadOnlyBuffer());
+ fail("ReadOnlyBufferException expected");
+ } catch (ReadOnlyBufferException e) {
+ //expected
+ }
+
+ bInput.rewind();
+ bInput.put(b, 0, 16);
+ bInput.rewind();
+ bOutput = ByteBuffer.allocate(8);
+ c = Cipher.getInstance("DESede");
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ try {
+ c.update(bInput, bOutput);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ class Mock_Key implements Key {
+ public String getAlgorithm() {
+ return null;
+ }
+
+ public byte[] getEncoded() {
+ return null;
+ }
+
+ public String getFormat() {
+ return null;
+ }
+
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "wrap",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineWrap",
+ args = {java.security.Key.class}
+ )
+ })
+ public void test_wrap_java_security_Key () throws NoSuchAlgorithmException,
+ NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
+ InvalidAlgorithmParameterException, MalformedURLException, IOException,
+ CertificateException {
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+
+ c.init(Cipher.WRAP_MODE, cipherKeyDES, ap, sr);
+ assertNotNull(c.wrap(cipherKeyDES));
+ assertNotNull(c.wrap(cipherKey));
+ String certName = Support_Resources.getURL("test.cert");
+ InputStream is = new URL(certName).openConnection().getInputStream();
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ Certificate cert = cf.generateCertificate(is);
+ assertNotNull(c.wrap(cert.getPublicKey()));
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.WRAP_MODE, cipherKeyDES, ap, sr);
+ try {
+ assertNotNull(c.wrap(cert.getPublicKey()));
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap, sr);
+
+ try {
+ c.wrap(cipherKeyDES);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c.init(Cipher.WRAP_MODE, cipherKeyDES, ap, sr);
+ try {
+ c.wrap(new Mock_Key());
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {byte[].class, int.class}
+ )
+ public void test_doFinal$BI() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.update(b, 0, 10);
+ try {
+ c.doFinal(b1, 5);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(b1, 5);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.update(b, 3, 8);
+ c.doFinal(b1, 0);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ c.update(b1, 0, 24);
+ try {
+ c.doFinal(b, 0);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+
+ b1 = new byte[6];
+ c = Cipher.getInstance("DESede");
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ c.update(b, 3, 6);
+ try {
+ c.doFinal(b1, 5);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {byte[].class}
+ )
+ public void test_doFinal$B() throws Exception {
+ byte[] b1 = new byte[32];
+ byte[] bI1 = {1,2,3,4,5,6,7,8,9,10};
+ byte[] bI2 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+ byte[] bI3 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] bI4 = {1,2,3};
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ try {
+ c.doFinal(bI1);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(bI1);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(bI2);
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(bI3, 0, 16, b1, 0);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ try {
+ c.doFinal(b1);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = CipherSpi.class,
+ method = "engineDoFinal",
+ args = {byte[].class, int.class, int.class}
+ )
+ })
+ public void test_doFinal$BII() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ try {
+ c.doFinal(b, 0, 10);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(b, 0, 10);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(b, 0, 16);
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(b, 0, 16, b1, 0);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ try {
+ c.doFinal(b1, 0, 24);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void test_doFinal$BII$B() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ try {
+ c.doFinal(b, 0, 10, b1);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ try {
+ c.doFinal(b, 0, 10, b1);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.doFinal(b, 0, 16, b1);
+
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = new byte[8];
+ sr.nextBytes(iv);
+ AlgorithmParameterSpec ap = new IvParameterSpec(iv);
+
+ c = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ c.init(Cipher.DECRYPT_MODE, cipherKeyDES, ap);
+
+ try {
+ c.doFinal(b1, 0, 24, new byte[42]);
+ fail("BadPaddingException expected");
+ } catch (BadPaddingException e) {
+ //expected
+ }
+
+ b1 = new byte[6];
+ c = Cipher.getInstance("DESede");
+ c.init(Cipher.ENCRYPT_MODE, cipherKey);
+ try {
+ c.doFinal(b, 3, 6, b1);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks exception",
+ method = "update",
+ args = {byte[].class}
+ )
+ public void test_update$B() throws Exception {
+ Cipher cipher = Cipher.getInstance("DESEDE/CBC/PKCS5Padding");
+ try {
+ cipher.update(new byte[64]);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "update",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void test_() throws Exception {
+ byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+ byte[] b1 = new byte[30];
+
+ Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
+
+ try {
+ c.update(b, 0, 10, b1);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ c = Cipher.getInstance("DES/CBC/NoPadding");
+ c.init(Cipher.ENCRYPT_MODE, cipherKeyDES);
+ c.update(b, 0, 16, b1);
+
+ b1 = new byte[3];
+
+ try {
+ c.update(b, 3, 15, b1);
+ fail("No expected ShortBufferException");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+ class testCipher extends Cipher {
+ testCipher(CipherSpi c, Provider p, String s) {
+ super(c, p, s);
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java
new file mode 100644
index 0000000..d78698c
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/EncryptedPrivateKeyInfoTest.java
@@ -0,0 +1,2252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vladimir N. Molotkov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+import java.security.AlgorithmParametersSpi;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.EncryptedPrivateKeyInfo;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import org.apache.harmony.crypto.tests.support.EncryptedPrivateKeyInfoData;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(EncryptedPrivateKeyInfo.class)
+/**
+ * Test for EncryptedPrivateKeyInfo class.
+ *
+ * All binary data for this test were generated using BEA JRockit j2sdk1.4.2_04
+ * (http://www.bea.com) with security providers list extended by Bouncy Castle's
+ * one (http://www.bouncycastle.org)
+ */
+public class EncryptedPrivateKeyInfoTest extends TestCase {
+
+ private static final Provider[] provider = Security.getProviders();
+
+ /**
+ * Algorithm names/transformations used in roundtrip tests of
+ * getKeySpec(...) methods
+ */
+ private static final String[][] algName = {
+ // AES
+ { "AES", null},
+ // {"AES", "AES/ECB/PKCS5Padding"},
+ // {"AES", "AES/CBC/PKCS5Padding"},
+ // {"AES", "AES/OFB/PKCS5Padding"},
+ // {"AES", "AES/CFB/PKCS5Padding"},
+ // {"2.16.840.1.101.3.4.1.1", null},
+ // {"2.16.840.1.101.3.4.1.2", null},
+ // {"2.16.840.1.101.3.4.1.3", null},
+ // {"2.16.840.1.101.3.4.1.4", null},
+ // {"2.16.840.1.101.3.4.1.5", null},
+ // {"2.16.840.1.101.3.4.1.21", null},
+ // {"2.16.840.1.101.3.4.1.22", null},
+ // {"2.16.840.1.101.3.4.1.23", null},
+ // {"2.16.840.1.101.3.4.1.24", null},
+ // {"2.16.840.1.101.3.4.1.25", null},
+ // {"2.16.840.1.101.3.4.1.41", null},
+ // {"2.16.840.1.101.3.4.1.42", null},
+ // {"2.16.840.1.101.3.4.1.43", null},
+ // {"2.16.840.1.101.3.4.1.44", null},
+ // {"2.16.840.1.101.3.4.1.45", null},
+
+ // Blowfish
+ // NO OIDs for Blowfish defined (?)
+ { "Blowfish", null },
+ // {"Blowfish","Blowfish/CBC/PKCS5Padding"},
+ // {"Blowfish","Blowfish/CFB/PKCS5Padding"},
+ // {"Blowfish","Blowfish/OFB/PKCS5Padding"},
+ // {"Blowfish","Blowfish/PCBC/PKCS5Padding"},
+
+ // DES: OIW OIDs only
+ // {iso(1) identified-organization(3) oiw(14) secsig(3)
+ // algorithms(2) desECB(6)}
+ // 1.3.14.3.2.6
+ // 1.3.14.3.2.7
+ // 1.3.14.3.2.8
+ // 1.3.14.3.2.9
+ { "DES", null },
+ // {"DES", "DES/CBC/PKCS5Padding"},
+ // {"DES","DES/CFB/PKCS5Padding"},
+ // {"DES","DES/OFB/PKCS5Padding"},
+ // {"DES","DES/PCBC/PKCS5Padding"},
+
+ // DESede (=TripleDes)
+ //{iso(1) identified-organization(3) oiw(14) secsig(3)
+ // algorithms(2) desEDE(17)}
+ // 1.3.14.3.2.17
+ // {"DESede",null},
+ // {"DESede","DESede/CBC/PKCS5Padding"},
+ // {"DESede","DESede/CFB/PKCS5Padding"},
+ // {"DESede","DESede/OFB/PKCS5Padding"},
+ // {"DESede","DESede/PCBC/PKCS5Padding"},
+ { "TripleDES", null },
+ // {"TripleDES","TripleDES/CBC/PKCS5Padding"},
+ // {"TripleDES","TripleDES/CFB/PKCS5Padding"},
+ // {"TripleDES","TripleDES/OFB/PKCS5Padding"},
+ // {"TripleDES","TripleDES/PCBC/PKCS5Padding"},
+
+ // PBEWith<digest>And<encryption>
+ { "PBEWithMD5AndTripleDES", null },
+ // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-5(5)
+ // pbeWithMD5AndDES-CBC(3)}
+ { "PBEWithMD5AndDES", "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndDES"},
+ { "PBEWithMD5AndDES", null, "PBEWithMD5AndDES"}, { "PBEWithHmacSHA1AndDESede", null },
+ // more oids:
+ // {iso(1) member-body(2) us(840) nortelnetworks(113533) entrust(7)
+ // algorithms(66) pbeWithMD5AndCAST5-CBC(12)}
+ //
+ // also named pbeWithSHAAnd128BitRC4, pbeWithSHA1And128BitRC4:
+ // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12)
+ // pkcs-12-PbeIds(1) pkcs-12-OfflineTransportMode(1)}
+ //
+ // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12)
+ // pkcs-12-PbeIds(1)} +
+ // pbeWithSHAAnd40BitRC4(2) pbeWithSHAAnd3-KeyTripleDES-CBC(3)
+ // pbeWithSHAAnd2-KeyTripleDES-CBC(4) pbeWithSHAAnd128BitRC2-CBC(5)
+ // pbeWithSHAAnd40BitRC2-CBC(6)
+
+ // DiffieHellman
+ { "DiffieHellman", null }, // 1.2.840.10046.2.1
+ // {"DH",null}, // 1.2.840.10046.2.1
+ // {"1.2.840.113549.1.3.1", null},
+
+ { "DSA", null }, // 1.2.840.10040.4.1
+
+ { "RC2", null },
+
+ { "RC4", null },
+
+ { "RC5", null },
+
+ // {"1.2.840.113549.1.12.1.1",null},
+ // {"1.2.840.113549.1.12.1.2",null},
+ { "1.2.840.113549.1.12.1.3", null, "PBEWithSHA1AndDESede"},
+ { "PBEWithSHA1AndDESede", null, "PBEWithSHA1AndDESede"},
+ // {"1.2.840.113549.1.12.1.4",null},
+ // {"1.2.840.113549.1.12.1.5",null},
+ // {"1.2.840.113549.1.12.1.6",null},
+ // {"ELGAMAL/PKCS1", "ELGAMAL/ECB/PKCS1PADDING"},
+ // {"ELGAMAL/PKCS1","ELGAMAL/NONE/PKCS1PADDING"},
+ // {"PBEWITHSHAAND3-KEYTRIPLEDES-CBC", null},
+ // {"PBEWITHSHA1ANDDESEDE", null},
+ // {"PBEWithSHAAnd3KeyTripleDES",null},
+ // {"PBEWITHSHAAND3-KEYTRIPLEDES-CBC",null},
+ //
+ // {"RC5-32",null},
+ //
+ // {"RSA/1", "RSA/1/PKCS1PADDING"},
+ // {"RSA/2", "RSA/2/PKCS1PADDING"},
+ // {"RSA/ISO9796-1", "RSA/ECB/ISO9796-1PADDING"},
+ // {"RSA", "RSA/ECB/NOPADDING"},
+ // {"RSA/OAEP", "RSA/ECB/OAEPPADDING"},
+ // {"RSA/PKCS1", "RSA/ECB/PKCS1PADDING"},
+ // {"RSA/ISO9796-1", "RSA/NONE/ISO9796-1PADDING"},
+ // {"RSA", "RSA/NONE/NOPADDING"},
+ // {"RSA/OAEP", "RSA/NONE/OAEPPADDING"},
+ // {"RSA/PKCS1", "RSA/NONE/PKCS1PADDING"},
+ // {"RSA",null}, // 1.2.840.113549.1.1.1
+ // {"1.2.840.113549.1.1.1", null},
+ };
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgName",
+ args = {}
+ )
+ public void test_getAlgName () {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ try {
+ // generate test data
+ TestDataGenerator g = new TestDataGenerator(algName[i][0],
+ algName[i][1], privateKeyInfoDamaged, null);
+
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ // call methods under test
+ if (algName[i].length == 3) {
+ assertTrue(epki.getAlgName().compareTo(algName[i][2]) == 0);
+ }
+
+ performed = true;
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #1 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
+ * Test preconditions: valid parameters passed <br>
+ * Expected: must pass without any exceptions
+ *
+ * @throws IOException
+ * @throws NoSuchAlgorithmException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray1() throws Exception {
+ new EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DH"));
+ }
+
+ /**
+ * Test #2 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: <code>NullPointerException</code> if encoding is
+ * <code>null</code><br>
+ * Test preconditions: <code>null</code> passed as a parameter <br>
+ * Expected: <code>NullPointerException</code>
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray2()
+ throws IOException {
+ try {
+ new EncryptedPrivateKeyInfo(null);
+ fail(getName() + ": NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+ }
+
+ /**
+ * Test #3 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: <code>IOException</code> if encoding is wrong <br>
+ * Test preconditions: wrong encoding passed as a parameter <br>
+ * Expected: <code>IOException</code>
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray3() {
+ try {
+ new EncryptedPrivateKeyInfo(new byte[0]);
+ fail(getName() + ": IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+ }
+
+ /**
+ * Test #4 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: <code>IOException</code> if encoding is wrong <br>
+ * Test preconditions: wrong encoding passed as a parameter <br>
+ * Expected: <code>IOException</code>
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray4() {
+ try {
+ new EncryptedPrivateKeyInfo(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10 });
+ fail(getName() + ": IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+ }
+
+ /**
+ * Test #5 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: <code>IOException</code> if encoding is wrong <br>
+ * Test preconditions: wrong encoding passed as a parameter <br>
+ * Expected: <code>IOException</code>
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray5() throws Exception {
+ byte[] enc = null;
+ try {
+ // 1: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+
+ // ... and corrupt it (set wrong alg OID length)
+ enc[9] = (byte) 6;
+
+ new EncryptedPrivateKeyInfo(enc);
+ fail(getName() + "(1): IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+
+ try {
+ // 2: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ // ... and corrupt it (set wrong encrypted data tag)
+ enc[307] = (byte) 6;
+ new EncryptedPrivateKeyInfo(enc);
+ fail(getName() + "(2): IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+
+ try {
+ // 3: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ // ... and corrupt it (set wrong encrypted data length)
+ enc[310] = (byte) 1;
+ new EncryptedPrivateKeyInfo(enc);
+ fail(getName() + "(3): IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+
+ try {
+ // 4: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ // ... and corrupt it (set wrong tag for alg params sequence)
+ enc[17] = (byte) 0x29;
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(enc);
+
+ if (epki.getAlgParameters() == null) {
+ // This kind of encoding corruption can
+ // be only determined while AlgorithmParameters
+ // initialization BUT No AlgorithmParameters instance
+ // available for algName0[i][0].
+ // So just skip this sub test
+ } else {
+ fail(getName() + "(4): IOException has not been thrown");
+ }
+
+ } catch (IOException ok) {
+ }
+
+ try {
+ // 5: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ // ... and corrupt it (set wrong length for alg params sequence)
+ enc[20] = (byte) 0x1d;
+ new EncryptedPrivateKeyInfo(enc);
+ fail(getName() + "(5): IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+
+ try {
+ // 6: get valid encoding
+ enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ // ... and corrupt it (set wrong length for alg params sequence)
+ enc[20] = (byte) 0x1f;
+ new EncryptedPrivateKeyInfo(enc);
+ fail(getName() + "(6): IOException has not been thrown");
+ } catch (IOException ok) {
+ }
+ }
+
+ /**
+ * Test #6 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
+ * <br>
+ * Assertion: byte array is copied to prevent subsequent modification <br>
+ * Test preconditions: valid array passed then modified <br>
+ * Expected: getEncoded(), invoked after above modification, must return
+ * array as it was before the modification
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfobyteArray6() throws Exception {
+ byte[] encoded = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DSA");
+ byte[] encodedCopy = encoded.clone();
+ // pass valid array
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(encodedCopy);
+ // modify array passed
+ encodedCopy[9] = (byte) 6;
+ // check that internal state has not been affected
+ assertTrue(Arrays.equals(encoded, epki.getEncoded()));
+ }
+
+ /**
+ * Test #1 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
+ * Test preconditions: valid parameters passed <br>
+ * Expected: must pass without any exceptions
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray1() {
+ boolean performed = false;
+
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+ performed = true;
+ } catch (NoSuchAlgorithmException allowed) {
+ }
+ }
+
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #2 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: <code>NoSuchAlgorithmException</code>- if the specified
+ * algorithm is not supported <br>
+ * Test preconditions: pass nonexistent algorithm name <br>
+ * Expected: <code>NoSuchAlgorithmException</code>
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray2() {
+ try {
+ new EncryptedPrivateKeyInfo("bla-bla",
+ EncryptedPrivateKeyInfoData.encryptedData);
+ fail(getName() + ": NoSuchAlgorithmException has not been thrown");
+ } catch (NoSuchAlgorithmException ok) {
+ }
+
+ try {
+ new EncryptedPrivateKeyInfo("",
+ EncryptedPrivateKeyInfoData.encryptedData);
+ fail(getName() + ": NoSuchAlgorithmException has not been thrown");
+ } catch (NoSuchAlgorithmException ok) {
+ }
+ }
+
+ /**
+ * Test #3 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: <code>NullPointerException</code>- if the specified
+ * algorithm or encrypted data is <code>null</code><br>
+ * Test preconditions: pass <code>null</code> as algorithm name then as
+ * encrypted data <br>
+ * Expected: <code>NullPointerException</code> in both cases
+ *
+ * @throws NoSuchAlgorithmException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray3()
+ throws NoSuchAlgorithmException {
+ // pass null as name
+ try {
+ new EncryptedPrivateKeyInfo((String) null,
+ EncryptedPrivateKeyInfoData.encryptedData);
+ fail(getName() + ": NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+
+ // pass null as encrypted data
+ try {
+ new EncryptedPrivateKeyInfo("DSA", null);
+ fail(getName() + ": NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+ }
+
+ /**
+ * Test #4 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: <code>IllegalArgumentException</code>- if encrypted data is
+ * empty, i.e. 0-length <br>
+ * Test preconditions: pass empty encrypted data <br>
+ * Expected: <code>IllegalArgumentException</code>
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray4()
+ throws Exception {
+ try {
+ new EncryptedPrivateKeyInfo("DSA", new byte[] {});
+ fail(getName() + ": IllegalArgumentException has not been thrown");
+ } catch (IllegalArgumentException ok) {
+ }
+ }
+
+ /**
+ * Test #5 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: byte array is copied to prevent subsequent modification <br>
+ * Test preconditions: valid array passed then modified <br>
+ * Expected: getEncryptedData(), invoked after above modification, must
+ * return array as it was before the modification
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray5()
+ throws Exception {
+ byte[] encryptedDataCopy = EncryptedPrivateKeyInfoData.encryptedData
+ .clone();
+ // pass valid array
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo("DSA",
+ encryptedDataCopy);
+ // modify array passed
+ encryptedDataCopy[0] = (byte) 6;
+ // check that internal state has not been affected
+ assertTrue(Arrays.equals(EncryptedPrivateKeyInfoData.encryptedData,
+ epki.getEncryptedData()));
+ }
+
+ /**
+ * @tests javax/crypto/EncryptedPrivateKeyInfo(String, byte[])
+ * Checks exception order
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for EncryptedPrivateKeyInfo(String, byte[]) constructor.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.lang.String.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoStringbyteArray6() {
+ //Regression for HARMONY-768
+ try {
+ new EncryptedPrivateKeyInfo("0", new byte[] {});
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+ }
+
+ class Mock_AlgorithmParameters extends AlgorithmParameters {
+ protected Mock_AlgorithmParameters(AlgorithmParametersSpi paramSpi, Provider provider, String algorithm) {
+ super(paramSpi, provider, algorithm);
+ }
+ }
+
+/**
+ * Test #1 for
+ * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
+ * </code>
+ * constructor <br>
+ * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
+ * Test preconditions: valid parameters passed <br>
+ * Expected: must pass without any exceptions
+ *
+ * @throws IOException
+ * @throws NoSuchAlgorithmException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Functionality checked. NoSuchAlgorithmException should be tested for complete tests subset.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.security.AlgorithmParameters.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray1()
+ throws IOException, NoSuchAlgorithmException {
+ AlgorithmParameters ap = null;
+
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ ap = AlgorithmParameters
+ .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ new EncryptedPrivateKeyInfo(ap,
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+
+ ap = new Mock_AlgorithmParameters(null, null, "Wrong alg name");
+
+ try {
+ new EncryptedPrivateKeyInfo(ap,
+ EncryptedPrivateKeyInfoData.encryptedData);
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+ }
+
+ /**
+ * Test #2 for
+ * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
+ * </code>
+ * constructor <br>
+ * Assertion: <code>NullPointerException</code>- if the specified
+ * algorithm parameters or encrypted data is <code>null</code><br>
+ * Test preconditions: pass <code>null</code> as algorithm parameters then
+ * as encrypted data <br>
+ * Expected: <code>NullPointerException</code> in both cases
+ *
+ * @throws NoSuchAlgorithmException
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "NullPointerException checked.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.security.AlgorithmParameters.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray2()
+ throws NoSuchAlgorithmException, IOException {
+ // 1: pass null as AlgorithmParameters
+ try {
+ new EncryptedPrivateKeyInfo((AlgorithmParameters) null,
+ EncryptedPrivateKeyInfoData.encryptedData);
+ fail(getName() + ": NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+
+ // 2: pass null as encrypted data
+ try {
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
+ new EncryptedPrivateKeyInfo(ap, null);
+ fail(getName() + ": NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+ }
+
+ /**
+ * Test #3 for
+ * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
+ * </code>
+ * constructor <br>
+ * Assertion: <code>IllegalArgumentException</code>- if encrypted data is
+ * empty, i.e. 0-length <br>
+ * Test preconditions: pass empty encrypted data <br>
+ * Expected: <code>IllegalArgumentException</code>
+ *
+ * @throws NoSuchAlgorithmException
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "IllegalArgumentException checked.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.security.AlgorithmParameters.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray3()
+ throws Exception {
+ try {
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
+
+ new EncryptedPrivateKeyInfo(ap, new byte[] {});
+ fail(getName() + ": IllegalArgumentException has not been thrown");
+
+ } catch (IllegalArgumentException ok) {
+ }
+ }
+
+ /**
+ * Test #4 for
+ * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
+ * </code>
+ * constructor <br>
+ * Assertion: byte array is copied to prevent subsequent modification <br>
+ * Test preconditions: valid array passed then modified <br>
+ * Expected: getEncryptedData(), invoked after above modification, must
+ * return array as it was before the modification
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Functionality checked.",
+ method = "EncryptedPrivateKeyInfo",
+ args = {java.security.AlgorithmParameters.class, byte[].class}
+ )
+ public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray4()
+ throws Exception {
+ AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
+
+ byte[] encryptedDataCopy = EncryptedPrivateKeyInfoData.encryptedData.clone();
+ // pass valid array
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
+ encryptedDataCopy);
+
+ // modify array passed
+ encryptedDataCopy[0] = (byte) 6;
+
+ // check that internal state has not been affected
+ assertTrue(Arrays.equals(EncryptedPrivateKeyInfoData.encryptedData,
+ epki.getEncryptedData()));
+ }
+
+ /**
+ * Test #1 for <code>getAlgParameters()</code> method <br>
+ * Assertion: returns the algorithm parameters <br>
+ * Test preconditions: test object created using ctor which takes encoded
+ * form as the only parameter; encoded form passed contains algorithm
+ * parameters encoding <br>
+ * Expected: corresponding algorithm parameters must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getAlgParameters method.",
+ method = "getAlgParameters",
+ args = {}
+ )
+ public final void testGetAlgParameters01() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ AlgorithmParameters apar = epki.getAlgParameters();
+ if (apar == null) {
+ continue;
+ }
+
+ // check that method under test returns
+ // parameters with the same encoded form
+ assertTrue(Arrays
+ .equals(
+ EncryptedPrivateKeyInfoData
+ .getParametersEncoding(EncryptedPrivateKeyInfoData.algName0[i][0]),
+ apar.getEncoded()));
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getAlgParameters method.",
+ method = "getAlgParameters",
+ args = {}
+ )
+ public final void testGetAlgParameters01_01() throws Exception {
+ byte[] validEncodingWithUnknownAlgOID = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding("DH");
+ // correct oid value
+ validEncodingWithUnknownAlgOID[18] = 0;
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ validEncodingWithUnknownAlgOID);
+
+ assertNull(epki.getAlgParameters());
+ }
+
+ /**
+ * Test #2 for <code>getAlgParameters()</code> method <br>
+ * Assertion: returns the algorithm parameters <br>
+ * Test preconditions: test object created using ctor which takes encoded
+ * form as the only parameter; encoded form passed does not contain
+ * algorithm parameters encoding <br>
+ * Expected: <code>null</code> must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getAlgParameters method.",
+ method = "getAlgParameters",
+ args = {}
+ )
+ public final void testGetAlgParameters02() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ false));
+
+ // check that method under test returns null
+ assertNull(epki.getAlgParameters());
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #3 for <code>getAlgParameters()</code> method <br>
+ * Assertion: returns the algorithm parameters <br>
+ * Test #6 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
+ * constructor <br>
+ * Assertion: ...This constructor will use null as the value of the
+ * algorithm parameters. <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: <code>null</code> must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getAlgParameters method.",
+ method = "getAlgParameters",
+ args = {}
+ )
+ public final void testGetAlgParameters03() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns null
+ // for object constructed in such a way
+ assertNull(epki.getAlgParameters());
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #4 for <code>getAlgParameters()</code> method <br>
+ * Assertion: returns the algorithm parameters <br>
+ * Test preconditions: test object created using ctor which takes
+ * AlgorithmParameters and encrypted data as a parameters; <br>
+ * Expected: the same algorithm parameters as ones passed to the ctor must be
+ * returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getAlgParameters method.",
+ method = "getAlgParameters",
+ args = {}
+ )
+ public final void testGetAlgParameters04() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ AlgorithmParameters ap = AlgorithmParameters
+ .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
+ // use pregenerated AlgorithmParameters encodings
+ ap
+ .init(EncryptedPrivateKeyInfoData
+ .getParametersEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // the same parameters instance
+ assertSame(ap, epki.getAlgParameters());
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #1 for <code>getEncryptedData()</code> method <br>
+ * Assertion: returns the encrypted data <br>
+ * Test preconditions: test object created using ctor which takes encoded
+ * form as the only parameter; encoded form passed contains encrypted data
+ * <br>
+ * Expected: the equivalent encrypted data must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getEncryptedData method.",
+ method = "getEncryptedData",
+ args = {}
+ )
+ public final void testGetEncryptedData01() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ // check that method under test returns
+ // valid encrypted data
+ assertTrue(Arrays.equals(
+ EncryptedPrivateKeyInfoData.encryptedData, epki
+ .getEncryptedData()));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #2 for <code>getEncryptedData()</code> method <br>
+ * Assertion: returns the encrypted data <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: the equivalent encrypted data must be returned
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getEncryptedData method.",
+ method = "getEncryptedData",
+ args = {}
+ )
+ public final void testGetEncryptedData02() {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // valid encrypted data
+ assertTrue(Arrays.equals(
+ EncryptedPrivateKeyInfoData.encryptedData, epki
+ .getEncryptedData()));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #3 for <code>getEncryptedData()</code> method <br>
+ * Assertion: returns the encrypted data <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * parameters and encrypted data as a parameters <br>
+ * Expected: the equivalent encrypted data must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getEncryptedData method.",
+ method = "getEncryptedData",
+ args = {}
+ )
+ public final void testGetEncryptedData03() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ AlgorithmParameters ap = AlgorithmParameters
+ .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // valid encrypted data
+ assertTrue(Arrays.equals(
+ EncryptedPrivateKeyInfoData.encryptedData, epki
+ .getEncryptedData()));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #4 for <code>getEncryptedData()</code> method <br>
+ * Assertion: returns a new array each time this method is called <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: refs to encrypted data byte array passed to the ctor and
+ * returned by the method under test must be different
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getEncryptedData method.",
+ method = "getEncryptedData",
+ args = {}
+ )
+ public final void testGetEncryptedData04() {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // new array each time
+ byte[] ecd1 = epki.getEncryptedData();
+ byte[] ecd2 = epki.getEncryptedData();
+ assertNotSame(EncryptedPrivateKeyInfoData.encryptedData, ecd1);
+ assertNotSame(EncryptedPrivateKeyInfoData.encryptedData, ecd2);
+ assertNotSame(ecd1, ecd2);
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #1 for <code>getEncoded()</code> method <br>
+ * Assertion: returns the ASN.1 encoding of this object <br>
+ * Test preconditions: test object created using ctor which takes encoded
+ * form as the only parameter <br>
+ * Expected: equivalent encoded form must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check IOException",
+ method = "getEncoded",
+ args = {}
+ )
+ public final void testGetEncoded01() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ byte[] enc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]);
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(enc);
+
+ // check that method under test returns
+ // valid encoded form
+ assertTrue(Arrays.equals(enc, epki.getEncoded()));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #2 for <code>getEncoded()</code> method <br>
+ * Assertion: returns the ASN.1 encoding of this object <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: equivalent encoded form (without alg params) must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check IOException",
+ method = "getEncoded",
+ args = {}
+ )
+ public final void testGetEncoded02() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // valid encoded form
+ byte[] refEnc = EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ false);
+ // System.out.println(Array.toString(refEnc, " "));
+ byte[] actEnc = epki.getEncoded();
+ // System.out.println(Array.toString(actEnc, " "));
+ assertTrue(Arrays.equals(refEnc, actEnc));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #3 for <code>getEncoded()</code> method <br>
+ * Assertion: returns the ASN.1 encoding of this object <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: equivalent encoded form (without alg params) must be returned
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check IOException",
+ method = "getEncoded",
+ args = {}
+ )
+ public final void testGetEncoded03() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ AlgorithmParameters ap = AlgorithmParameters
+ .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
+ // use pregenerated AlgorithmParameters encodings
+ ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]));
+
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // valid encoded form
+ assertTrue(Arrays.equals(
+ EncryptedPrivateKeyInfoData
+ .getValidEncryptedPrivateKeyInfoEncoding(
+ EncryptedPrivateKeyInfoData.algName0[i][0]),
+ epki.getEncoded()));
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Test #4 for <code>getEncoded()</code> method <br>
+ * Assertion: returns a new array each time this method is called <br>
+ * Test preconditions: test object created using ctor which takes algorithm
+ * name and encrypted data as a parameters <br>
+ * Expected: several refs to byte array returned by the method under test
+ * must be different
+ *
+ * @throws IOException
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check IOException",
+ method = "getEncoded",
+ args = {}
+ )
+ public final void testGetEncoded04() throws IOException {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ // check that method under test returns
+ // new array each time
+ byte[] ec1 = epki.getEncoded();
+ byte[] ec2 = epki.getEncoded();
+ byte[] ec3 = epki.getEncoded();
+ assertNotSame(ec1, ec2);
+ assertNotSame(ec2, ec3);
+ assertNotSame(ec1, ec3);
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getKeySpec method.",
+ method = "getKeySpec",
+ args = {javax.crypto.Cipher.class}
+ )
+ public final void testGetKeySpecCipher01() {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ try {
+
+ // check that method under test throws NPE
+ epki.getKeySpec((Cipher) null);
+ fail(getName() + "NullPointerException has not been thrown");
+
+ } catch (NullPointerException ok) {
+ } catch (InvalidKeySpecException e) {
+ fail(getName() + "Unexpected exception: " + e);
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains valid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getKeySpec method.",
+ method = "getKeySpec",
+ args = {javax.crypto.Cipher.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecCipher01() {
+ boolean performed = false;
+
+ for (int i = 0; i < algName.length; i++) {
+ try {
+ // generate test data
+ TestDataGenerator g = new TestDataGenerator(algName[i][0],
+ algName[i][1], privateKeyInfo, null);
+
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ // call methods under test
+ try {
+
+ PKCS8EncodedKeySpec eks = epki.getKeySpec(g.c());
+
+ if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
+ fail(algName[i][0] + " != " + algName[i][1]);
+ }
+ } catch (InvalidKeySpecException e) {
+ fail(algName[i][0] + ", " + algName[i][1] + e + "\n");
+ }
+ performed = true;
+
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ } catch (NoSuchAlgorithmException allowed) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains invalid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getKeySpec method.",
+ method = "getKeySpec",
+ args = {javax.crypto.Cipher.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecCipher02() {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ try {
+ // generate test data
+ TestDataGenerator g = new TestDataGenerator(algName[i][0],
+ algName[i][1], privateKeyInfoDamaged, null);
+
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ // call methods under test
+ try {
+ epki.getKeySpec(g.c());
+
+ // must not get here because decrypted data does
+ // not represent valid PKCS8 encoding
+ fail(algName[i][0] + ", " + algName[i][1]);
+ } catch (InvalidKeySpecException ok) {
+ }
+
+ performed = true;
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class}
+ )
+ public final void testGetKeySpecKey01() {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ try {
+
+ // check that method under test throws NPE
+ epki.getKeySpec((Key) null);
+ fail(getName() + "NullPointerException has not been thrown");
+
+ } catch (NullPointerException ok) {
+ } catch (InvalidKeyException e) {
+ fail(getName() + "Unexpected exception: " + e);
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains valid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKey01() {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ try {
+ // generate test data
+ TestDataGenerator g = new TestDataGenerator(algName[i][0],
+ algName[i][1], privateKeyInfo, null);
+
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ try {
+ PKCS8EncodedKeySpec eks = epki
+ .getKeySpec(g.pubK() == null ? g.k() : g.pubK());
+
+ if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
+ fail(algName[i][0] + " != " + algName[i][1]);
+ }
+ } catch (InvalidKeyException e) {
+ fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
+ }
+
+ performed = true;
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains invalid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKey02() {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ try {
+ // generate test data
+ TestDataGenerator g = new TestDataGenerator(algName[i][0],
+ algName[i][1], privateKeyInfoDamaged, null);
+
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ try {
+ epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK());
+ fail(algName[i][0] + ", " + algName[i][1]);
+ } catch (InvalidKeyException e) {
+ }
+
+ performed = true;
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "NoSuchAlgorithmException can not be checking",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.lang.String.class}
+ )
+ public final void testGetKeySpecKeyString01() throws Exception {
+ boolean performed = false;
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ try {
+ // check that method under test throws NPE
+ epki.getKeySpec((Key) null, "SomeProviderName");
+ fail(getName() + "NullPointerException has not been thrown");
+
+ } catch (NullPointerException ok) {
+ }
+
+ try {
+ epki.getKeySpec(new Key() {
+ public String getAlgorithm() {
+ return "alg";
+ }
+
+ public String getFormat() {
+ return "fmt";
+ }
+
+ public byte[] getEncoded() {
+ return new byte[] {};
+ }
+ }, "StrangeProviderName");
+ fail(getName() + "NoSuchProviderException has not been thrown");
+ } catch (NoSuchProviderException ok) {
+ //expected
+ }
+
+ try {
+
+ // check that method under test throws NPE
+ epki.getKeySpec(new Key() {
+ public String getAlgorithm() {
+ return "alg";
+ }
+
+ public String getFormat() {
+ return "fmt";
+ }
+
+ public byte[] getEncoded() {
+ return new byte[] {};
+ }
+ }, (String) null);
+
+ fail(getName() + "NullPointerException has not been thrown");
+
+ } catch (NullPointerException ok) {
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains valid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "In subset missed NoSuchProviderException & NoSuchAlgorithmException checking",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.lang.String.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKeyString01() throws Exception {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ for (int l = 0; l < provider.length; l++) {
+ if (provider[l] == null) {
+ continue;
+ }
+ TestDataGenerator g;
+ try {
+ // generate test data
+ g = new TestDataGenerator(algName[i][0], algName[i][1],
+ privateKeyInfo, provider[l]);
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ continue;
+ }
+
+ try {
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g
+ .ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+ try {
+
+ PKCS8EncodedKeySpec eks = epki.getKeySpec(
+ g.pubK() == null ? g.k() : g.pubK(),
+ provider[l].getName());
+
+ if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
+ fail(algName[i][0] + " != " + algName[i][1]);
+ }
+ } catch (InvalidKeyException e) {
+ fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains invalid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "In subset missed NoSuchProviderException & NoSuchAlgorithmException checking",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.lang.String.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKeyString02() throws Exception {
+ boolean performed = false;
+ for (int i = 0; i < algName.length; i++) {
+ for (int l = 0; l < provider.length; l++) {
+ if (provider[l] == null) {
+ continue;
+ }
+ TestDataGenerator g;
+ try {
+ // generate test data
+ g = new TestDataGenerator(algName[i][0], algName[i][1],
+ privateKeyInfoDamaged, provider[l]);
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ continue;
+ }
+
+ try {
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g
+ .ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+
+ try {
+
+ epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK(),
+ provider[l].getName());
+
+ fail(algName[i][0] + ", " + algName[i][1]);
+
+ } catch (InvalidKeyException e) {
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.security.Provider.class}
+ )
+ public final void testGetKeySpecKeyProvider01() throws Exception {
+ boolean performed = false;
+
+ for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
+ try {
+ EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
+ EncryptedPrivateKeyInfoData.algName0[i][0],
+ EncryptedPrivateKeyInfoData.encryptedData);
+
+ try {
+
+ // check that method under test throws NPE
+ epki.getKeySpec((Key) null, (Provider) null);
+ fail(getName() + "NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+
+ try {
+
+ // check that method under test throws NPE
+ epki.getKeySpec(new Key() {
+ public String getAlgorithm() {
+ return "alg";
+ }
+
+ public String getFormat() {
+ return "fmt";
+ }
+
+ public byte[] getEncoded() {
+ return new byte[] {};
+ }
+ }, (Provider) null);
+
+ fail(getName() + "NullPointerException has not been thrown");
+ } catch (NullPointerException ok) {
+ }
+
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains valid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.security.Provider.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKeyProvider01() {
+ boolean performed = false;
+
+ for (int i = 0; i < algName.length; i++) {
+ for (int l = 0; l < provider.length; l++) {
+ if (provider[l] == null) {
+ continue;
+ }
+ TestDataGenerator g;
+ try {
+ // generate test data
+ g = new TestDataGenerator(algName[i][0], algName[i][1],
+ privateKeyInfo, provider[l]);
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ continue;
+ }
+ try {
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g
+ .ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+ try {
+
+ PKCS8EncodedKeySpec eks = epki.getKeySpec(
+ g.pubK() == null ? g.k() : g.pubK(),
+ provider[l]);
+
+ if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
+ fail(algName[i][0] + " != " + algName[i][1]);
+ }
+ } catch (InvalidKeyException e) {
+ fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
+ }
+ performed = true;
+
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ /**
+ * Encrypted data contains invalid PKCS8 key info encoding
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Can not check NoSuchAlgorithmException",
+ method = "getKeySpec",
+ args = {java.security.Key.class, java.security.Provider.class}
+ )
+ public final void test_ROUNDTRIP_GetKeySpecKeyProvider02() {
+ boolean performed = false;
+
+ for (int i = 0; i < algName.length; i++) {
+ for (int l = 0; l < provider.length; l++) {
+ if (provider[l] == null) {
+ continue;
+ }
+ TestDataGenerator g;
+ try {
+ // generate test data
+ g = new TestDataGenerator(algName[i][0], algName[i][1],
+ privateKeyInfoDamaged, provider[l]);
+ } catch (TestDataGenerator.AllowedFailure allowedFailure) {
+ continue;
+ }
+
+ try {
+ // create test object
+ EncryptedPrivateKeyInfo epki;
+ if (g.ap() == null) {
+ epki = new EncryptedPrivateKeyInfo(algName[i][0], g
+ .ct());
+ } else {
+ epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
+ }
+ try {
+
+ epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK(),
+ provider[l]);
+
+ fail(algName[i][0] + ", " + algName[i][1]);
+
+ } catch (InvalidKeyException e) {
+ }
+ performed = true;
+ } catch (NoSuchAlgorithmException allowedFailure) {
+ }
+ }
+ }
+ assertTrue("Test not performed", performed);
+ }
+
+ public static class TestDataGenerator {
+
+ public static class AllowedFailure extends Exception {
+ AllowedFailure(String msg) {
+ super(msg);
+ }
+ }
+
+ private Cipher c = null;
+
+ private Key k = null, pubK = null;
+
+ private AlgorithmParameters ap = null;
+
+ byte[] ct;
+
+ public TestDataGenerator(String algName, String transformation,
+ byte[] privateKeyInfo, Provider provider) throws AllowedFailure {
+ try {
+ c = (provider == null) ? Cipher
+ .getInstance(transformation != null ? transformation
+ : algName) : Cipher.getInstance(
+ transformation != null ? transformation : algName,
+ provider);
+ } catch (NoSuchAlgorithmException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (NoSuchPaddingException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+
+ try {
+ KeyGenerator kg = (provider == null) ? KeyGenerator
+ .getInstance(algName) : KeyGenerator.getInstance(
+ algName, provider);
+ k = kg.generateKey();
+ } catch (NoSuchAlgorithmException e) {
+ }
+
+ if (k == null) {
+ try {
+ KeyPairGenerator kpg = (provider == null) ? KeyPairGenerator
+ .getInstance(algName)
+ : KeyPairGenerator.getInstance(algName, provider);
+ KeyPair kp = kpg.genKeyPair();
+ k = kp.getPrivate();
+ pubK = kp.getPublic();
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+
+ PBEParameterSpec pbeParamSpec = null;
+ if (k == null) {
+ try {
+ pbeParamSpec = new PBEParameterSpec(new byte[] { 1, 2, 3,
+ 4, 5, 6, 7, 8 }, 10);
+ SecretKeyFactory skf = (provider == null) ? SecretKeyFactory
+ .getInstance(algName)
+ : SecretKeyFactory.getInstance(algName, provider);
+ PBEKeySpec ks = new PBEKeySpec("12345678".toCharArray());
+ try {
+ k = skf.generateSecret(ks);
+ } catch (InvalidKeySpecException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+ }
+
+ try {
+ if (pbeParamSpec == null) {
+ c.init(Cipher.ENCRYPT_MODE, k);
+ } else {
+ c.init(Cipher.ENCRYPT_MODE, k, pbeParamSpec);
+ }
+ } catch (InvalidKeyException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (SecurityException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+
+ ap = c.getParameters();
+
+ try {
+ ct = c.doFinal(privateKeyInfo);
+ } catch (IllegalStateException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (IllegalBlockSizeException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (BadPaddingException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (RuntimeException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+
+ try {
+ // try to convert pbeParamSpec->ap
+ if (pbeParamSpec != null) {
+ try {
+ ap = (provider == null) ? AlgorithmParameters
+ .getInstance(algName) : AlgorithmParameters
+ .getInstance(algName, provider);
+ ap.init(pbeParamSpec);
+ pbeParamSpec = null;
+ } catch (NoSuchAlgorithmException e) {
+ // couldn't convert
+ throw new AllowedFailure(e.getMessage());
+ } catch (InvalidParameterSpecException e) {
+ // couldn't convert
+ throw new AllowedFailure(e.getMessage());
+ }
+ }
+
+ if (ap == null) {
+ c.init(Cipher.DECRYPT_MODE, pubK == null ? k : pubK);
+ } else {
+ c.init(Cipher.DECRYPT_MODE, pubK == null ? k : pubK, ap);
+ }
+
+ } catch (InvalidKeyException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (SecurityException e) {
+ throw new AllowedFailure(e.getMessage());
+ } catch (InvalidAlgorithmParameterException e) {
+ throw new AllowedFailure(e.getMessage());
+ }
+ }
+
+ public Key k() {
+ return k;
+ }
+
+ public Key pubK() {
+ return pubK;
+ }
+
+ public Cipher c() {
+ return c;
+ }
+
+ public byte[] ct() {
+ return ct;
+ }
+
+ public AlgorithmParameters ap() {
+ return ap;
+ }
+ }
+
+ // valid PrivateKeyInfo encoding
+ private static final byte[] privateKeyInfo = { (byte) 0x30, (byte) 0x82,
+ (byte) 0x02, (byte) 0x77, (byte) 0x02, (byte) 0x01, (byte) 0x00,
+ (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+ (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
+ (byte) 0x04, (byte) 0x82, (byte) 0x02, (byte) 0x61, (byte) 0x30,
+ (byte) 0x82, (byte) 0x02, (byte) 0x5d, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00,
+ (byte) 0xb2, (byte) 0x4a, (byte) 0x9b, (byte) 0x5b, (byte) 0xba,
+ (byte) 0x01, (byte) 0xc0, (byte) 0xcd, (byte) 0x65, (byte) 0x09,
+ (byte) 0x63, (byte) 0x70, (byte) 0x0b, (byte) 0x5a, (byte) 0x1b,
+ (byte) 0x92, (byte) 0x08, (byte) 0xf8, (byte) 0x55, (byte) 0x5e,
+ (byte) 0x7c, (byte) 0x1b, (byte) 0x50, (byte) 0x17, (byte) 0xec,
+ (byte) 0x44, (byte) 0x4c, (byte) 0x58, (byte) 0x42, (byte) 0x2b,
+ (byte) 0x41, (byte) 0x09, (byte) 0x59, (byte) 0xf2, (byte) 0xe1,
+ (byte) 0x5d, (byte) 0x43, (byte) 0x71, (byte) 0x4d, (byte) 0x92,
+ (byte) 0x03, (byte) 0x1d, (byte) 0xb6, (byte) 0x6c, (byte) 0x7f,
+ (byte) 0x5d, (byte) 0x48, (byte) 0xcd, (byte) 0x17, (byte) 0xec,
+ (byte) 0xd7, (byte) 0x4c, (byte) 0x39, (byte) 0xb1, (byte) 0x7b,
+ (byte) 0xe2, (byte) 0xbf, (byte) 0x96, (byte) 0x77, (byte) 0xbe,
+ (byte) 0xd0, (byte) 0xa0, (byte) 0xf0, (byte) 0x2d, (byte) 0x6b,
+ (byte) 0x24, (byte) 0xaa, (byte) 0x14, (byte) 0xba, (byte) 0x82,
+ (byte) 0x79, (byte) 0x10, (byte) 0x9b, (byte) 0x16, (byte) 0x68,
+ (byte) 0x47, (byte) 0x81, (byte) 0x54, (byte) 0xa2, (byte) 0xfa,
+ (byte) 0x91, (byte) 0x9e, (byte) 0x0a, (byte) 0x2a, (byte) 0x53,
+ (byte) 0xa6, (byte) 0xe7, (byte) 0x9e, (byte) 0x7d, (byte) 0x29,
+ (byte) 0x33, (byte) 0xd8, (byte) 0x05, (byte) 0xfc, (byte) 0x02,
+ (byte) 0x3f, (byte) 0xbd, (byte) 0xc7, (byte) 0x6e, (byte) 0xed,
+ (byte) 0xaa, (byte) 0x30, (byte) 0x6c, (byte) 0x5f, (byte) 0x52,
+ (byte) 0xed, (byte) 0x35, (byte) 0x65, (byte) 0x4b, (byte) 0x0e,
+ (byte) 0xc8, (byte) 0xa7, (byte) 0x12, (byte) 0x10, (byte) 0x56,
+ (byte) 0x37, (byte) 0xaf, (byte) 0x11, (byte) 0xfa, (byte) 0x21,
+ (byte) 0x0e, (byte) 0x99, (byte) 0xff, (byte) 0xfa, (byte) 0x8c,
+ (byte) 0x65, (byte) 0x8e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
+ (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81,
+ (byte) 0x80, (byte) 0x78, (byte) 0x41, (byte) 0x72, (byte) 0x40,
+ (byte) 0x90, (byte) 0x59, (byte) 0x96, (byte) 0x5d, (byte) 0xf3,
+ (byte) 0x84, (byte) 0x3d, (byte) 0x99, (byte) 0xd9, (byte) 0x4e,
+ (byte) 0x51, (byte) 0xc2, (byte) 0x52, (byte) 0x62, (byte) 0x8d,
+ (byte) 0xd2, (byte) 0x49, (byte) 0x0b, (byte) 0x73, (byte) 0x1e,
+ (byte) 0x6f, (byte) 0xb2, (byte) 0x31, (byte) 0x7c, (byte) 0x66,
+ (byte) 0x45, (byte) 0x1e, (byte) 0x7c, (byte) 0xdc, (byte) 0x3a,
+ (byte) 0xc2, (byte) 0x5f, (byte) 0x51, (byte) 0x9a, (byte) 0x1e,
+ (byte) 0xa4, (byte) 0x19, (byte) 0x8d, (byte) 0xf4, (byte) 0xf9,
+ (byte) 0x81, (byte) 0x7e, (byte) 0xbe, (byte) 0x17, (byte) 0xf7,
+ (byte) 0xc7, (byte) 0x3c, (byte) 0x00, (byte) 0xa1, (byte) 0xf9,
+ (byte) 0x60, (byte) 0x82, (byte) 0x34, (byte) 0x8f, (byte) 0x9c,
+ (byte) 0xfd, (byte) 0x0b, (byte) 0x63, (byte) 0x42, (byte) 0x1b,
+ (byte) 0x7f, (byte) 0x45, (byte) 0xf1, (byte) 0x31, (byte) 0xc3,
+ (byte) 0x63, (byte) 0x47, (byte) 0x5c, (byte) 0xc1, (byte) 0xb2,
+ (byte) 0x5f, (byte) 0x57, (byte) 0xee, (byte) 0x02, (byte) 0x9f,
+ (byte) 0x5e, (byte) 0x08, (byte) 0x48, (byte) 0xba, (byte) 0x74,
+ (byte) 0xba, (byte) 0x81, (byte) 0xb7, (byte) 0x30, (byte) 0xac,
+ (byte) 0x4c, (byte) 0x01, (byte) 0x35, (byte) 0xce, (byte) 0x46,
+ (byte) 0x47, (byte) 0x8c, (byte) 0xe4, (byte) 0x62, (byte) 0x36,
+ (byte) 0x1a, (byte) 0x65, (byte) 0x0e, (byte) 0x33, (byte) 0x56,
+ (byte) 0xf9, (byte) 0xb7, (byte) 0xa0, (byte) 0xc4, (byte) 0xb6,
+ (byte) 0x82, (byte) 0x55, (byte) 0x7d, (byte) 0x36, (byte) 0x55,
+ (byte) 0xc0, (byte) 0x52, (byte) 0x5e, (byte) 0x35, (byte) 0x54,
+ (byte) 0xbd, (byte) 0x97, (byte) 0x01, (byte) 0x00, (byte) 0xbf,
+ (byte) 0x10, (byte) 0xdc, (byte) 0x1b, (byte) 0x51, (byte) 0x02,
+ (byte) 0x41, (byte) 0x00, (byte) 0xe7, (byte) 0x68, (byte) 0x03,
+ (byte) 0x3e, (byte) 0x21, (byte) 0x64, (byte) 0x68, (byte) 0x24,
+ (byte) 0x7b, (byte) 0xd0, (byte) 0x31, (byte) 0xa0, (byte) 0xa2,
+ (byte) 0xd9, (byte) 0x87, (byte) 0x6d, (byte) 0x79, (byte) 0x81,
+ (byte) 0x8f, (byte) 0x8f, (byte) 0x2d, (byte) 0x7a, (byte) 0x95,
+ (byte) 0x2e, (byte) 0x55, (byte) 0x9f, (byte) 0xd7, (byte) 0x86,
+ (byte) 0x29, (byte) 0x93, (byte) 0xbd, (byte) 0x04, (byte) 0x7e,
+ (byte) 0x4f, (byte) 0xdb, (byte) 0x56, (byte) 0xf1, (byte) 0x75,
+ (byte) 0xd0, (byte) 0x4b, (byte) 0x00, (byte) 0x3a, (byte) 0xe0,
+ (byte) 0x26, (byte) 0xf6, (byte) 0xab, (byte) 0x9e, (byte) 0x0b,
+ (byte) 0x2a, (byte) 0xf4, (byte) 0xa8, (byte) 0xd7, (byte) 0xff,
+ (byte) 0xbe, (byte) 0x01, (byte) 0xeb, (byte) 0x9b, (byte) 0x81,
+ (byte) 0xc7, (byte) 0x5f, (byte) 0x02, (byte) 0x73, (byte) 0xe1,
+ (byte) 0x2b, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xc5,
+ (byte) 0x3d, (byte) 0x78, (byte) 0xab, (byte) 0xe6, (byte) 0xab,
+ (byte) 0x3e, (byte) 0x29, (byte) 0xfd, (byte) 0x98, (byte) 0xd0,
+ (byte) 0xa4, (byte) 0x3e, (byte) 0x58, (byte) 0xee, (byte) 0x48,
+ (byte) 0x45, (byte) 0xa3, (byte) 0x66, (byte) 0xac, (byte) 0xe9,
+ (byte) 0x4d, (byte) 0xbd, (byte) 0x60, (byte) 0xea, (byte) 0x24,
+ (byte) 0xff, (byte) 0xed, (byte) 0x0c, (byte) 0x67, (byte) 0xc5,
+ (byte) 0xfd, (byte) 0x36, (byte) 0x28, (byte) 0xea, (byte) 0x74,
+ (byte) 0x88, (byte) 0xd1, (byte) 0xd1, (byte) 0xad, (byte) 0x58,
+ (byte) 0xd7, (byte) 0xf0, (byte) 0x67, (byte) 0x20, (byte) 0xc1,
+ (byte) 0xe3, (byte) 0xb3, (byte) 0xdb, (byte) 0x52, (byte) 0xad,
+ (byte) 0xf3, (byte) 0xc4, (byte) 0x21, (byte) 0xd8, (byte) 0x8c,
+ (byte) 0x4c, (byte) 0x41, (byte) 0x27, (byte) 0xdb, (byte) 0xd0,
+ (byte) 0x35, (byte) 0x92, (byte) 0xc7, (byte) 0x02, (byte) 0x41,
+ (byte) 0x00, (byte) 0xe0, (byte) 0x99, (byte) 0x42, (byte) 0xb4,
+ (byte) 0x76, (byte) 0x02, (byte) 0x97, (byte) 0x55, (byte) 0xf9,
+ (byte) 0xda, (byte) 0x3b, (byte) 0xa0, (byte) 0xd7, (byte) 0x0e,
+ (byte) 0xdc, (byte) 0xf4, (byte) 0x33, (byte) 0x7f, (byte) 0xbd,
+ (byte) 0xcf, (byte) 0xd0, (byte) 0xeb, (byte) 0x6e, (byte) 0x89,
+ (byte) 0xf7, (byte) 0x4f, (byte) 0x5a, (byte) 0x07, (byte) 0x7c,
+ (byte) 0xa9, (byte) 0x49, (byte) 0x47, (byte) 0x68, (byte) 0x35,
+ (byte) 0xa8, (byte) 0x05, (byte) 0x3d, (byte) 0xfd, (byte) 0x04,
+ (byte) 0x7b, (byte) 0x17, (byte) 0x31, (byte) 0x0d, (byte) 0xc8,
+ (byte) 0xa3, (byte) 0x98, (byte) 0x34, (byte) 0xa0, (byte) 0x50,
+ (byte) 0x44, (byte) 0x00, (byte) 0xf1, (byte) 0x0c, (byte) 0xe6,
+ (byte) 0xe5, (byte) 0xc4, (byte) 0x41, (byte) 0x3d, (byte) 0xf8,
+ (byte) 0x3d, (byte) 0x4e, (byte) 0x0b, (byte) 0x1c, (byte) 0xdb,
+ (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0x82, (byte) 0x9b,
+ (byte) 0x8a, (byte) 0xfd, (byte) 0xa1, (byte) 0x98, (byte) 0x41,
+ (byte) 0x68, (byte) 0xc2, (byte) 0xd1, (byte) 0xdf, (byte) 0x4e,
+ (byte) 0xf3, (byte) 0x2e, (byte) 0x26, (byte) 0x53, (byte) 0x5b,
+ (byte) 0x31, (byte) 0xb1, (byte) 0x7a, (byte) 0xcc, (byte) 0x5e,
+ (byte) 0xbb, (byte) 0x09, (byte) 0xa2, (byte) 0xe2, (byte) 0x6f,
+ (byte) 0x4a, (byte) 0x04, (byte) 0x0d, (byte) 0xef, (byte) 0x90,
+ (byte) 0x15, (byte) 0xbe, (byte) 0x10, (byte) 0x4a, (byte) 0xac,
+ (byte) 0x92, (byte) 0xeb, (byte) 0xda, (byte) 0x72, (byte) 0xdb,
+ (byte) 0x43, (byte) 0x08, (byte) 0xb7, (byte) 0x2b, (byte) 0x4c,
+ (byte) 0xe1, (byte) 0xbb, (byte) 0x58, (byte) 0xcb, (byte) 0x71,
+ (byte) 0x80, (byte) 0xad, (byte) 0xbc, (byte) 0xdc, (byte) 0x62,
+ (byte) 0x5e, (byte) 0x3e, (byte) 0xcb, (byte) 0x92, (byte) 0xda,
+ (byte) 0xf6, (byte) 0xdf, (byte) 0x02, (byte) 0x40, (byte) 0x4d,
+ (byte) 0x81, (byte) 0x90, (byte) 0xc5, (byte) 0x77, (byte) 0x30,
+ (byte) 0xb7, (byte) 0x29, (byte) 0x00, (byte) 0xa8, (byte) 0xf1,
+ (byte) 0xb4, (byte) 0xae, (byte) 0x52, (byte) 0x63, (byte) 0x00,
+ (byte) 0xb2, (byte) 0x2d, (byte) 0x3e, (byte) 0x7d, (byte) 0xd6,
+ (byte) 0x4d, (byte) 0xf9, (byte) 0x8a, (byte) 0xc1, (byte) 0xb1,
+ (byte) 0x98, (byte) 0x89, (byte) 0x52, (byte) 0x40, (byte) 0x14,
+ (byte) 0x1b, (byte) 0x0e, (byte) 0x61, (byte) 0x8f, (byte) 0xf4,
+ (byte) 0xbe, (byte) 0x59, (byte) 0x79, (byte) 0x79, (byte) 0x95,
+ (byte) 0x19, (byte) 0x5c, (byte) 0x51, (byte) 0x08, (byte) 0x66,
+ (byte) 0xc1, (byte) 0x42, (byte) 0x30, (byte) 0xb3, (byte) 0x7a,
+ (byte) 0x86, (byte) 0x9f, (byte) 0x3e, (byte) 0xf5, (byte) 0x19,
+ (byte) 0xa3, (byte) 0xae, (byte) 0x64, (byte) 0x69, (byte) 0x14,
+ (byte) 0x07, (byte) 0x50, (byte) 0x97, };
+
+ // valid PrivateKeyInfo encoding (Damaged)
+ private static final byte[] privateKeyInfoDamaged = { (byte) 0x30,
+ (byte) 0x82, (byte) 0x02, (byte) 0x77, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+ (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+ (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+ (byte) 0x00, (byte) 0x04, // private key octet str
+ (byte) 0x82, (byte) 0x02, (byte) 0x62, // Damage: l=460->461
+ // (0x61->0x62)
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5d, (byte) 0x02,
+ (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0xb2, (byte) 0x4a, (byte) 0x9b, (byte) 0x5b,
+ (byte) 0xba, (byte) 0x01, (byte) 0xc0, (byte) 0xcd, (byte) 0x65,
+ (byte) 0x09, (byte) 0x63, (byte) 0x70, (byte) 0x0b, (byte) 0x5a,
+ (byte) 0x1b, (byte) 0x92, (byte) 0x08, (byte) 0xf8, (byte) 0x55,
+ (byte) 0x5e, (byte) 0x7c, (byte) 0x1b, (byte) 0x50, (byte) 0x17,
+ (byte) 0xec, (byte) 0x44, (byte) 0x4c, (byte) 0x58, (byte) 0x42,
+ (byte) 0x2b, (byte) 0x41, (byte) 0x09, (byte) 0x59, (byte) 0xf2,
+ (byte) 0xe1, (byte) 0x5d, (byte) 0x43, (byte) 0x71, (byte) 0x4d,
+ (byte) 0x92, (byte) 0x03, (byte) 0x1d, (byte) 0xb6, (byte) 0x6c,
+ (byte) 0x7f, (byte) 0x5d, (byte) 0x48, (byte) 0xcd, (byte) 0x17,
+ (byte) 0xec, (byte) 0xd7, (byte) 0x4c, (byte) 0x39, (byte) 0xb1,
+ (byte) 0x7b, (byte) 0xe2, (byte) 0xbf, (byte) 0x96, (byte) 0x77,
+ (byte) 0xbe, (byte) 0xd0, (byte) 0xa0, (byte) 0xf0, (byte) 0x2d,
+ (byte) 0x6b, (byte) 0x24, (byte) 0xaa, (byte) 0x14, (byte) 0xba,
+ (byte) 0x82, (byte) 0x79, (byte) 0x10, (byte) 0x9b, (byte) 0x16,
+ (byte) 0x68, (byte) 0x47, (byte) 0x81, (byte) 0x54, (byte) 0xa2,
+ (byte) 0xfa, (byte) 0x91, (byte) 0x9e, (byte) 0x0a, (byte) 0x2a,
+ (byte) 0x53, (byte) 0xa6, (byte) 0xe7, (byte) 0x9e, (byte) 0x7d,
+ (byte) 0x29, (byte) 0x33, (byte) 0xd8, (byte) 0x05, (byte) 0xfc,
+ (byte) 0x02, (byte) 0x3f, (byte) 0xbd, (byte) 0xc7, (byte) 0x6e,
+ (byte) 0xed, (byte) 0xaa, (byte) 0x30, (byte) 0x6c, (byte) 0x5f,
+ (byte) 0x52, (byte) 0xed, (byte) 0x35, (byte) 0x65, (byte) 0x4b,
+ (byte) 0x0e, (byte) 0xc8, (byte) 0xa7, (byte) 0x12, (byte) 0x10,
+ (byte) 0x56, (byte) 0x37, (byte) 0xaf, (byte) 0x11, (byte) 0xfa,
+ (byte) 0x21, (byte) 0x0e, (byte) 0x99, (byte) 0xff, (byte) 0xfa,
+ (byte) 0x8c, (byte) 0x65, (byte) 0x8e, (byte) 0x6d, (byte) 0x02,
+ (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x81, (byte) 0x80, (byte) 0x78, (byte) 0x41, (byte) 0x72,
+ (byte) 0x40, (byte) 0x90, (byte) 0x59, (byte) 0x96, (byte) 0x5d,
+ (byte) 0xf3, (byte) 0x84, (byte) 0x3d, (byte) 0x99, (byte) 0xd9,
+ (byte) 0x4e, (byte) 0x51, (byte) 0xc2, (byte) 0x52, (byte) 0x62,
+ (byte) 0x8d, (byte) 0xd2, (byte) 0x49, (byte) 0x0b, (byte) 0x73,
+ (byte) 0x1e, (byte) 0x6f, (byte) 0xb2, (byte) 0x31, (byte) 0x7c,
+ (byte) 0x66, (byte) 0x45, (byte) 0x1e, (byte) 0x7c, (byte) 0xdc,
+ (byte) 0x3a, (byte) 0xc2, (byte) 0x5f, (byte) 0x51, (byte) 0x9a,
+ (byte) 0x1e, (byte) 0xa4, (byte) 0x19, (byte) 0x8d, (byte) 0xf4,
+ (byte) 0xf9, (byte) 0x81, (byte) 0x7e, (byte) 0xbe, (byte) 0x17,
+ (byte) 0xf7, (byte) 0xc7, (byte) 0x3c, (byte) 0x00, (byte) 0xa1,
+ (byte) 0xf9, (byte) 0x60, (byte) 0x82, (byte) 0x34, (byte) 0x8f,
+ (byte) 0x9c, (byte) 0xfd, (byte) 0x0b, (byte) 0x63, (byte) 0x42,
+ (byte) 0x1b, (byte) 0x7f, (byte) 0x45, (byte) 0xf1, (byte) 0x31,
+ (byte) 0xc3, (byte) 0x63, (byte) 0x47, (byte) 0x5c, (byte) 0xc1,
+ (byte) 0xb2, (byte) 0x5f, (byte) 0x57, (byte) 0xee, (byte) 0x02,
+ (byte) 0x9f, (byte) 0x5e, (byte) 0x08, (byte) 0x48, (byte) 0xba,
+ (byte) 0x74, (byte) 0xba, (byte) 0x81, (byte) 0xb7, (byte) 0x30,
+ (byte) 0xac, (byte) 0x4c, (byte) 0x01, (byte) 0x35, (byte) 0xce,
+ (byte) 0x46, (byte) 0x47, (byte) 0x8c, (byte) 0xe4, (byte) 0x62,
+ (byte) 0x36, (byte) 0x1a, (byte) 0x65, (byte) 0x0e, (byte) 0x33,
+ (byte) 0x56, (byte) 0xf9, (byte) 0xb7, (byte) 0xa0, (byte) 0xc4,
+ (byte) 0xb6, (byte) 0x82, (byte) 0x55, (byte) 0x7d, (byte) 0x36,
+ (byte) 0x55, (byte) 0xc0, (byte) 0x52, (byte) 0x5e, (byte) 0x35,
+ (byte) 0x54, (byte) 0xbd, (byte) 0x97, (byte) 0x01, (byte) 0x00,
+ (byte) 0xbf, (byte) 0x10, (byte) 0xdc, (byte) 0x1b, (byte) 0x51,
+ (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xe7, (byte) 0x68,
+ (byte) 0x03, (byte) 0x3e, (byte) 0x21, (byte) 0x64, (byte) 0x68,
+ (byte) 0x24, (byte) 0x7b, (byte) 0xd0, (byte) 0x31, (byte) 0xa0,
+ (byte) 0xa2, (byte) 0xd9, (byte) 0x87, (byte) 0x6d, (byte) 0x79,
+ (byte) 0x81, (byte) 0x8f, (byte) 0x8f, (byte) 0x2d, (byte) 0x7a,
+ (byte) 0x95, (byte) 0x2e, (byte) 0x55, (byte) 0x9f, (byte) 0xd7,
+ (byte) 0x86, (byte) 0x29, (byte) 0x93, (byte) 0xbd, (byte) 0x04,
+ (byte) 0x7e, (byte) 0x4f, (byte) 0xdb, (byte) 0x56, (byte) 0xf1,
+ (byte) 0x75, (byte) 0xd0, (byte) 0x4b, (byte) 0x00, (byte) 0x3a,
+ (byte) 0xe0, (byte) 0x26, (byte) 0xf6, (byte) 0xab, (byte) 0x9e,
+ (byte) 0x0b, (byte) 0x2a, (byte) 0xf4, (byte) 0xa8, (byte) 0xd7,
+ (byte) 0xff, (byte) 0xbe, (byte) 0x01, (byte) 0xeb, (byte) 0x9b,
+ (byte) 0x81, (byte) 0xc7, (byte) 0x5f, (byte) 0x02, (byte) 0x73,
+ (byte) 0xe1, (byte) 0x2b, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+ (byte) 0xc5, (byte) 0x3d, (byte) 0x78, (byte) 0xab, (byte) 0xe6,
+ (byte) 0xab, (byte) 0x3e, (byte) 0x29, (byte) 0xfd, // 88
+ (byte) 0x98, (byte) 0xd0, (byte) 0xa4, (byte) 0x3e, (byte) 0x58,
+ (byte) 0xee, (byte) 0x48, (byte) 0x45, (byte) 0xa3, (byte) 0x66,
+ (byte) 0xac, (byte) 0xe9, (byte) 0x4d, (byte) 0xbd, (byte) 0x60,
+ (byte) 0xea, (byte) 0x24, (byte) 0xff, (byte) 0xed, (byte) 0x0c,
+ (byte) 0x67, (byte) 0xc5, (byte) 0xfd, (byte) 0x36, (byte) 0x28,
+ (byte) 0xea, (byte) 0x74, (byte) 0x88, (byte) 0xd1, (byte) 0xd1,
+ (byte) 0xad, (byte) 0x58, (byte) 0xd7, (byte) 0xf0, (byte) 0x67,
+ (byte) 0x20, (byte) 0xc1, (byte) 0xe3, (byte) 0xb3, (byte) 0xdb,
+ (byte) 0x52, (byte) 0xad, (byte) 0xf3, (byte) 0xc4, (byte) 0x21,
+ (byte) 0xd8, (byte) 0x8c, (byte) 0x4c, (byte) 0x41, (byte) 0x27,
+ (byte) 0xdb, (byte) 0xd0, (byte) 0x35, (byte) 0x92, (byte) 0xc7,
+ (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xe0, (byte) 0x99,
+ (byte) 0x42, (byte) 0xb4, (byte) 0x76, (byte) 0x02, (byte) 0x97,
+ (byte) 0x55, (byte) 0xf9, (byte) 0xda, (byte) 0x3b, (byte) 0xa0,
+ (byte) 0xd7, (byte) 0x0e, (byte) 0xdc, (byte) 0xf4, (byte) 0x33,
+ (byte) 0x7f, (byte) 0xbd, (byte) 0xcf, (byte) 0xd0, (byte) 0xeb,
+ (byte) 0x6e, (byte) 0x89, (byte) 0xf7, (byte) 0x4f, (byte) 0x5a,
+ (byte) 0x07, (byte) 0x7c, (byte) 0xa9, (byte) 0x49, (byte) 0x47,
+ (byte) 0x68, (byte) 0x35, (byte) 0xa8, (byte) 0x05, (byte) 0x3d,
+ (byte) 0xfd, (byte) 0x04, (byte) 0x7b, (byte) 0x17, (byte) 0x31,
+ (byte) 0x0d, (byte) 0xc8, (byte) 0xa3, (byte) 0x98, (byte) 0x34,
+ (byte) 0xa0, (byte) 0x50, (byte) 0x44, (byte) 0x00, (byte) 0xf1,
+ (byte) 0x0c, (byte) 0xe6, (byte) 0xe5, (byte) 0xc4, (byte) 0x41,
+ (byte) 0x3d, (byte) 0xf8, (byte) 0x3d, (byte) 0x4e, (byte) 0x0b, // 118
+ (byte) 0x1c, (byte) 0xdb, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+ (byte) 0x82, (byte) 0x9b, (byte) 0x8a, (byte) 0xfd, (byte) 0xa1,
+ (byte) 0x98, (byte) 0x41, (byte) 0x68, (byte) 0xc2, (byte) 0xd1,
+ (byte) 0xdf, (byte) 0x4e, (byte) 0xf3, (byte) 0x2e, (byte) 0x26,
+ (byte) 0x53, (byte) 0x5b, (byte) 0x31, (byte) 0xb1, (byte) 0x7a,
+ (byte) 0xcc, (byte) 0x5e, (byte) 0xbb, (byte) 0x09, (byte) 0xa2,
+ (byte) 0xe2, (byte) 0x6f, (byte) 0x4a, (byte) 0x04, (byte) 0x0d,
+ (byte) 0xef, (byte) 0x90, (byte) 0x15, (byte) 0xbe, (byte) 0x10,
+ (byte) 0x4a, (byte) 0xac, (byte) 0x92, (byte) 0xeb, (byte) 0xda,
+ (byte) 0x72, (byte) 0xdb, (byte) 0x43, (byte) 0x08, (byte) 0xb7,
+ (byte) 0x2b, (byte) 0x4c, (byte) 0xe1, (byte) 0xbb, (byte) 0x58,
+ (byte) 0xcb, (byte) 0x71, (byte) 0x80, (byte) 0xad, (byte) 0xbc,
+ (byte) 0xdc, (byte) 0x62, (byte) 0x5e, (byte) 0x3e, (byte) 0xcb,
+ (byte) 0x92, (byte) 0xda, (byte) 0xf6, (byte) 0xdf, (byte) 0x02,
+ (byte) 0x40, (byte) 0x4d, (byte) 0x81, (byte) 0x90, (byte) 0xc5,
+ (byte) 0x77, (byte) 0x30, (byte) 0xb7, (byte) 0x29, (byte) 0x00,
+ (byte) 0xa8, (byte) 0xf1, (byte) 0xb4, (byte) 0xae, (byte) 0x52,
+ (byte) 0x63, (byte) 0x00, (byte) 0xb2, // 140
+ (byte) 0x2d, (byte) 0x3e, (byte) 0x7d, (byte) 0xd6, (byte) 0x4d,
+ (byte) 0xf9, (byte) 0x8a, (byte) 0xc1, (byte) 0xb1, (byte) 0x98,
+ (byte) 0x89, (byte) 0x52, (byte) 0x40, (byte) 0x14, (byte) 0x1b,
+ (byte) 0x0e, (byte) 0x61, (byte) 0x8f, (byte) 0xf4, (byte) 0xbe,
+ (byte) 0x59, (byte) 0x79, (byte) 0x79, (byte) 0x95, (byte) 0x19,
+ (byte) 0x5c, (byte) 0x51, (byte) 0x08, (byte) 0x66, (byte) 0xc1,
+ (byte) 0x42, (byte) 0x30, (byte) 0xb3, (byte) 0x7a, (byte) 0x86,
+ (byte) 0x9f, (byte) 0x3e, (byte) 0xf5, (byte) 0x19, (byte) 0xa3, // 150
+ (byte) 0xae, (byte) 0x64, (byte) 0x69, (byte) 0x14, (byte) 0x07,
+ (byte) 0x50, (byte) 0x97, };
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java
new file mode 100644
index 0000000..a26e605
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismExceptionTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.ExemptionMechanismException;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(ExemptionMechanismException.class)
+/**
+ * Tests for <code>ExemptionMechanismException</code> class constructors and
+ * methods.
+ *
+ */
+public class ExemptionMechanismExceptionTest extends TestCase {
+
+ static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+ static Throwable tCause = new Throwable("Throwable for exception");
+
+ static String createErr(Exception tE, Exception eE) {
+ return "ExemptionMechanismException: ".concat(tE.toString()).concat(
+ " is not equal to caught exception: ").concat(eE.toString());
+ }
+
+ /**
+ * Test for <code>ExemptionMechanismException()</code> constructor
+ * Assertion: constructs ExemptionMechanismException with no detail message
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ExemptionMechanismException",
+ args = {}
+ )
+ public void testExemptionMechanismException01() {
+ ExemptionMechanismException tE = new ExemptionMechanismException();
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ try {
+ throw tE;
+ } catch (Exception e) {
+ assertTrue(createErr(tE, e), tE.equals(e));
+ }
+ }
+
+ /**
+ * Test for <code>ExemptionMechanismException(String)</code> constructor
+ * Assertion: constructs ExemptionMechanismException with detail message
+ * msg. Parameter <code>msg</code> is not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ExemptionMechanismException",
+ args = {java.lang.String.class}
+ )
+ public void testExemptionMechanismException02() {
+ ExemptionMechanismException tE;
+ for (int i = 0; i < msgs.length; i++) {
+ tE = new ExemptionMechanismException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), tE
+ .getMessage(), msgs[i]);
+ assertNull("getCause() must return null", tE.getCause());
+ try {
+ throw tE;
+ } catch (Exception e) {
+ assertTrue(createErr(tE, e), tE.equals(e));
+ }
+ }
+ }
+
+ /**
+ * Test for <code>ExemptionMechanismException(String)</code> constructor
+ * Assertion: constructs ExemptionMechanismException when <code>msg</code>
+ * is null
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ExemptionMechanismException",
+ args = {java.lang.String.class}
+ )
+ public void testExemptionMechanismException03() {
+ String msg = null;
+ ExemptionMechanismException tE = new ExemptionMechanismException(msg);
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ try {
+ throw tE;
+ } catch (Exception e) {
+ assertTrue(createErr(tE, e), tE.equals(e));
+ }
+ }
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java
new file mode 100644
index 0000000..793edcb
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismSpiTest.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import javax.crypto.ExemptionMechanismException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.ExemptionMechanismSpi;
+import org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(ExemptionMechanismSpi.class)
+/**
+ * Tests for <code>ExemptionMechanismSpi</code> class constructors and
+ * methods.
+ *
+ */
+public class ExemptionMechanismSpiTest extends TestCase {
+class Mock_ExemptionMechanismSpi extends MyExemptionMechanismSpi{
+
+ @Override
+ protected byte[] engineGenExemptionBlob() throws ExemptionMechanismException {
+ return super.engineGenExemptionBlob();
+ }
+
+ @Override
+ protected int engineGenExemptionBlob(byte[] output, int outputOffset) throws ShortBufferException, ExemptionMechanismException {
+ return super.engineGenExemptionBlob(output, outputOffset);
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ return super.engineGetOutputSize(inputLen);
+ }
+
+ @Override
+ protected void engineInit(Key key) throws InvalidKeyException, ExemptionMechanismException {
+ super.engineInit(key);
+
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException, ExemptionMechanismException {
+ super.engineInit(key, params);
+
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameters params) throws InvalidKeyException, InvalidAlgorithmParameterException, ExemptionMechanismException {
+ super.engineInit(key, params);
+
+ }
+
+}
+
+ /**
+ * Test for <code>ExemptionMechanismSpi</code> constructor Assertion:
+ * constructs ExemptionMechanismSpi
+ * @throws Exception
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ExemptionMechanismSpi",
+ args = {}
+ )
+ public void testExemptionMechanismSpi01() throws Exception {
+ Mock_ExemptionMechanismSpi emSpi = new Mock_ExemptionMechanismSpi(){};
+ int len = MyExemptionMechanismSpi.getLength();
+ byte [] bbRes = emSpi.engineGenExemptionBlob();
+ assertEquals("Incorrect length", bbRes.length, len);
+ assertEquals("Incorrect result",
+ emSpi.engineGenExemptionBlob(new byte[1], len), len);
+ assertEquals("Incorrect output size", 10, emSpi.engineGetOutputSize(100));
+ Key key = null;
+ AlgorithmParameters params = null;
+ AlgorithmParameterSpec parSpec = null;
+ try {
+ emSpi.engineInit(key);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ emSpi.engineInit(key, params);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ emSpi.engineInit(key, parSpec);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {
+ }
+ key = ((MyExemptionMechanismSpi)emSpi).new tmp1Key("Proba", new byte[0]);
+ try {
+ emSpi.engineInit(key);
+ fail("ExemptionMechanismException must be thrown");
+ } catch (ExemptionMechanismException e) {
+ }
+ try {
+ emSpi.engineInit(key, params);
+ fail("ExemptionMechanismException must be thrown");
+ } catch (ExemptionMechanismException e) {
+ }
+ try {
+ emSpi.engineInit(key, parSpec);
+ fail("ExemptionMechanismException must be thrown");
+ } catch (ExemptionMechanismException e) {
+ }
+ key = ((MyExemptionMechanismSpi)emSpi).new tmpKey("Proba", new byte[0]);
+ emSpi.engineInit(key);
+ emSpi.engineInit(key, AlgorithmParameters.getInstance("DH"));
+ emSpi.engineInit(key, new RSAKeyGenParameterSpec(10, new BigInteger ("10")));
+
+ assertEquals("Incorrect result", 10, emSpi.engineGetOutputSize(100));
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
new file mode 100644
index 0000000..eb2920e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
@@ -0,0 +1,734 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+import java.util.Vector;
+
+import javax.crypto.ExemptionMechanism;
+import javax.crypto.ExemptionMechanismException;
+import javax.crypto.ExemptionMechanismSpi;
+import javax.crypto.KeyGenerator;
+import javax.crypto.ShortBufferException;
+
+import org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi;
+import org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi.tmpKey;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(ExemptionMechanism.class)
+/**
+ * Tests for <code>ExemptionMechanism</code> class constructors and methods
+ *
+ */
+
+public class ExemptionMechanismTest extends TestCase {
+
+ private static final String srvExemptionMechanism = "ExemptionMechanism";
+
+ private static final String defaultAlg = "EMech";
+
+ private static final String ExemptionMechanismProviderClass = "org.apache.harmony.crypto.tests.support.MyExemptionMechanismSpi";
+
+ /**
+ * Test for <code>ExemptionMechanism</code> constructor
+ * Assertion: creates new object using provider and mechanism name
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ExemptionMechanism",
+ args = {javax.crypto.ExemptionMechanismSpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void testExemptionMechanism() throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanismSpi spi = new MyExemptionMechanismSpi();
+
+ ExemptionMechanism em = new ExemptionMechanism(spi, mProv, defaultAlg) {};
+ assertEquals("Incorrect provider", em.getProvider(), mProv);
+ assertEquals("Incorrect algorithm", em.getName(), defaultAlg);
+ try {
+ em.init(null);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {}
+
+ try {
+ em.getOutputSize(100);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {}
+
+
+ em = new ExemptionMechanism(null, null, null) {};
+ assertNull("Incorrect mechanism", em.getName());
+ assertNull("Incorrect provider", em.getProvider());
+ try {
+ em.init(null);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {}
+ try {
+ em.getOutputSize(100);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {}
+ }
+
+ /**
+ * @tests javax/crypto/ExemptionMechanism#getInstance(String algorithm, String provider)
+ * Checks exception order
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstance() throws Exception {
+ //Regression for HARMONY-762
+ try {
+ ExemptionMechanism.getInstance((String) null, "aaa");
+ fail("NoSuchProviderException must be thrown");
+ } catch (NoSuchProviderException pe) {
+ //expected
+ }
+ try {
+ ExemptionMechanism.getInstance("AlgName", (String)null);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ /**
+ * Test for <code>isCryptoAllowed(Key key)</code> method
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isCryptoAllowed",
+ args = {java.security.Key.class}
+ )
+ public void testIsCryptoAllowed() throws Exception {
+
+ //Regression for HARMONY-1029
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ assertFalse(em.isCryptoAllowed(key));
+
+ em.init(key);
+ assertFalse(em.isCryptoAllowed(key));
+
+ em.genExemptionBlob();
+ assertTrue(em.isCryptoAllowed(key));
+
+ Key key1 = new MyExemptionMechanismSpi().new tmpKey("Proba",
+ new byte[] { 1 });
+ assertFalse(em.isCryptoAllowed(key1));
+
+ em.init(key1);
+ assertFalse(em.isCryptoAllowed(key));
+ }
+
+ /**
+ * Test for <code>genExemptionBlob((byte[] output, int outputOffset)</code> method
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Regression test",
+ method = "genExemptionBlob",
+ args = {byte[].class, int.class}
+ )
+ public void testGenExemptionBlob() throws Exception {
+ //Regression for HARMONY-1029
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ em.init(key);
+ // ExemptionMechanism doesn't check parameters
+ // it is a responsibility of ExemptionMechanismSpi
+ em.genExemptionBlob(null, 0);
+ em.genExemptionBlob(new byte[0], 0);
+ em.genExemptionBlob(new byte[10], -5);
+ }
+
+ static boolean flag = false;
+
+ class Mock_ExemptionMechanism extends ExemptionMechanism {
+ protected Mock_ExemptionMechanism(ExemptionMechanismSpi exmechSpi, Provider provider, String mechanism) {
+ super(exmechSpi, provider, mechanism);
+ }
+
+ @Override
+ protected void finalize() {
+ flag = true;
+ super.finalize();
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "finalize",
+ args = {}
+ )
+ public void test_finalize () {
+ Mock_ExemptionMechanism mem = new Mock_ExemptionMechanism(null, null, "Name");
+ assertNotNull(mem);
+ mem = null;
+ assertFalse(flag);
+ Vector v = new Vector();
+ int capacity;
+ try {
+ while(true) {
+ v.add(this);
+ }
+ } catch (OutOfMemoryError e) {
+ capacity = v.size();
+ v = null;
+ }
+
+ v = new Vector();
+ for (int i = 0; i < capacity/2; i++) {
+ v.add(this);
+ }
+ v = null;
+ assertTrue(flag);
+ }
+
+ class Mock_ExemptionMechanismSpi extends MyExemptionMechanismSpi {
+ @Override
+ protected byte[] engineGenExemptionBlob()
+ throws ExemptionMechanismException {
+ throw new ExemptionMechanismException();
+ }
+
+ @Override
+ protected int engineGenExemptionBlob(byte[] output, int outputOffset)
+ throws ShortBufferException, ExemptionMechanismException {
+ if (output.length - outputOffset <
+ super.engineGenExemptionBlob(output, outputOffset)) {
+ throw new ShortBufferException();
+ }
+ if (output[outputOffset + 3] == 33) {
+ throw new ExemptionMechanismException();
+ }
+ return super.engineGenExemptionBlob(output, outputOffset);
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "genExemptionBlob",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineGenExemptionBlob",
+ args = {}
+ )
+ })
+ public void test_genExemptionBlob() throws InvalidKeyException,
+ ExemptionMechanismException {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ try {
+ em.genExemptionBlob();
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //failed
+ }
+
+ em.init(key);
+
+ assertNotNull(em.genExemptionBlob());
+
+ em = new ExemptionMechanism(
+ new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+ key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+ em.init(key);
+
+ try {
+ em.genExemptionBlob();
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //failed
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "genExemptionBlob",
+ args = {byte[].class}
+ )
+ public void test_genExemptionBlob$B() throws InvalidKeyException,
+ ExemptionMechanismException, ShortBufferException {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ try {
+ em.genExemptionBlob(new byte[10]);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //failed
+ }
+
+ em.init(key);
+
+ assertEquals(5, (em.genExemptionBlob(new byte[10])));
+
+ try {
+ em.genExemptionBlob(new byte[2]);
+ fail("ShortBufferException expected");
+ } catch (ShortBufferException e) {
+ //failed
+ }
+ byte[] b = new byte[] {0,0,0,33,0};
+
+ try {
+ em.genExemptionBlob(b);
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //failed
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "genExemptionBlob",
+ args = {byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineGenExemptionBlob",
+ args = {byte[].class, int.class}
+ )
+ })
+ public void test_genExemptionBlob$BI() throws InvalidKeyException,
+ ExemptionMechanismException, ShortBufferException {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new Mock_ExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ try {
+ em.genExemptionBlob(new byte[10], 2);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //failed
+ }
+
+ em.init(key);
+
+ assertEquals(5, (em.genExemptionBlob(new byte[10], 5)));
+
+ try {
+ em.genExemptionBlob(new byte[7], 3);
+ fail("ShortBufferException expected");
+ } catch (ShortBufferException e) {
+ //failed
+ }
+ byte[] b = new byte[] {0, 0, 0, 1, 2, 3, 33, 0};
+
+ try {
+ em.genExemptionBlob(b, 3);
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //failed
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tests Exceptions",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void test_getInstanceLjava_lang_String() throws Exception {
+ try {
+ ExemptionMechanism.getInstance((String) null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ try {
+ em.getInstance("WrongAlgName");
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tests Exceptions",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void test_getInstanceLjava_lang_StringLjava_security_Provider()
+ throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ try {
+ ExemptionMechanism.getInstance((String) null, mProv);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new Mock_ExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ try {
+ em.getInstance("WrongAlgName", mProv);
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+
+ try {
+ em.getInstance("WrongAlgName", (Provider)null);
+ fail("IllegalArgumentException expected");
+ } catch (IllegalArgumentException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getName",
+ args = {}
+ )
+ public void test_getName() throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ assertEquals(defaultAlg, em.getName());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getOutputSize",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineGetOutputSize",
+ args = {int.class}
+ )
+ })
+ public void test_getOutputSizeI() throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ try {
+ em.getOutputSize(10);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //failed
+ }
+
+ em.init(key);
+ assertEquals(10, em.getOutputSize(10));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider() throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ assertEquals(mProv, em.getProvider());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class}
+ )
+ })
+ public void test_initLjava_security_Key() throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ em.init(key);
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ kg.init(56, new SecureRandom());
+ key = kg.generateKey();
+
+ try {
+ em.init(null);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ em.init(key);
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.Key.class, java.security.AlgorithmParameters.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.AlgorithmParameters.class}
+ )
+ })
+ public void test_initLjava_security_KeyLjava_security_AlgorithmParameters()
+ throws Exception {
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ em.init(key, AlgorithmParameters.getInstance("DES"));
+
+ try {
+ em.init(key, (AlgorithmParameters)null);
+ fail("InvalidAlgorithmParameterException expected");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ kg.init(56, new SecureRandom());
+ key = kg.generateKey();
+
+ try {
+ em.init(null, AlgorithmParameters.getInstance("DES"));
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ em.init(key, AlgorithmParameters.getInstance("DES"));
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = ExemptionMechanismSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ )
+ })
+ public void test_initLjava_security_KeyLjava_security_spec_AlgorithmParameterSpec()
+ throws Exception{
+ Provider mProv = (new SpiEngUtils()).new MyProvider("MyExMechProvider",
+ "Provider for ExemptionMechanism testing",
+ srvExemptionMechanism.concat(".").concat(defaultAlg),
+ ExemptionMechanismProviderClass);
+
+ ExemptionMechanism em = new ExemptionMechanism(
+ new MyExemptionMechanismSpi(), mProv, defaultAlg) {
+ };
+
+ Key key = new MyExemptionMechanismSpi().new tmpKey("Proba", new byte[0]);
+
+ em.init(key, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
+
+ try {
+ em.init(key, (AlgorithmParameterSpec)null);
+ fail("InvalidAlgorithmParameterException expected");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ kg.init(56, new SecureRandom());
+ key = kg.generateKey();
+
+ try {
+ em.init(null, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ em.init(key, new RSAKeyGenParameterSpec(10, new BigInteger("10")));
+ fail("ExemptionMechanismException expected");
+ } catch (ExemptionMechanismException e) {
+ //expected
+ }
+ }
+}
+
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java
new file mode 100644
index 0000000..b98297d
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/IllegalBlockSizeExceptionTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.IllegalBlockSizeException;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(IllegalBlockSizeException.class)
+/**
+ * Tests for <code>IllegalBlockSizeException</code> class constructors and
+ * methods.
+ *
+ */
+public class IllegalBlockSizeExceptionTest extends TestCase {
+
+ static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+ static Throwable tCause = new Throwable("Throwable for exception");
+
+ /**
+ * Test for <code>IllegalBlockSizeException()</code> constructor
+ * Assertion: constructs IllegalBlockSizeException with no detail message
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "IllegalBlockSizeException",
+ args = {}
+ )
+ public void testIllegalBlockSizeException01() {
+ IllegalBlockSizeException tE = new IllegalBlockSizeException();
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+
+ /**
+ * Test for <code>IllegalBlockSizeException(String)</code> constructor
+ * Assertion: constructs IllegalBlockSizeException with detail message msg.
+ * Parameter <code>msg</code> is not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "IllegalBlockSizeException",
+ args = {java.lang.String.class}
+ )
+ public void testIllegalBlockSizeException02() {
+ IllegalBlockSizeException tE;
+ for (int i = 0; i < msgs.length; i++) {
+ tE = new IllegalBlockSizeException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), tE
+ .getMessage(), msgs[i]);
+ assertNull("getCause() must return null", tE.getCause());
+ }
+ }
+
+ /**
+ * Test for <code>IllegalBlockSizeException(String)</code> constructor
+ * Assertion: constructs IllegalBlockSizeException when <code>msg</code>
+ * is null
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "IllegalBlockSizeException",
+ args = {java.lang.String.class}
+ )
+ public void testIllegalBlockSizeException03() {
+ String msg = null;
+ IllegalBlockSizeException tE = new IllegalBlockSizeException(msg);
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java
new file mode 100644
index 0000000..3954608
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementSpiTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+
+import junit.framework.TestCase;
+
+import org.apache.harmony.crypto.tests.support.MyKeyAgreementSpi;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+@TestTargetClass(KeyAgreementSpi.class)
+/**
+ * Tests for <code>KeyAgreementSpi</code> class constructors and methods.
+ *
+ */
+
+public class KeyAgreementSpiTest extends TestCase {
+ class Mock_KeyAgreementSpi extends MyKeyAgreementSpi {
+
+ @Override
+ protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException,
+ IllegalStateException {
+ return super.engineDoPhase(key, lastPhase);
+ }
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ return super.engineGenerateSecret();
+ }
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException,
+ NoSuchAlgorithmException, InvalidKeyException {
+ return super.engineGenerateSecret(algorithm);
+ }
+
+ @Override
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
+ return super.engineGenerateSecret(sharedSecret, offset);
+ }
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
+ super.engineInit(key, random);
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(key, params, random);
+ }
+
+ }
+
+ /**
+ * Test for <code>KeyAgreementSpi</code> constructor Assertion: constructs
+ * KeyAgreementSpi
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "KeyAgreementSpi",
+ args = {}
+ )
+ public void testKeyAgreementSpi01() throws InvalidKeyException,
+ ShortBufferException, NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException {
+ Mock_KeyAgreementSpi kaSpi = new Mock_KeyAgreementSpi();
+
+ assertNull("Not null result", kaSpi.engineDoPhase(null, true));
+ try {
+ kaSpi.engineDoPhase(null, false);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ byte[] bb = kaSpi.engineGenerateSecret();
+ assertEquals("Length is not 0", bb.length, 0);
+ assertEquals("Returned integer is not 0", kaSpi.engineGenerateSecret(new byte[1], 10), -1);
+ assertNull("Not null result", kaSpi.engineGenerateSecret("aaa"));
+ try {
+ kaSpi.engineGenerateSecret("");
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ Key key = null;
+ try {
+ kaSpi.engineInit(key, new SecureRandom());
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ AlgorithmParameterSpec params = null;
+ try {
+ kaSpi.engineInit(key, params, new SecureRandom());
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
new file mode 100644
index 0000000..220c6c6
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyAgreementTest.java
@@ -0,0 +1,975 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.ShortBufferException;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+
+import org.apache.harmony.crypto.tests.support.MyKeyAgreementSpi;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+import org.apache.harmony.security.tests.support.TestKeyPair;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(KeyAgreement.class)
+/**
+ * Tests for KeyAgreement constructor and methods
+ *
+ */
+
+public class KeyAgreementTest extends TestCase {
+
+ public static final String srvKeyAgreement = "KeyAgreement";
+
+ private static String defaultAlgorithm = "DH";
+
+ private static String defaultProviderName = null;
+
+ private static Provider defaultProvider = null;
+
+ private static boolean DEFSupported = false;
+
+ private static final String NotSupportMsg = "There is no suitable provider for KeyAgreement";
+
+ private static final String[] invalidValues = SpiEngUtils.invalidValues;
+
+ private static String[] validValues = { "DH", "dH",
+ "Dh", "dh" };
+
+ private static PrivateKey privKey = null;
+
+ private static PublicKey publKey = null;
+
+ private static boolean initKeys = false;
+
+ static {
+ defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm,
+ srvKeyAgreement);
+ DEFSupported = (defaultProvider != null);
+ defaultProviderName = (DEFSupported ? defaultProvider.getName() : null);
+ }
+
+ private void createKeys() throws Exception {
+ if (!initKeys) {
+ TestKeyPair tkp = new TestKeyPair(defaultAlgorithm);
+ privKey = tkp.getPrivate();
+ publKey = tkp.getPublic();
+ initKeys = true;
+ }
+
+ }
+
+ private KeyAgreement[] createKAs() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ }
+
+ KeyAgreement[] ka = new KeyAgreement[3];
+ ka[0] = KeyAgreement.getInstance(defaultAlgorithm);
+ ka[1] = KeyAgreement.getInstance(defaultAlgorithm, defaultProvider);
+ ka[2] = KeyAgreement.getInstance(defaultAlgorithm,
+ defaultProviderName);
+ return ka;
+ }
+
+ public static String getDefAlg() {
+ return defaultAlgorithm;
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm) </code> method Assertions:
+ * throws NullPointerException when algorithm is null throws
+ * NoSuchAlgorithmException when algorithm isnot available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testGetInstanceString01() throws NoSuchAlgorithmException {
+ try {
+ KeyAgreement.getInstance(null);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyAgreement.getInstance(invalidValues[i]);
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm) </code> method Assertions:
+ * returns KeyAgreement object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testGetInstanceString02() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyAgreement keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyAgreement.getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
+ validValues[i]);
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, String provider)</code>
+ * method Assertions: throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString01()
+ throws NoSuchAlgorithmException, IllegalArgumentException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ KeyAgreement.getInstance(null, defaultProviderName);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyAgreement.getInstance(invalidValues[i], defaultProviderName);
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, String provider)</code>
+ * method Assertions: throws IllegalArgumentException when provider is null
+ * or empty throws NoSuchProviderException when provider has not be
+ * configured
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString02()
+ throws IllegalArgumentException, NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ String provider = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ KeyAgreement.getInstance(validValues[i], provider);
+ fail("IllegalArgumentException must be thrown when provider is null");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ KeyAgreement.getInstance(validValues[i], "");
+ fail("IllegalArgumentException must be thrown when provider is empty");
+ } catch (IllegalArgumentException e) {
+ }
+ for (int j = 1; j < invalidValues.length; j++) {
+ try {
+ KeyAgreement.getInstance(validValues[i], invalidValues[j]);
+ fail("NoSuchProviderException must be thrown (algorithm: "
+ .concat(validValues[i]).concat(" provider: ")
+ .concat(invalidValues[j]).concat(")"));
+ } catch (NoSuchProviderException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, String provider)</code>
+ * method Assertions: returns KeyAgreement object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString03()
+ throws IllegalArgumentException, NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyAgreement keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyAgreement
+ .getInstance(validValues[i], defaultProviderName);
+ assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
+ validValues[i]);
+ assertEquals("Incorrect provider", keyA.getProvider().getName(),
+ defaultProviderName);
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, Provider provider)</code>
+ * method Assertions: throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm isnot available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider01()
+ throws NoSuchAlgorithmException, IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ KeyAgreement.getInstance(null, defaultProvider);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyAgreement.getInstance(invalidValues[i], defaultProvider);
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, Provider provider)</code>
+ * method Assertions: throws IllegalArgumentException when provider is null
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider02()
+ throws NoSuchAlgorithmException, IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ Provider provider = null;
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyAgreement.getInstance(invalidValues[i], provider);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code> getInstance(String algorithm, Provider provider)</code>
+ * method Assertions: returns KeyAgreement object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider03()
+ throws IllegalArgumentException, NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyAgreement keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyAgreement.getInstance(validValues[i], defaultProvider);
+ assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
+ validValues[i]);
+ assertEquals("Incorrect provider", keyA.getProvider(),
+ defaultProvider);
+ }
+ }
+
+ /**
+ * Test for the methods: <code>init(Key key)</code>
+ * <code>generateSecret()</code>
+ * <code>generateSecret(byte[] sharedsecret, int offset)</code>
+ * <code>generateSecret(String algorithm)</code>
+ * Assertions: initializes KeyAgreement; returns sharedSecret; puts
+ * sharedsecret in buffer and return numbers of bytes; returns SecretKey
+ * object
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ method = "init",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ method = "generateSecret",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ method = "generateSecret",
+ args = {byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ method = "generateSecret",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality only.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGenerateSecret03() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+
+ byte[] bb;
+ byte[] bb1 = new byte[10];
+ for (int i = 0; i < kAgs.length; i++) {
+ kAgs[i].init(privKey);
+ kAgs[i].doPhase(publKey, true);
+ bb = kAgs[i].generateSecret();
+ kAgs[i].init(privKey);
+ kAgs[i].doPhase(publKey, true);
+ bb1 = new byte[bb.length + 10];
+ kAgs[i].generateSecret(bb1, 9);
+ kAgs[i].init(privKey);
+ kAgs[i].doPhase(publKey, true);
+ kAgs[i].generateSecret("DES");
+ }
+ }
+
+ /**
+ * Test for <code>doPhase(Key key, boolean lastPhase)</code> method
+ * Assertion: throws InvalidKeyException if key is not appropriate
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "doPhase",
+ args = {java.security.Key.class, boolean.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyAgreementSpi.class,
+ method = "engineDoPhase",
+ args = {java.security.Key.class, boolean.class}
+ )
+ })
+ public void testDoPhase() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+ DHParameterSpec dhPs = ((DHPrivateKey) privKey).getParams();
+ SecureRandom randomNull = null;
+ SecureRandom random = new SecureRandom();
+
+ for (int i = 0; i < kAgs.length; i++) {
+ try {
+ kAgs[i].doPhase(publKey, true);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+
+ kAgs[i].init(privKey);
+
+ try {
+ kAgs[i].doPhase(privKey, false);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+
+ try {
+ kAgs[i].doPhase(privKey, true);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+
+ kAgs[i].init(privKey, dhPs);
+ kAgs[i].doPhase(publKey, true);
+ kAgs[i].init(privKey, dhPs, random);
+ kAgs[i].doPhase(publKey, true);
+ }
+ }
+
+ /**
+ * Test for the methods <code>init(Key key)</code>
+ * <code>init(Key key, SecureRandom random)</code>
+ * <code>init(Key key, AlgorithmParameterSpec params)</code>
+ * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
+ * Assertion: throws InvalidKeyException when key is inappropriate
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidKeyException.",
+ method = "init",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidKeyException.",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidKeyException.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidKeyException.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.SecureRandom.class}
+ )
+ })
+ public void testInit01() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+
+ SecureRandom random = null;
+ AlgorithmParameterSpec aps = null;
+ DHParameterSpec dhPs = new DHParameterSpec(new BigInteger("56"),
+ new BigInteger("56"));
+ for (int i = 0; i < kAgs.length; i++) {
+ try {
+ kAgs[i].init(publKey);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(publKey, new SecureRandom());
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(publKey, random);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(publKey, dhPs);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(publKey, aps);
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(publKey, dhPs, new SecureRandom());
+ fail("InvalidKeyException must be throw");
+ } catch (InvalidKeyException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for the methods
+ * <code>init(Key key, AlgorithmParameterSpec params)</code>
+ * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
+ * Assertion: throws AlgorithmParameterException when params are
+ * inappropriate
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidAlgorithmParameterException.This is a complete subset of tests for exceptions checking for init methods group",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks InvalidAlgorithmParameterException.This is a complete subset of tests for exceptions checking for init methods group",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ )
+ })
+ public void testInit02() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+
+ SecureRandom random = null;
+ DSAParameterSpec dsa = new DSAParameterSpec(new BigInteger("56"),
+ new BigInteger("56"), new BigInteger("56"));
+ for (int i = 0; i < kAgs.length; i++) {
+ try {
+ kAgs[i].init(privKey, dsa);
+ fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
+ } catch (InvalidAlgorithmParameterException e) {
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(privKey, dsa, new SecureRandom());
+ fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
+ } catch (InvalidAlgorithmParameterException e) {
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ kAgs[i].init(privKey, dsa, random);
+ fail("InvalidAlgorithmParameterException or InvalidKeyException must be throw");
+ } catch (InvalidAlgorithmParameterException e) {
+ } catch (InvalidKeyException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for the methods: <code>init(Key key)</code>
+ * <code>init(Key key, SecureRandom random)</code>
+ * <code>generateSecret()</code>
+ * Assertions: initializes KeyAgreement and returns byte array
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "init",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "init",
+ args = {java.security.Key.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "generateSecret",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {}
+ )
+ })
+ public void testInit03() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+
+ byte[] bbRes1;
+ byte[] bbRes2;
+ byte[] bbRes3;
+ SecureRandom randomNull = null;
+ SecureRandom random = new SecureRandom();
+ for (int i = 0; i < kAgs.length; i++) {
+ kAgs[i].init(privKey);
+ kAgs[i].doPhase(publKey, true);
+ bbRes1 = kAgs[i].generateSecret();
+ kAgs[i].init(privKey, random);
+ kAgs[i].doPhase(publKey, true);
+ bbRes2 = kAgs[i].generateSecret();
+ assertEquals("Incorrect byte array length", bbRes1.length,
+ bbRes2.length);
+ for (int j = 0; j < bbRes1.length; j++) {
+ assertEquals("Incorrect byte (index: ".concat(
+ Integer.toString(i)).concat(")"), bbRes1[j], bbRes2[j]);
+ }
+ kAgs[i].init(privKey, randomNull);
+ kAgs[i].doPhase(publKey, true);
+ bbRes3 = kAgs[i].generateSecret();
+ assertEquals("Incorrect byte array length", bbRes1.length,
+ bbRes3.length);
+ for (int j = 0; j < bbRes1.length; j++) {
+ assertEquals("Incorrect byte (index: ".concat(
+ Integer.toString(i)).concat(")"), bbRes1[j], bbRes3[j]);
+ }
+ }
+ }
+
+ /**
+ * Test for the methods:
+ * <code>init(Key key, AlgorithmParameterSpec params)</code>
+ * <code>init(Key key, AlgorithmParameterSpec params, SecureRandom random)</code>
+ * <code>generateSecret()</code>
+ * Assertions: initializes KeyAgreement and returns byte array
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Checks functionality.",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks functionality.",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Checks functionality.",
+ method = "generateSecret",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Checks functionality.",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {}
+ )
+ })
+ public void testInit04() throws Exception,
+ InvalidAlgorithmParameterException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+
+ DHParameterSpec dhPs = ((DHPrivateKey) privKey).getParams();
+ AlgorithmParameterSpec aps = new RSAKeyGenParameterSpec(10, new BigInteger("10"));
+
+ byte[] bbRes1;
+ byte[] bbRes2;
+ byte[] bbRes3;
+ SecureRandom randomNull = null;
+ SecureRandom random = new SecureRandom();
+ for (int i = 0; i < kAgs.length; i++) {
+ kAgs[i].init(privKey, dhPs);
+ kAgs[i].doPhase(publKey, true);
+ bbRes1 = kAgs[i].generateSecret();
+ kAgs[i].init(privKey, dhPs, random);
+ kAgs[i].doPhase(publKey, true);
+ bbRes2 = kAgs[i].generateSecret();
+ assertEquals("Incorrect byte array length", bbRes1.length,
+ bbRes2.length);
+ for (int j = 0; j < bbRes1.length; j++) {
+ assertEquals("Incorrect byte (index: ".concat(
+ Integer.toString(i)).concat(")"), bbRes1[j], bbRes2[j]);
+ }
+ kAgs[i].init(privKey, dhPs, randomNull);
+ kAgs[i].doPhase(publKey, true);
+ bbRes3 = kAgs[i].generateSecret();
+ assertEquals("Incorrect byte array length", bbRes1.length,
+ bbRes3.length);
+ for (int j = 0; j < bbRes1.length; j++) {
+ assertEquals("Incorrect byte (index: ".concat(
+ Integer.toString(i)).concat(")"), bbRes1[j], bbRes3[j]);
+ }
+
+ try {
+ kAgs[i].init(publKey, dhPs, random);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ try {
+ kAgs[i].init(privKey, aps, random);
+ fail("InvalidAlgorithmParameterException expected");
+ } catch (InvalidAlgorithmParameterException e) {
+ //expected
+ }
+ }
+ }
+
+ class Mock_KeyAgreement extends KeyAgreement {
+ protected Mock_KeyAgreement(KeyAgreementSpi arg0, Provider arg1, String arg2) {
+ super(arg0, arg1, arg2);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "KeyAgreement",
+ args = {javax.crypto.KeyAgreementSpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void test_constructor() {
+ assertNotNull(new Mock_KeyAgreement(null, null, null));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void test_getAlgorithm() throws NoSuchAlgorithmException {
+ Mock_KeyAgreement mka = new Mock_KeyAgreement(null, null, null);
+ assertNull(mka.getAlgorithm());
+
+ KeyAgreement keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyAgreement.getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", keyA.getAlgorithm(),
+ validValues[i]);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider() throws NoSuchAlgorithmException {
+ KeyAgreement keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyAgreement.getInstance(validValues[i]);
+ assertNotNull(keyA.getProvider());
+ }
+ }
+
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "generateSecret",
+ args = {byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {byte[].class, int.class}
+ )})
+ public void test_generateSecret$BI() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+ KeyAgreement ka = KeyAgreement.getInstance("DH");
+
+ byte[] bb1 = new byte[1];
+ try {
+ ka.generateSecret(bb1, 0);
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ ka.init(privKey);
+ ka.doPhase(publKey, true);
+ try {
+ ka.generateSecret(bb1, 0);
+ fail("ShortBufferException expected");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "generateSecret",
+ args = {java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ clazz = KeyAgreementSpi.class,
+ method = "engineGenerateSecret",
+ args = {java.lang.String.class}
+ )})
+ @KnownFailure("Does not throw expected exception")
+ public void test_generateSecretLjava_lang_String() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+ KeyAgreement ka = KeyAgreement.getInstance("DH");
+
+ byte[] bb1 = new byte[1];
+ try {
+ ka.generateSecret("dh");
+ fail("IllegalStateException expected");
+ } catch (IllegalStateException e) {
+ //expected
+ }
+ ka.init(privKey);
+ ka.doPhase(publKey, true);
+ try {
+ ka.generateSecret("Wrong alg name");
+ fail("NoSuchAlgorithmException expected");
+ } catch (NoSuchAlgorithmException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.Key.class, java.security.SecureRandom.class}
+ )
+ public void test_initLjava_security_KeyLjava_security_SecureRandom() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ createKeys();
+ KeyAgreement[] kAgs = createKAs();
+ KeyAgreement ka = KeyAgreement.getInstance("DH");
+
+ ka.init(privKey, new SecureRandom());
+ try {
+ ka.init(publKey, new SecureRandom());
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java
new file mode 100644
index 0000000..0605986
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorSpiTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.KeyGeneratorSpi;
+import javax.crypto.SecretKey;
+
+import org.apache.harmony.crypto.tests.support.MyKeyGeneratorSpi;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(KeyGeneratorSpi.class)
+/**
+ * Tests for <code>KeyGeneratorSpi</code> class constructors and methods.
+ *
+ */
+
+public class KeyGeneratorSpiTest extends TestCase {
+ class Mock_KeyGeneratorSpi extends MyKeyGeneratorSpi {
+
+ @Override
+ protected SecretKey engineGenerateKey() {
+ return super.engineGenerateKey();
+ }
+
+ @Override
+ protected void engineInit(SecureRandom random) {
+ super.engineInit(random);
+ }
+
+ @Override
+ protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ super.engineInit(params, random);
+ }
+
+ @Override
+ protected void engineInit(int keysize, SecureRandom random) {
+ super.engineInit(keysize, random);
+ }
+
+ }
+
+ /**
+ * Test for <code>KeyGeneratorSpi</code> constructor Assertion: constructs
+ * KeyGeneratorSpi
+ */
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "KeyGeneratorSpi", args = {})
+ public void testKeyGeneratorSpi01() throws InvalidAlgorithmParameterException {
+ Mock_KeyGeneratorSpi kgSpi = new Mock_KeyGeneratorSpi();
+ assertNull("Not null result", kgSpi.engineGenerateKey());
+ try {
+ kgSpi.engineInit(77, new SecureRandom());
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ kgSpi.engineInit(new SecureRandom());
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ AlgorithmParameterSpec aps = null;
+ try {
+ kgSpi.engineInit(aps, new SecureRandom());
+ fail("InvalidAlgorithmParameterException must be thrown when parameter is null");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ aps = new APSpecSpi();
+ kgSpi.engineInit(aps, new SecureRandom());
+ }
+
+}
+
+class APSpecSpi implements AlgorithmParameterSpec {
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorTest.java
new file mode 100644
index 0000000..8451979
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/KeyGeneratorTest.java
@@ -0,0 +1,690 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.KeyGeneratorSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.harmony.crypto.tests.support.MyKeyGeneratorSpi;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(KeyGenerator.class)
+/**
+ * Tests for KeyGenerator constructor and methods
+ *
+ */
+
+public class KeyGeneratorTest extends TestCase {
+
+ public static final String srvKeyGenerator = "KeyGenerator";
+
+ public static final String validAlgorithmsKeyGenerator [] =
+ {"DESede", "DES", "AES", "HmacMD5"};
+
+ private static final int [] validKeySizes = { 168, 56, 256, 56};
+
+ private static int defaultKeySize = -1;
+
+ private static String defaultAlgorithm = null;
+
+ private static String defaultProviderName = null;
+
+ private static Provider defaultProvider = null;
+
+ private static boolean DEFSupported = false;
+
+ private static final String NotSupportMsg = "There is no suitable provider for KeyGenerator";
+
+ private static final String[] invalidValues = SpiEngUtils.invalidValues;
+
+ private static String[] validValues = new String[3];
+
+ static {
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ defaultProvider = SpiEngUtils.isSupport(validAlgorithmsKeyGenerator[i],
+ srvKeyGenerator);
+ DEFSupported = (defaultProvider != null);
+ if (DEFSupported) {
+ defaultAlgorithm = validAlgorithmsKeyGenerator[i];
+ defaultKeySize = validKeySizes[i];
+ defaultProviderName = defaultProvider.getName();
+ validValues[0] = defaultAlgorithm;
+ validValues[1] = defaultAlgorithm.toUpperCase();
+ validValues[2] = defaultAlgorithm.toLowerCase();
+ break;
+ }
+ }
+ }
+
+ private KeyGenerator[] createKGs() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ }
+
+ KeyGenerator [] kg = new KeyGenerator[3];
+ kg[0] = KeyGenerator.getInstance(defaultAlgorithm);
+ kg[1] = KeyGenerator.getInstance(defaultAlgorithm, defaultProvider);
+ kg[2] = KeyGenerator.getInstance(defaultAlgorithm, defaultProviderName);
+ return kg;
+ }
+
+
+ /**
+ * Test for <code>KeyGenerator</code> constructor Assertion: returns
+ * KeyGenerator object
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "KeyGenerator",
+ args = {javax.crypto.KeyGeneratorSpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void testKeyGenerator() throws NoSuchAlgorithmException,
+ InvalidAlgorithmParameterException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyGeneratorSpi spi = new MyKeyGeneratorSpi();
+ KeyGenerator keyG = new myKeyGenerator(spi, defaultProvider,
+ defaultAlgorithm);
+ assertEquals("Incorrect algorithm", keyG.getAlgorithm(),
+ defaultAlgorithm);
+ assertEquals("Incorrect provider", keyG.getProvider(), defaultProvider);
+ AlgorithmParameterSpec params = null;
+ int keysize = 0;
+ try {
+ keyG.init(params, null);
+ fail("InvalidAlgorithmParameterException must be thrown");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ try {
+ keyG.init(keysize, null);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ keyG = new myKeyGenerator(null, null, null);
+ assertNull("Algorithm must be null", keyG.getAlgorithm());
+ assertNull("Provider must be null", keyG.getProvider());
+
+ try {
+ keyG.init(params, null);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ try {
+ keyG.init(keysize, null);
+ fail("NullPointerException or InvalidParameterException must be thrown");
+ } catch (InvalidParameterException e) {
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm) </code> method Assertions:
+ * throws NullPointerException when algorithm is null throws
+ * NoSuchAlgorithmException when algorithm isnot available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testGetInstanceString01() throws NoSuchAlgorithmException {
+ try {
+ KeyGenerator.getInstance(null);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyGenerator.getInstance(invalidValues[i]);
+ fail("NoSuchAlgorithmException should be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm) </code> method
+ * Assertions: returns KeyGenerator object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testGetInstanceString02() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyGenerator keyG;
+ for (int i = 0; i < validValues.length; i++) {
+ keyG = KeyGenerator.getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", keyG.getAlgorithm(), validValues[i]);
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm, String provider)</code> method
+ * Assertions:
+ * throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm isnot available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString01() throws
+ NoSuchAlgorithmException, IllegalArgumentException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ KeyGenerator.getInstance(null, defaultProviderName);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyGenerator.getInstance(invalidValues[i], defaultProviderName);
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm, String provider)</code> method
+ * Assertions:
+ * throws IllegalArgumentException when provider is null or empty
+ * throws NoSuchProviderException when provider has not be configured
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString02() throws IllegalArgumentException,
+ NoSuchAlgorithmException, NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ String provider = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ KeyGenerator.getInstance(validValues[i], provider);
+ fail("IllegalArgumentException must be thrown when provider is null");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ KeyGenerator.getInstance(validValues[i], "");
+ fail("IllegalArgumentException must be thrown when provider is empty");
+ } catch (IllegalArgumentException e) {
+ }
+ for (int j = 1; j < invalidValues.length; j++) {
+ try {
+ KeyGenerator.getInstance(validValues[i], invalidValues[j]);
+ fail("NoSuchProviderException must be thrown (algorithm: "
+ .concat(validValues[i]).concat(" provider: ")
+ .concat(invalidValues[j]).concat(")"));
+ } catch (NoSuchProviderException e) {
+ }
+ }
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm, String provider)</code> method
+ * Assertions: returns KeyGenerator object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testGetInstanceStringString03() throws IllegalArgumentException,
+ NoSuchAlgorithmException, NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyGenerator keyG;
+ for (int i = 0; i < validValues.length; i++) {
+ keyG = KeyGenerator.getInstance(validValues[i], defaultProviderName);
+ assertEquals("Incorrect algorithm", keyG.getAlgorithm(), validValues[i]);
+ assertEquals("Incorrect provider", keyG.getProvider().getName(), defaultProviderName);
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm, Provider provider)</code> method
+ * Assertions:
+ * throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm isnot available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider01() throws NoSuchAlgorithmException,
+ IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ KeyGenerator.getInstance(null, defaultProvider);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyGenerator.getInstance(invalidValues[i], defaultProvider);
+ fail("NoSuchAlgorithmException must be thrown");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+ /*
+ * Test for <code> getInstance(String algorithm, Provider provider)</code> method
+ * Assertions:
+ * throws IllegalArgumentException when provider is null
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider02() throws NoSuchAlgorithmException,
+ IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ Provider provider = null;
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ KeyGenerator.getInstance(invalidValues[i], provider);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ /*
+ * Test for <code> getInstance(String algorithm, Provider provider)</code> method
+ * Assertions: returns KeyGenerator object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testGetInstanceStringProvider03() throws IllegalArgumentException,
+ NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyGenerator keyA;
+ for (int i = 0; i < validValues.length; i++) {
+ keyA = KeyGenerator.getInstance(validValues[i], defaultProvider);
+ assertEquals("Incorrect algorithm", keyA.getAlgorithm(), validValues[i]);
+ assertEquals("Incorrect provider", keyA.getProvider(), defaultProvider);
+ }
+ }
+
+ /*
+ * Test for <code>init(int keysize)</code> and
+ * <code>init(int keysize, SecureRandom random)</code> methods
+ * Assertion: throws InvalidParameterException if keysize is wrong
+ *
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "init",
+ args = {int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "init",
+ args = {int.class, java.security.SecureRandom.class}
+ )
+ })
+ public void testInitKey() throws Exception {
+ byte flag = 0xF;
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ if (defaultAlgorithm
+ .equals(validAlgorithmsKeyGenerator[validAlgorithmsKeyGenerator.length - 1])) {
+ return;
+ }
+ int[] size = { Integer.MIN_VALUE, -1, 0, 112, 168, Integer.MAX_VALUE };
+ KeyGenerator[] kgs = createKGs();
+ SecureRandom random = new SecureRandom();
+
+ for (int i = 0; i < kgs.length; i++) {
+ for (int j = 0; j < size.length; j++) {
+ try {
+ kgs[i].init(size[j]);
+ flag &= 0xE;
+ } catch (InvalidParameterException ignore) {
+ flag &= 0xD;
+ }
+
+ try {
+ kgs[i].init(size[j], random);
+ flag &= 0xB;
+ } catch (InvalidParameterException ignore) {
+ flag &= 0x7;
+ }
+ }
+ }
+ assertTrue(flag == 0);
+ }
+
+ /*
+ * Test for <code>init(AlgorithmParameterSpec params)</code> and
+ * <code>init(AlgorithmParameterSpec params, SecureRandom random)</code> methods
+ * Assertion: throws InvalidAlgorithmParameterException when params is null
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions only",
+ method = "init",
+ args = {java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions only",
+ method = "init",
+ args = {java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions only",
+ clazz = KeyGeneratorSpi.class,
+ method = "engineInit",
+ args = {java.security.spec.AlgorithmParameterSpec.class, java.security.SecureRandom.class}
+ )
+ })
+ public void testInitParams() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ KeyGenerator [] kgs = createKGs();
+ AlgorithmParameterSpec aps = null;
+
+ for (int i = 0; i < kgs.length; i++) {
+ try {
+ kgs[i].init(aps);
+ fail("InvalidAlgorithmParameterException must be thrown");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ try {
+ kgs[i].init(aps, new SecureRandom());
+ fail("InvalidAlgorithmParameterException must be thrown");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ }
+ }
+
+ /*
+ * Test for <code>generateKey()</code> and
+ * <code>init(SecureRandom random)</code> methods
+ * <code>init(int keysize, SecureRandom random)</code> methods
+ * <code>init(int keysize)</code> methods
+ * <code>init(AlgorithmParameterSpec params, SecureRandom random)</code> methods
+ * <code>init(AlgorithmParameterSpec params)</code> methods
+ * Assertions:
+ * initializes KeyGenerator;
+ * returns SecretKey object
+ *
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "generateKey",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGeneratorSpi.class,
+ method = "engineGenerateKey",
+ args = {}
+ )
+ })
+ public void testGenerateKey() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ SecretKey sKey;
+ String dAl = defaultAlgorithm.toUpperCase();
+
+ KeyGenerator[] kgs = createKGs();
+
+ for (int i = 0; i < kgs.length; i++) {
+ sKey = kgs[i].generateKey();
+ assertEquals("Incorrect algorithm", sKey.getAlgorithm()
+ .toUpperCase(), dAl);
+ kgs[i].init(new SecureRandom());
+ sKey = kgs[i].generateKey();
+ assertEquals("Incorrect algorithm", sKey.getAlgorithm()
+ .toUpperCase(), dAl);
+ kgs[i].init(defaultKeySize);
+ sKey = kgs[i].generateKey();
+ assertEquals("Incorrect algorithm", sKey.getAlgorithm()
+ .toUpperCase(), dAl);
+ kgs[i].init(defaultKeySize, new SecureRandom());
+ sKey = kgs[i].generateKey();
+ assertEquals("Incorrect algorithm", sKey.getAlgorithm()
+ .toUpperCase(), dAl);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void test_getAlgorithm() throws NoSuchAlgorithmException {
+ KeyGenerator kg = null;
+
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[i]);
+ assertEquals(validAlgorithmsKeyGenerator[i], kg.getAlgorithm());
+ }
+
+ kg = new myKeyGenerator(null, null, null);
+ assertNull(kg.getAlgorithm());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider () throws NoSuchAlgorithmException {
+ KeyGenerator kg = null;
+
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[i]);
+ assertNotNull(kg.getProvider());
+ }
+
+ kg = new myKeyGenerator(null, null, null);
+ assertNull(kg.getProvider());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {int.class, java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGeneratorSpi.class,
+ method = "engineInit",
+ args = {int.class, java.security.SecureRandom.class}
+ )
+ })
+ public void test_initILjava_security_SecureRandom() throws NoSuchAlgorithmException {
+ SecureRandom random = null;
+ KeyGenerator kg = null;
+
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[i]);
+ random = new SecureRandom();
+ kg.init(validKeySizes[i], random);
+ assertNotNull(kg.getProvider());
+ }
+
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[0]);
+
+ try {
+ kg.init(5, random);
+ fail("InvalidParameterException expected");
+ } catch (InvalidParameterException e) {
+ //expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.SecureRandom.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGeneratorSpi.class,
+ method = "engineInit",
+ args = {java.security.SecureRandom.class}
+ )
+ })
+ public void test_Ljava_security_SecureRandom() throws NoSuchAlgorithmException {
+ SecureRandom random = null;
+ KeyGenerator kg = null;
+
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[i]);
+ random = new SecureRandom();
+ kg.init(random);
+ assertNotNull(kg.getProvider());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "init",
+ args = {java.security.spec.AlgorithmParameterSpec.class}
+ )
+ public void test_initLjava_security_spec_AlgorithmParameterSpec ()
+ throws Exception {
+ KeyGenerator kg = null;
+
+ IvParameterSpec aps = null;
+ SecureRandom sr = new SecureRandom();
+
+ byte[] iv = null;
+ iv = new byte[8];
+ sr.nextBytes(iv);
+ aps = new IvParameterSpec(iv);
+
+ for (int i = 0; i < validAlgorithmsKeyGenerator.length; i++) {
+ kg = KeyGenerator.getInstance(validAlgorithmsKeyGenerator[i]);
+ try {
+ kg.init(aps);
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ assertNotNull(kg.getProvider());
+ }
+ }
+}
+
+/**
+ * Additional class for KeyGenerator constructor verification
+ */
+class myKeyGenerator extends KeyGenerator {
+
+ public myKeyGenerator(KeyGeneratorSpi keyAgreeSpi, Provider provider,
+ String algorithm) {
+ super(keyAgreeSpi, provider, algorithm);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java
new file mode 100644
index 0000000..270adaa
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacSpiTest.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.spec.SecretKeySpec;
+import javax.crypto.MacSpi;
+
+import org.apache.harmony.crypto.tests.support.MyMacSpi;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(MacSpi.class)
+/**
+ * Tests for <code>MacSpi</code> class constructors and methods.
+ *
+ */
+
+public class MacSpiTest extends TestCase {
+class Mock_MacSpi extends MyMacSpi {
+
+ @Override
+ protected byte[] engineDoFinal() {
+ return super.engineDoFinal();
+ }
+
+ @Override
+ protected int engineGetMacLength() {
+ return super.engineGetMacLength();
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(key, params);
+ }
+
+ @Override
+ protected void engineReset() {
+ super.engineReset();
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ super.engineUpdate(input);
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ super.engineUpdate(input, offset, len);
+ }
+
+}
+
+class Mock_MacSpi1 extends MyMacSpi1 {
+
+ @Override
+ protected byte[] engineDoFinal() {
+ return super.engineDoFinal();
+ }
+
+ @Override
+ protected int engineGetMacLength() {
+ return super.engineGetMacLength();
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(key, params);
+ }
+
+ @Override
+ protected void engineReset() {
+ super.engineReset();
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ super.engineUpdate(input);
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ super.engineUpdate(input, offset, len);
+ }
+
+ protected void engineUpdate(ByteBuffer input) {
+ super.engineUpdate(input);
+ }
+
+}
+
+
+class Mock_MacSpi2 extends MyMacSpi2 {
+
+ @Override
+ protected byte[] engineDoFinal() {
+ return super.engineDoFinal();
+ }
+
+ @Override
+ protected int engineGetMacLength() {
+ return super.engineGetMacLength();
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException {
+ super.engineInit(key, params);
+ }
+
+ @Override
+ protected void engineReset() {
+ super.engineReset();
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ super.engineUpdate(input);
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ super.engineUpdate(input, offset, len);
+ }
+
+ protected void engineUpdate(ByteBuffer input) {
+ super.engineUpdate(input);
+ }
+
+}
+
+
+ /**
+ * Test for <code>MacSpi</code> constructor
+ * Assertion: constructs MacSpi
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All others methods are abstract.",
+ method = "MacSpi",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All others methods are abstract.",
+ method = "engineUpdate",
+ args = {java.nio.ByteBuffer.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All others methods are abstract.",
+ method = "clone",
+ args = {}
+ )
+ })
+ public void testMacSpiTests01() throws Exception {
+ Mock_MacSpi mSpi = new Mock_MacSpi();
+
+ byte [] bb1 = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(bb1, "SHA1");
+
+ assertEquals("Incorrect MacLength", mSpi.engineGetMacLength(), 0);
+
+ try {
+ mSpi.engineInit(null, null);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+
+ mSpi.engineInit(sks, null);
+
+ byte[] bb = mSpi.engineDoFinal();
+ assertEquals(bb.length, 0);
+ try {
+ mSpi.clone();
+ fail("CloneNotSupportedException was not thrown as expected");
+ } catch (CloneNotSupportedException e) {
+ }
+
+ Mock_MacSpi1 mSpi1 = new Mock_MacSpi1();
+ mSpi1.clone();
+
+ byte [] bbb = new byte[10];
+ for (int i = 0; i < bbb.length; i++) {
+ bbb[i] = (byte)i;
+ }
+ try {
+ mSpi1.engineInit(null, null);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ mSpi1.engineInit(sks, null);
+
+ ByteBuffer byteBuf = ByteBuffer.allocate(10);
+ byteBuf.put(bbb);
+ byteBuf.position(5);
+ int beforeUp = byteBuf.remaining();
+ mSpi1.engineUpdate(byteBuf);
+ bb = mSpi1.engineDoFinal();
+ assertEquals("Incorrect result of engineDoFinal", bb.length, beforeUp);
+
+ Mock_MacSpi2 mSpi2 = new Mock_MacSpi2();
+
+ mSpi2.engineInit(null, null);
+ mSpi2.engineInit(sks, null);
+
+ try {
+ mSpi2.clone();
+ } catch (CloneNotSupportedException e) {
+ }
+
+ byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
+ byteBuf = ByteBuffer.allocate(5);
+ byteBuf.put(bbuf);
+ byteBuf.position(5);
+ if (!byteBuf.hasRemaining()) {
+ mSpi2.engineUpdate(byteBuf);
+ }
+ }
+}
+
+
+class MyMacSpi1 extends MyMacSpi {
+ public Object clone() throws CloneNotSupportedException {
+ return new MyMacSpi1();
+ }
+}
+
+class MyMacSpi2 extends MacSpi {
+ protected int engineGetMacLength() {
+ return 0;
+ }
+
+ protected void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ }
+
+ protected void engineUpdate(byte input) {
+ }
+
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ }
+
+ protected byte[] engineDoFinal() {
+ return new byte[0];
+ }
+
+ protected void engineReset() {
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
new file mode 100644
index 0000000..750342c
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -0,0 +1,1189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.PSSParameterSpec;
+
+import javax.crypto.Mac;
+import javax.crypto.MacSpi;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.DHGenParameterSpec;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.harmony.crypto.tests.support.MyMacSpi;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+
+import junit.framework.TestCase;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+@TestTargetClass(Mac.class)
+/**
+ * Tests for Mac class constructors and methods
+ *
+ */
+
+public class MacTest extends TestCase {
+
+ public static final String srvMac = "Mac";
+
+ private static String defaultAlgorithm = null;
+
+ private static String defaultProviderName = null;
+
+ private static Provider defaultProvider = null;
+
+ private static boolean DEFSupported = false;
+
+ private static final String NotSupportedMsg = "There is no suitable provider for Mac";
+
+ private static final String[] invalidValues = SpiEngUtils.invalidValues;
+
+ private static String[] validValues = new String[3];
+
+ public static final String validAlgorithmsMac [] =
+ {"HmacSHA1", "HmacMD5", "HmacSHA256", "HmacSHA384", "HmacSHA512"};
+
+
+ static {
+ for (int i = 0; i < validAlgorithmsMac.length; i++) {
+ defaultProvider = SpiEngUtils.isSupport(validAlgorithmsMac[i],
+ srvMac);
+ DEFSupported = (defaultProvider != null);
+ if (DEFSupported) {
+ defaultAlgorithm = validAlgorithmsMac[i];
+ defaultProviderName = defaultProvider.getName();
+ validValues[0] = defaultAlgorithm;
+ validValues[1] = defaultAlgorithm.toUpperCase();
+ validValues[2] = defaultAlgorithm.toLowerCase();
+ break;
+ }
+ }
+ }
+
+ private Mac [] createMacs() {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return null;
+ }
+ try {
+ Mac m [] = new Mac[3];
+ m[0] = Mac.getInstance(defaultAlgorithm);
+ m[1] = Mac.getInstance(defaultAlgorithm, defaultProvider);
+ m[2] = Mac.getInstance(defaultAlgorithm, defaultProviderName);
+ return m;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm)</code> method
+ * Assertion:
+ * throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testMac01() {
+ try {
+ Mac.getInstance(null);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ Mac.getInstance(invalidValues[i]);
+ fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
+ .concat(invalidValues[i]));
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm)</code> method
+ * Assertion: returns Mac object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testMac02() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac mac;
+ for (int i = 0; i < validValues.length; i++) {
+ mac = Mac.getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
+ }
+ }
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code> method
+ * Assertion:
+ * throws IllegalArgumentException when provider is null or empty
+ * throws NoSuchProviderException when provider is not available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testMac03() throws NoSuchAlgorithmException, NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ String provider = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ Mac.getInstance(validValues[i], provider);
+ fail("IllegalArgumentException must be thrown when provider is null");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ Mac.getInstance(validValues[i], "");
+ fail("IllegalArgumentException must be thrown when provider is empty");
+ } catch (IllegalArgumentException e) {
+ }
+ for (int j = 1; j < invalidValues.length; j++) {
+ try {
+ Mac.getInstance(validValues[i], invalidValues[j]);
+ fail("NoSuchProviderException must be thrown (algorithm: "
+ .concat(validValues[i]).concat(" provider: ")
+ .concat(invalidValues[j]).concat(")"));
+ } catch (NoSuchProviderException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code> method
+ * Assertion:
+ * throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testMac04() throws NoSuchAlgorithmException,
+ IllegalArgumentException, NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ try {
+ Mac.getInstance(null, defaultProviderName);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ Mac.getInstance(invalidValues[i], defaultProviderName);
+ fail("NoSuchAlgorithmException must be throws when algorithm is not available: "
+ .concat(invalidValues[i]));
+ } catch( NoSuchAlgorithmException e) {
+ }
+ }
+ }
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code> method
+ * Assertion: returns Mac object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testMac05() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac mac;
+ for (int i = 0; i < validValues.length; i++) {
+ mac = Mac.getInstance(validValues[i], defaultProviderName);
+ assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
+ assertEquals("Incorrect provider", mac.getProvider().getName(),
+ defaultProviderName);
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code> method
+ * Assertion: throws IllegalArgumentException when provider is null
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testMac06() throws NoSuchAlgorithmException, NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Provider provider = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ Mac.getInstance(validValues[i], provider);
+ fail("IllegalArgumentException must be thrown when provider is null");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code> method
+ * Assertion:
+ * throws NullPointerException when algorithm is null
+ * throws NoSuchAlgorithmException when algorithm is not available
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testMac07() throws NoSuchAlgorithmException,
+ NoSuchProviderException, IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ try {
+ Mac.getInstance(null, defaultProvider);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown when algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ Mac.getInstance(invalidValues[i], defaultProvider);
+ fail("NoSuchAlgorithmException must be thrown when algorithm is not available: "
+ .concat(invalidValues[i]));
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code> method
+ * Assertion: returns Mac object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testMac08() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac mac;
+ for (int i = 0; i < validValues.length; i++) {
+ mac = Mac.getInstance(validValues[i], defaultProvider);
+ assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
+ assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
+ }
+ }
+ /**
+ * Test for <code>update</code> and <code>doFinal</code> methods
+ * Assertion: throws IllegalStateException when Mac is not initialized
+ * @throws Exception
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "doFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineDoFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "doFinal",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "doFinal",
+ args = {byte[].class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "update",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ method = "update",
+ args = {java.nio.ByteBuffer.class}
+ )
+ })
+ public void testMac09() throws Exception {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] buf = new byte[10];
+ ByteBuffer bBuf = ByteBuffer.wrap(buf, 0, 10);
+ byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ try {
+ macs[i].update((byte)0);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].update(buf);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].update(buf, 0, 3);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].update(bBuf);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].doFinal();
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].doFinal(new byte[10]);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+ try {
+ macs[i].doFinal(new byte[10], 0);
+ fail("IllegalStateException must be thrown");
+ } catch (IllegalStateException e) {
+ }
+
+ macs[i].init(sks);
+ try {
+ macs[i].doFinal(new byte[1], 0);
+ fail("ShortBufferException expected");
+ } catch (ShortBufferException e) {
+ //expected
+ }
+ }
+ }
+ /**
+ * Test for <code>doFinal(byte[] output, int outOffset)</code> method
+ * Assertion:
+ * throws ShotBufferException when outOffset is negative or
+ * outOffset >= output.length or when given buffer is small
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks ShortBufferException",
+ method = "doFinal",
+ args = {byte[].class, int.class}
+ )
+ public void testMac10() throws NoSuchAlgorithmException,
+ NoSuchProviderException, IllegalArgumentException,
+ IllegalStateException, InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac[] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte[] b = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+ byte[] byteA = new byte[b.length];
+ SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(sks);
+ try {
+ macs[i].doFinal(null, 10);
+ fail("ShortBufferException must be thrown");
+ } catch (ShortBufferException e) {
+ }
+ try {
+ macs[i].doFinal(byteA, -4);
+ fail("ShortBufferException must be thrown");
+ } catch (ShortBufferException e) {
+ }
+ try {
+ macs[i].doFinal(byteA, 10);
+ fail("ShortBufferException must be thrown");
+ } catch (ShortBufferException e) {
+ }
+ try {
+ macs[i].doFinal(new byte[1], 0);
+ fail("ShortBufferException must be thrown");
+ } catch (ShortBufferException e) {
+ }
+ byte[] res = macs[i].doFinal();
+ try {
+ macs[i].doFinal(new byte[res.length - 1], 0);
+ fail("ShortBufferException must be thrown");
+ } catch (ShortBufferException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>doFinal(byte[] output, int outOffset)</code> and
+ * <code>doFinal()</code> methods Assertion: Mac result is stored in
+ * output buffer
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "doFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineDoFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "doFinal",
+ args = {byte[].class, int.class}
+ )
+ })
+ public void testMac11() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, IllegalStateException,
+ InvalidKeyException, ShortBufferException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
+ SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(scs);
+ byte [] res1 = macs[i].doFinal();
+ byte [] res2 = new byte[res1.length + 10];
+ macs[i].doFinal(res2, 0);
+ for (int j = 0; j < res1.length; j++) {
+ assertEquals("Not equals byte number: "
+ .concat(Integer.toString(j)), res1[j], res2[j]);
+ }
+ }
+ }
+ /**
+ * Test for <code>doFinal(byte[] input)</code> method
+ * Assertion: update Mac and returns result
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "doFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineDoFinal",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "doFinal",
+ args = {byte[].class}
+ )
+ })
+ public void testMac12() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, IllegalStateException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
+ byte [] upd = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1, (byte)0};
+ SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(scs);
+ byte [] res1 = macs[i].doFinal();
+ byte [] res2 = macs[i].doFinal();
+ assertEquals("Results are not the same", res1.length, res2.length);
+ for(int t = 0; t < res1.length; t++) {
+ assertEquals("Results are not the same", res1[t], res2[t]);
+ }
+ res2 = macs[i].doFinal(upd);
+ macs[i].update(upd);
+ res1 = macs[i].doFinal();
+ assertEquals("Results are not the same", res1.length, res2.length);
+ for(int t = 0; t < res1.length; t++) {
+ assertEquals("Results are not the same", res1[t], res2[t]);
+ }
+ }
+ }
+
+ /**
+ * Test for <code>update(byte[] input, int outset, int len)</code> method
+ * Assertion: throws IllegalArgumentException when offset or len is negative,
+ * offset + len >= input.length
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalArgumentException",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ )
+ })
+ public void testMac13() throws NoSuchAlgorithmException,
+ NoSuchProviderException, IllegalArgumentException, IllegalStateException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
+ SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(scs);
+ try {
+ macs[i].update(b, -10, b.length);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ macs[i].update(b, 0, -10);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ macs[i].update(b, 0, b.length + 1);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ macs[i].update(b, b.length - 1, 2);
+ fail("IllegalArgumentException must be thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+ /**
+ * Test for <code>update(byte[] input, int outset, int len)</code> and
+ * <code>update(byte[] input</code>
+ * methods
+ * Assertion: updates Mac
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "update",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality.",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ )
+ })
+ public void testMac14() throws NoSuchAlgorithmException,
+ NoSuchProviderException, IllegalArgumentException, IllegalStateException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
+ byte [] upd1 = {(byte)0, (byte)1, (byte)5, (byte)4, (byte)3, (byte)2};
+ byte [] upd2 = {(byte)5, (byte)4, (byte)3, (byte)2};
+ byte [] res1;
+ byte [] res2;
+ SecretKeySpec scs = new SecretKeySpec(b, "SHA1");
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(scs);
+ macs[i].update(upd1, 2, 4);
+ res1 = macs[i].doFinal();
+ macs[i].init(scs);
+ macs[i].update(upd2);
+ res2 = macs[i].doFinal();
+ assertEquals("Results are not the same", res1.length, res2.length);
+ for(int t = 0; t < res1.length; t++) {
+ assertEquals("Results are not the same", res1[t], res2[t]);
+ }
+ macs[i].init(scs);
+ macs[i].update((byte)5);
+ res1 = macs[i].doFinal();
+ macs[i].init(scs);
+ macs[i].update(upd1,2,1);
+ res2 = macs[i].doFinal();
+ assertEquals("Results are not the same", res1.length, res2.length);
+ for(int t = 0; t < res1.length; t++) {
+ assertEquals("Results are not the same", res1[t], res2[t]);
+ }
+ }
+ }
+ /**
+ * Test for <code>clone()</code> method
+ * Assertion: returns Mac object or throws CloneNotSupportedException
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "clone",
+ args = {}
+ )
+ public void testMacClone() throws NoSuchAlgorithmException, CloneNotSupportedException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ for (int i = 0; i < macs.length; i++) {
+ try {
+ Mac mac1 = (Mac) macs[i].clone();
+ assertEquals(mac1.getAlgorithm(), macs[i].getAlgorithm());
+ assertEquals(mac1.getProvider(), macs[i].getProvider());
+ assertFalse(macs[i].equals(mac1));
+ } catch (CloneNotSupportedException e) {
+ }
+ }
+ }
+ /**
+ * Test for
+ * <code>init(Key key, AlgorithmParameterSpec params)</code>
+ * <code>init(Key key)</code>
+ * methods
+ * Assertion: throws InvalidKeyException and InvalidAlgorithmParameterException
+ * when parameters are not appropriate
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions",
+ method = "init",
+ args = {java.security.Key.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions",
+ method = "init",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks exceptions",
+ clazz = MacSpi.class,
+ method = "engineInit",
+ args = {java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ )
+ })
+ public void testInit() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] b = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
+ DHGenParameterSpec algPS = new DHGenParameterSpec(1, 2);
+ PSSParameterSpec algPSS = new PSSParameterSpec(20);
+ SecretKeySpec sks1 = new SecretKeySpec(b, "RSA");
+
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(sks);
+ try {
+ macs[i].init(sks1, algPSS);
+ fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+ try {
+ macs[i].init(sks, algPS);
+ fail("init(..) accepts incorrect AlgorithmParameterSpec parameter");
+ } catch (InvalidAlgorithmParameterException e) {
+ }
+
+ try {
+ macs[i].init(null, null);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {
+ }
+
+ try {
+ macs[i].init(null);
+ fail("InvalidKeyException must be thrown");
+ } catch (InvalidKeyException e) {
+ }
+// macs[i].init(sks, null);
+ }
+ }
+
+ /**
+ * Test for <code>update(ByteBuffer input)</code>
+ * <code>update(byte[] input, int offset, int len)</code>
+ * methods
+ * Assertion: processes Mac; if input is null then do nothing
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality",
+ method = "update",
+ args = {java.nio.ByteBuffer.class}
+ )
+ })
+ public void testUpdateByteBuffer01() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
+ ByteBuffer byteNull = null;
+ ByteBuffer byteBuff = ByteBuffer.allocate(0);
+ byte [] bb1;
+ byte [] bb2;
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(sks);
+ bb1 = macs[i].doFinal();
+ try {
+ macs[i].update(byteNull);
+ fail("IllegalArgumentException must be thrown because buffer is null");
+ } catch (IllegalArgumentException e) {
+ }
+ macs[i].update(byteBuff);
+ bb2 = macs[i].doFinal();
+ for (int t = 0; t < bb1.length; t++) {
+ assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
+ }
+ macs[i].init(sks);
+ bb1 = macs[i].doFinal();
+ macs[i].update(null, 0, 0);
+ bb2 = macs[i].doFinal();
+ for (int t = 0; t < bb1.length; t++) {
+ assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
+ }
+ }
+ }
+ /**
+ * Test for <code>update(ByteBuffer input)</code>
+ * <code>update(byte[] input, int offset, int len)</code>
+ * methods
+ * Assertion: processes Mac
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality",
+ method = "update",
+ args = {java.nio.ByteBuffer.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks functionality",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks IllegalStateException only but for all methods. Not enough for doFinal(byte[] output, int outOffset) - it can throw ShortBufferException",
+ clazz = MacSpi.class,
+ method = "engineUpdate",
+ args = {byte[].class, int.class, int.class}
+ )
+ })
+ public void testUpdateByteBuffer02() throws NoSuchAlgorithmException, NoSuchProviderException,
+ IllegalArgumentException, IllegalStateException, InvalidAlgorithmParameterException,
+ InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
+ byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
+ ByteBuffer byteBuf;
+ byte [] bb1;
+ byte [] bb2;
+ for (int i = 0; i < macs.length; i++) {
+ byteBuf = ByteBuffer.allocate(5);
+ byteBuf.put(bbuf);
+ byteBuf.position(2);
+ macs[i].init(sks);
+ macs[i].update(byteBuf);
+ bb1 = macs[i].doFinal();
+
+ macs[i].init(sks);
+ macs[i].update(bbuf, 2, 3);
+ bb2 = macs[i].doFinal();
+ for (int t = 0; t < bb1.length; t++) {
+ assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
+ }
+ }
+ }
+ /**
+ * Test for <code>clone()</code> method
+ * Assertion: clone if provider is clo
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "clone",
+ args = {}
+ )
+ public void testClone() {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ Mac res;
+ for (int i = 0; i < macs.length; i++) {
+ try {
+ res = (Mac)macs[i].clone();
+ assertTrue("Object should not be equals", !macs[i].equals(res));
+ assertEquals("Incorrect class", macs[i].getClass(), res.getClass());
+ } catch (CloneNotSupportedException e) {
+ }
+ }
+ }
+ /**
+ * Test for <code>getMacLength()</code> method
+ * Assertion: return Mac length
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMacLength",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = MacSpi.class,
+ method = "engineGetMacLength",
+ args = {}
+ )
+ })
+ public void testGetMacLength() {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ for (int i = 0; i < macs.length; i++) {
+ assertTrue("Length should be positive", (macs[i].getMacLength() >= 0));
+ }
+ }
+
+ /**
+ * Test for <code>reset()</code> method
+ * Assertion: return Mac length
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "reset",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = MacSpi.class,
+ method = "engineReset",
+ args = {}
+ )
+ })
+ public void testReset() throws InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ Mac [] macs = createMacs();
+ assertNotNull("Mac objects were not created", macs);
+ byte [] bb = {(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
+ SecretKeySpec sks = new SecretKeySpec(bb, "SHA1");
+ byte [] bbuf = {(byte)5, (byte)4, (byte)3, (byte)2, (byte)1};
+ byte [] bb1;
+ byte [] bb2;
+ for (int i = 0; i < macs.length; i++) {
+ macs[i].init(sks);
+ bb1 = macs[i].doFinal();
+ macs[i].reset();
+ bb2 = macs[i].doFinal();
+ assertEquals("incorrect result",bb1.length, bb2.length);
+ for (int t = 0; t < bb1.length; t++) {
+ assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
+ }
+ macs[i].reset();
+ macs[i].update(bbuf);
+ bb1 = macs[i].doFinal();
+ macs[i].reset();
+ macs[i].update(bbuf, 0, bbuf.length);
+ bb2 = macs[i].doFinal();
+ assertEquals("incorrect result",bb1.length, bb2.length);
+ for (int t = 0; t < bb1.length; t++) {
+ assertEquals("Incorrect doFinal result", bb1[t], bb2[t]);
+ }
+ }
+ }
+ /**
+ * Test for <code>Mac</code> constructor
+ * Assertion: returns Mac object
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "Mac",
+ args = {javax.crypto.MacSpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void testMacConstructor() throws NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException {
+ if (!DEFSupported) {
+ fail(NotSupportedMsg);
+ return;
+ }
+ MacSpi spi = new MyMacSpi();
+ Mac mac = new myMac(spi, defaultProvider, defaultAlgorithm);
+ assertEquals("Incorrect algorithm", mac.getAlgorithm(),
+ defaultAlgorithm);
+ assertEquals("Incorrect provider", mac.getProvider(), defaultProvider);
+ try {
+ mac.init(null, null);
+ fail("Exception should be thrown because init(..) uses incorrect parameters");
+ } catch (Exception e) {
+ }
+ assertEquals("Invalid mac length", mac.getMacLength(), 0);
+
+ mac = new myMac(null, null, null);
+ assertNull("Algorithm must be null", mac.getAlgorithm());
+ assertNull("Provider must be null", mac.getProvider());
+ try {
+ mac.init(null, null);
+ fail("Exception should be thrown because init(..) uses incorrect parameters");
+ } catch (Exception e) {
+ }
+ try {
+ mac.getMacLength();
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void test_getAlgorithm() throws NoSuchAlgorithmException {
+ Mac mac;
+ for (int i = 0; i < validValues.length; i++) {
+ mac = Mac.getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", mac.getAlgorithm(), validValues[i]);
+ }
+
+ mac = new Mock_Mac(null, null, null);
+ assertNull(mac.getAlgorithm());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider() throws NoSuchAlgorithmException {
+ Mac mac;
+ for (int i = 0; i < validValues.length; i++) {
+ mac = Mac.getInstance(validValues[i]);
+ assertNotNull(mac.getProvider());
+ }
+
+ mac = new Mock_Mac(null, null, null);
+ assertNull(mac.getProvider());
+ }
+
+ class Mock_Mac extends Mac {
+ protected Mock_Mac(MacSpi arg0, Provider arg1, String arg2) {
+ super(arg0, arg1, arg2);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(MacTest.class);
+ }
+
+ public static void main(String args[]) {
+ junit.textui.TestRunner.run(suite());
+
+ }
+}
+/**
+ * Additional class for Mac constructor verification
+ */
+class myMac extends Mac {
+
+ public myMac(MacSpi macSpi, Provider provider,
+ String algorithm) {
+ super(macSpi, provider, algorithm);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java
new file mode 100644
index 0000000..da4a94d
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NoSuchPaddingExceptionTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.NoSuchPaddingException;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(NoSuchPaddingException.class)
+/**
+ * Tests for <code>NoSuchPaddingException</code> class constructors and
+ * methods.
+ *
+ */
+public class NoSuchPaddingExceptionTest extends TestCase {
+
+ static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+ static Throwable tCause = new Throwable("Throwable for exception");
+
+ /**
+ * Test for <code>NoSuchPaddingException()</code> constructor Assertion:
+ * constructs NoSuchPaddingException with no detail message
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "NoSuchPaddingException",
+ args = {}
+ )
+ public void testNoSuchPaddingException01() {
+ NoSuchPaddingException tE = new NoSuchPaddingException();
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+
+ /**
+ * Test for <code>NoSuchPaddingException(String)</code> constructor
+ * Assertion: constructs NoSuchPaddingException with detail message msg.
+ * Parameter <code>msg</code> is not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "NoSuchPaddingException",
+ args = {java.lang.String.class}
+ )
+ public void testNoSuchPaddingException02() {
+ NoSuchPaddingException tE;
+ for (int i = 0; i < msgs.length; i++) {
+ tE = new NoSuchPaddingException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), tE
+ .getMessage(), msgs[i]);
+ assertNull("getCause() must return null", tE.getCause());
+ }
+ }
+
+ /**
+ * Test for <code>NoSuchPaddingException(String)</code> constructor
+ * Assertion: constructs NoSuchPaddingException when <code>msg</code> is
+ * null
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "NoSuchPaddingException",
+ args = {java.lang.String.class}
+ )
+ public void testNoSuchPaddingException03() {
+ String msg = null;
+ NoSuchPaddingException tE = new NoSuchPaddingException(msg);
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NullCipherTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NullCipherTest.java
new file mode 100644
index 0000000..f521690
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/NullCipherTest.java
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Boris V. Kuznetsov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherSpi;
+import javax.crypto.NullCipher;
+import javax.crypto.spec.SecretKeySpec;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(NullCipher.class)
+/**
+ *
+ * Tests for NullCipher
+ */
+public class NullCipherTest extends TestCase {
+
+ private Cipher c;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ c = new NullCipher();
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Class checks inherited methods.",
+ method = "getAlgorithm",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Class checks inherited methods.",
+ method = "NullCipher",
+ args = {}
+ )
+ })
+ public void testGetAlgorithm() {
+ c.getAlgorithm();
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks inherited method from Cipher.",
+ method = "getBlockSize",
+ args = {}
+ )
+ public void testGetBlockSize() {
+ assertEquals("Incorrect BlockSize", 1, c.getBlockSize());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "IllegalStateException checking missed. Checks inherited method from Cipher.",
+ method = "getOutputSize",
+ args = {int.class}
+ )
+ public void testGetOutputSize() {
+ assertEquals("Incorrect OutputSize", 111, c.getOutputSize(111));
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks inherited method from Cipher.",
+ method = "getIV",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks inherited method from Cipher.",
+ clazz = CipherSpi.class,
+ method = "engineGetIV",
+ args = {}
+ )
+ })
+ public void testGetIV() {
+ assertTrue("Incorrect IV", Arrays.equals(c.getIV(), new byte[8]));
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks inherited method from Cipher.",
+ method = "getParameters",
+ args = {}
+ )
+ public void testGetParameters() {
+ assertNull("Incorrect Parameters", c.getParameters());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks inherited method from Cipher.",
+ method = "getExemptionMechanism",
+ args = {}
+ )
+ public void testGetExemptionMechanism() {
+ assertNull("Incorrect ExemptionMechanism", c.getExemptionMechanism());
+ }
+
+ /*
+ * Class under test for void init(int, Key)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "InvalidKeyException checking missed. Checks inherited method from Cipher.",
+ method = "init",
+ args = {int.class, java.security.Key.class}
+ )
+ public void testInitintKey() throws Exception {
+ c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[1], "algorithm"));
+
+ }
+
+ /*
+ * Class under test for void init(int, Key, SecureRandom)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "InvalidKeyException checking missed. Checks inherited method from Cipher.",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.SecureRandom.class}
+ )
+ public void testInitintKeySecureRandom() throws Exception {
+ c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[1],
+ "algorithm"), new SecureRandom());
+ }
+
+ /*
+ * Class under test for void init(int, Key, AlgorithmParameterSpec)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "init",
+ args = {int.class, java.security.Key.class, java.security.spec.AlgorithmParameterSpec.class}
+ )
+ public void testInitintKeyAlgorithmParameterSpec() throws Exception {
+ class myAlgorithmParameterSpec implements java.security.spec.AlgorithmParameterSpec {}
+ c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(new byte[1],
+ "algorithm"), new myAlgorithmParameterSpec());
+ }
+
+ /*
+ * Class under test for byte[] update(byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "IllegalStateException checking missed. Checks inherited method from Cipher.",
+ method = "update",
+ args = {byte[].class}
+ )
+ public void testUpdatebyteArray() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = c.update(b);
+ assertEquals("different length", b.length, r.length);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for byte[] update(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "IllegalStateException checking missed. Checks inherited method from Cipher.",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testUpdatebyteArrayintint() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = c.update(b, 0, 5);
+ assertEquals("different length", b.length, r.length);
+ assertTrue("different content", Arrays.equals(b, r));
+
+ r = c.update(b, 1, 3);
+ assertEquals("different length", 3, r.length);
+ for (int i = 0; i < 3; i++) {
+ assertEquals("different content", b[i + 1], r[i]);
+ }
+ }
+
+ /*
+ * Class under test for int update(byte[], int, int, byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "update",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void testUpdatebyteArrayintintbyteArray() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = new byte[5];
+ c.update(b, 0, 5, r);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for int update(byte[], int, int, byte[], int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "update",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ public void testUpdatebyteArrayintintbyteArrayint() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = new byte[5];
+ c.update(b, 0, 5, r, 0);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for byte[] doFinal()
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {}
+ )
+ public void testDoFinal() throws Exception {
+ assertNull("doFinal failed", c.doFinal());
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class}
+ )
+ public void testDoFinalbyteArrayint() throws Exception {
+ byte [] r = new byte[5];
+ assertEquals("doFinal failed", 0, c.doFinal(r, 0));
+ }
+
+ /*
+ * Class under test for byte[] doFinal(byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class}
+ )
+ public void testDoFinalbyteArray() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = null;
+ r = c.doFinal(b);
+ assertEquals("different length", b.length, r.length);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for byte[] doFinal(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testDoFinalbyteArrayintint() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = null;
+ r = c.doFinal(b, 0, 5);
+ assertEquals("different length", b.length, r.length);
+ assertTrue("different content", Arrays.equals(b, r));
+
+ r = c.doFinal(b, 1, 3);
+ assertEquals("different length", 3, r.length);
+ for (int i = 0; i < 3; i++) {
+ assertEquals("different content", b[i + 1], r[i]);
+ }
+ }
+
+ /*
+ * Class under test for byte[] update(byte[], int, int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "update",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testUpdatebyteArrayintint2() {
+ //Regression for HARMONY-758
+ try {
+ new NullCipher().update(new byte[1], 1, Integer.MAX_VALUE);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void testDoFinalbyteArrayintintbyteArray() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = new byte[5];
+ c.doFinal(b, 0, 5, r);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void testDoFinalbyteArrayintintbyteArray2() throws Exception {
+ //Regression for HARMONY-758
+ try {
+ new NullCipher().update(new byte[1], 1, Integer.MAX_VALUE,
+ new byte[1]);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[])
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class}
+ )
+ public void testDoFinalbyteArrayintintbyteArray3() throws Exception {
+ //Regression for HARMONY-758
+ try {
+ new NullCipher().update(new byte[1], 0, 1, new byte[0]);
+ fail("Expected IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[], int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ public void testDoFinalbyteArrayintintbyteArrayint() throws Exception {
+ byte [] b = {1, 2, 3, 4, 5};
+ byte [] r = new byte[5];
+ c.doFinal(b, 0, 5, r, 0);
+ assertTrue("different content", Arrays.equals(b, r));
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[], int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ public void testDoFinalbyteArrayintintbyteArrayint2() throws Exception {
+ //Regression for HARMONY-758
+ try {
+ new NullCipher().update(new byte[1], 1, Integer.MAX_VALUE,
+ new byte[1], 0);
+ fail("Expected IllegalArgumentException was not thrown");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ /*
+ * Class under test for int doFinal(byte[], int, int, byte[], int)
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Exceptions checking missed. Checks inherited method from Cipher.",
+ method = "doFinal",
+ args = {byte[].class, int.class, int.class, byte[].class, int.class}
+ )
+ public void testDoFinalbyteArrayintintbyteArrayint3() throws Exception {
+ //Regression for HARMONY-758
+ try {
+ new NullCipher().update(new byte[1], 0, 1,
+ new byte[0], 0);
+ fail("Expected IndexOutOfBoundsException was not thrown");
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java
new file mode 100644
index 0000000..5fb0245
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @author Alexander Y. Kleymenov
+ * @version $Revision$
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchProviderException;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NullCipher;
+import javax.crypto.SealedObject;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+@TestTargetClass(SealedObject.class)
+/**
+ */
+public class SealedObjectTest extends TestCase {
+ class Mock_SealedObject extends SealedObject {
+ public Mock_SealedObject(Serializable object, Cipher c)
+ throws IOException, IllegalBlockSizeException {
+ super(object, c);
+ }
+
+ public byte[] get_encodedParams() {
+ return super.encodedParams;
+ }
+
+ }
+
+ /**
+ * readObject(ObjectInputStream s) method testing. Tests if the
+ * serialization/deserialization works correctly: object is serialized,
+ * deserialized, the content od deserialized object equals to the content of
+ * initial object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "!Serialization",
+ args = {}
+ )
+ public void testReadObject() throws Exception {
+ String secret = "secret string";
+ SealedObject so = new SealedObject(secret, new NullCipher());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(so);
+
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
+ bos.toByteArray()));
+
+ SealedObject so_des = (SealedObject) ois.readObject();
+ assertEquals("The secret content of deserialized object "
+ + "should be equal to the secret content of initial object",
+ secret, so_des.getObject(new NullCipher()));
+ assertEquals("The value returned by getAlgorithm() method of "
+ + "deserialized object should be equal to the value returned "
+ + "by getAlgorithm() method of initial object", so
+ .getAlgorithm(), so_des.getAlgorithm());
+ }
+
+ /**
+ * SealedObject(Serializable object, Cipher c) method testing. Tests if the
+ * NullPointerException is thrown in the case of null cipher.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SealedObject",
+ args = {java.io.Serializable.class, javax.crypto.Cipher.class}
+ )
+ public void testSealedObject1() throws Exception {
+ String secret = "secret string";
+ try {
+ new SealedObject(secret, null);
+ fail("NullPointerException should be thrown in the case "
+ + "of null cipher.");
+ } catch (NullPointerException e) {
+ }
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ Key key = kg.generateKey();
+
+ IvParameterSpec ips = new IvParameterSpec(new byte[] {
+ 1, 2, 3, 4, 5, 6, 7, 8});
+
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, ips);
+
+ SealedObject so = new SealedObject(secret, cipher);
+
+ cipher = Cipher.getInstance("DES/CBC/NoPadding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, ips);
+
+ try {
+ new SealedObject(secret, cipher);
+ fail("IllegalBlockSizeException expected");
+ } catch (IllegalBlockSizeException e) {
+ //expected
+ }
+ }
+
+ /**
+ * SealedObject(SealedObject so) method testing. Tests if the
+ * NullPointerException is thrown in the case of null SealedObject.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SealedObject",
+ args = {javax.crypto.SealedObject.class}
+ )
+ public void testSealedObject2() throws Exception {
+ try {
+ new SealedObject(null) {};
+ fail("NullPointerException should be thrown in the case "
+ + "of null SealedObject.");
+ } catch (NullPointerException e) {
+ }
+
+ String secret = "secret string";
+ Cipher cipher = new NullCipher();
+ SealedObject so1 = new SealedObject(secret, cipher);
+ SealedObject so2 = new SealedObject(so1) {};
+
+ assertEquals("The secret content of the object should equals "
+ + "to the secret content of initial object.", secret, so2
+ .getObject(cipher));
+ assertEquals("The algorithm which was used to seal the object "
+ + "should be the same as the algorithm used to seal the "
+ + "initial object", so1.getAlgorithm(), so2.getAlgorithm());
+ }
+
+ /**
+ * getAlgorithm() method testing. Tests if the returned value equals to the
+ * corresponding value of Cipher object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void testGetAlgorithm() throws Exception {
+ String secret = "secret string";
+ String algorithm = "DES";
+ KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+ Key key = kg.generateKey();
+
+ Cipher cipher = Cipher.getInstance(algorithm);
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ SealedObject so = new SealedObject(secret, cipher);
+
+ assertEquals("The algorithm name should be the same as used "
+ + "in cipher.", algorithm, so.getAlgorithm());
+ }
+
+ /**
+ * getObject(Key key) method testing. Tests if the object sealed with
+ * encryption algorithm and specified parameters can be retrieved by
+ * specifying the cryptographic key.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Not all exceptions can be checked.",
+ method = "getObject",
+ args = {java.security.Key.class}
+ )
+ public void testGetObject1() throws Exception {
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ Key key = kg.generateKey();
+
+ IvParameterSpec ips = new IvParameterSpec(new byte[] {
+ 1, 2, 3, 4, 5, 6, 7, 8});
+
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, ips);
+
+ String secret = "secret string";
+ Mock_SealedObject so = new Mock_SealedObject(secret, cipher);
+
+ assertEquals("The returned object does not equals to the "
+ + "original object.", secret, so.getObject(key));
+
+ assertTrue("The encodedParams field of SealedObject object "
+ + "should contain the encoded algorithm parameters.", Arrays
+ .equals(so.get_encodedParams(), cipher.getParameters()
+ .getEncoded()));
+ try {
+ so.getObject((Key)null);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ } catch (NullPointerException e) {
+ //also ok
+ }
+ }
+
+ /**
+ * getObject(Cipher c) method testing. Tests if the proper exception is
+ * thrown in the case of incorrect input parameters and if the object sealed
+ * with encryption algorithm and specified parameters can be retrieved by
+ * specifying the initialized Cipher object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Not all exceptions can be checked.",
+ method = "getObject",
+ args = {javax.crypto.Cipher.class}
+ )
+ public void testGetObject2() throws Exception {
+ try {
+ new SealedObject("secret string", new NullCipher())
+ .getObject((Cipher) null);
+ fail("NullPointerException should be thrown in the case of "
+ + "null cipher.");
+ } catch (NullPointerException e) {
+ }
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ Key key = kg.generateKey();
+
+ IvParameterSpec ips = new IvParameterSpec(new byte[] {
+ 1, 2, 3, 4, 5, 6, 7, 8});
+
+ Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key, ips);
+
+ String secret = "secret string";
+ SealedObject so = new SealedObject(secret, cipher);
+
+ cipher.init(Cipher.DECRYPT_MODE, key, ips);
+ assertEquals("The returned object does not equals to the "
+ + "original object.", secret, so.getObject(cipher));
+
+ try {
+ so.getObject((Cipher)null);
+ fail("NullPointerException expected");
+ } catch (NullPointerException e) {
+ //expected
+ }
+ }
+
+ /**
+ * getObject(Key key, String provider) method testing. Tests if the proper
+ * exception is thrown in the case of incorrect input parameters and if the
+ * object sealed with encryption algorithm can be retrieved by specifying
+ * the cryptographic key and provider name.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Not all exceptions can be checked.",
+ method = "getObject",
+ args = {java.security.Key.class, java.lang.String.class}
+ )
+ public void testGetObject3() throws Exception {
+ try {
+ new SealedObject("secret string", new NullCipher()).getObject(
+ new SecretKeySpec(new byte[] {0, 0, 0}, "algorithm"), null);
+ fail("IllegalArgumentException should be thrown in the case of "
+ + "null provider.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SealedObject("secret string", new NullCipher()).getObject(
+ new SecretKeySpec(new byte[] {0, 0, 0}, "algorithm"), "");
+ fail("IllegalArgumentException should be thrown in the case of "
+ + "empty provider.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ KeyGenerator kg = KeyGenerator.getInstance("DES");
+ Key key = kg.generateKey();
+
+ Cipher cipher = Cipher.getInstance("DES");
+ String provider = cipher.getProvider().getName();
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+
+ String secret = "secret string";
+ SealedObject so = new SealedObject(secret, cipher);
+
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ assertEquals("The returned object does not equals to the "
+ + "original object.", secret, so.getObject(key, provider));
+
+ kg = KeyGenerator.getInstance("DESede");
+ key = kg.generateKey();
+
+ try {
+ so.getObject(key, provider);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+
+ try {
+ so.getObject(key, "Wrong provider name");
+ fail("NoSuchProviderException expected");
+ } catch (NoSuchProviderException e) {
+ //expected
+ }
+ }
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java
new file mode 100644
index 0000000..bcc05a2
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactorySpiTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Vera Y. Petrashkova
+ * @version $Revision$
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKeyFactorySpi;
+import javax.crypto.SecretKey;
+import org.apache.harmony.crypto.tests.support.MySecretKeyFactorySpi;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for <code>SecretKeyFactorySpi</code> class constructors and methods.
+ */
+
+@TestTargetClass(SecretKeyFactorySpi.class)
+public class SecretKeyFactorySpiTest extends TestCase {
+ class Mock_SecretKeyFactorySpi extends MySecretKeyFactorySpi {
+
+ @Override
+ protected SecretKey engineGenerateSecret(KeySpec keySpec) throws InvalidKeySpecException {
+ return super.engineGenerateSecret(keySpec);
+ }
+
+ @Override
+ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException {
+ return super.engineGetKeySpec(key, keySpec);
+ }
+
+ @Override
+ protected SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException {
+ return super.engineTranslateKey(key);
+ }
+
+ }
+
+ /**
+ * Test for <code>SecretKeyFactorySpi</code> constructor Assertion:
+ * constructs SecretKeyFactorySpi
+ */
+ @TestTargetNew(level = TestLevel.COMPLETE, notes = "", method = "SecretKeyFactorySpi", args = {})
+ public void testSecretKeyFactorySpi01() throws InvalidKeyException, InvalidKeySpecException {
+ Mock_SecretKeyFactorySpi skfSpi = new Mock_SecretKeyFactorySpi();
+ SecretKey sk = null;
+ assertNull("Not null result", skfSpi.engineTranslateKey(sk));
+
+ KeySpec kspec = null;
+ assertNull("Not null result", skfSpi.engineGenerateSecret(kspec));
+
+ assertNull("Not null result", skfSpi.engineGetKeySpec(sk, null));
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactoryTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactoryTest.java
new file mode 100644
index 0000000..6526239
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyFactoryTest.java
@@ -0,0 +1,596 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.SecretKeyFactorySpi;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.harmony.crypto.tests.support.MySecretKeyFactorySpi;
+import org.apache.harmony.security.tests.support.SpiEngUtils;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(SecretKeyFactory.class)
+/**
+ * Tests for <code>SecretKeyFactory</code> class constructors and methods.
+ *
+ */
+
+public class SecretKeyFactoryTest extends TestCase {
+
+ public static final String srvSecretKeyFactory = "SecretKeyFactory";
+
+ private static String defaultAlgorithm1 = "DESede";
+ private static String defaultAlgorithm2 = "DES";
+
+ public static String defaultAlgorithm = null;
+
+ private static String defaultProviderName = null;
+
+ private static Provider defaultProvider = null;
+
+ private static final String[] invalidValues = SpiEngUtils.invalidValues;
+
+ public static final String[] validValues = new String[2];
+ private static boolean DEFSupported = false;
+
+ private static final String NotSupportMsg = "Default algorithm is not supported";
+
+ static {
+ defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm1,
+ srvSecretKeyFactory);
+ DEFSupported = (defaultProvider != null);
+ if (DEFSupported) {
+ defaultAlgorithm = defaultAlgorithm1;
+ validValues[0] = defaultAlgorithm.toUpperCase();
+ validValues[1] = defaultAlgorithm.toLowerCase();
+ defaultProviderName = defaultProvider.getName();
+ } else {
+ defaultProvider = SpiEngUtils.isSupport(defaultAlgorithm2,
+ srvSecretKeyFactory);
+ DEFSupported = (defaultProvider != null);
+ if (DEFSupported) {
+ defaultAlgorithm = defaultAlgorithm2;
+ validValues[0] = defaultAlgorithm.toUpperCase();
+ validValues[2] = defaultAlgorithm.toLowerCase();
+ defaultProviderName = defaultProvider.getName();
+ } else {
+ defaultAlgorithm = null;
+ defaultProviderName = null;
+ defaultProvider = null;
+ }
+ }
+ }
+
+ protected SecretKeyFactory[] createSKFac() {
+ if (!DEFSupported) {
+ fail(defaultAlgorithm + " algorithm is not supported");
+ return null;
+ }
+ SecretKeyFactory[] skF = new SecretKeyFactory[3];
+ try {
+ skF[0] = SecretKeyFactory.getInstance(defaultAlgorithm);
+ skF[1] = SecretKeyFactory.getInstance(defaultAlgorithm,
+ defaultProvider);
+ skF[2] = SecretKeyFactory.getInstance(defaultAlgorithm,
+ defaultProviderName);
+ return skF;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Test for <code>SecretKeyFactory</code> constructor
+ * Assertion: returns SecretKeyFactory object
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SecretKeyFactory",
+ args = {javax.crypto.SecretKeyFactorySpi.class, java.security.Provider.class, java.lang.String.class}
+ )
+ public void testSecretKeyFactory01() throws NoSuchAlgorithmException,
+ InvalidKeySpecException, InvalidKeyException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ SecretKeyFactorySpi spi = new MySecretKeyFactorySpi();
+ SecretKeyFactory secKF = new mySecretKeyFactory(spi, defaultProvider,
+ defaultAlgorithm);
+ assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
+ defaultAlgorithm);
+ assertEquals("Incorrect provider", secKF.getProvider(), defaultProvider);
+ assertNull("Incorrect result", secKF.generateSecret(null));
+ assertNull("Incorrect result", secKF.getKeySpec(null, null));
+ assertNull("Incorrect result", secKF.translateKey(null));
+ secKF = new mySecretKeyFactory(null, null, null);
+ assertNull("Algorithm must be null", secKF.getAlgorithm());
+ assertNull("Provider must be null", secKF.getProvider());
+ try {
+ secKF.translateKey(null);
+ fail("NullPointerException must be thrown");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm)</code> method
+ * Assertions:
+ * throws NullPointerException when algorithm is null;
+ * throws NoSuchAlgorithmException when algorithm has invalid value
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testSecretKeyFactory02() throws NoSuchAlgorithmException {
+ try {
+ SecretKeyFactory.getInstance(null);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ SecretKeyFactory.getInstance(invalidValues[i]);
+ fail("NoSuchAlgorithmException was not thrown as expected");
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm)</code> method
+ * Assertion: returns SecretKeyObject
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class}
+ )
+ public void testSecretKeyFactory03() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ for (int i = 0; i < validValues.length; i++) {
+ SecretKeyFactory secKF = SecretKeyFactory
+ .getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
+ validValues[i]);
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code>
+ * method
+ * Assertion:
+ * throws NullPointerException when algorithm is null;
+ * throws NoSuchAlgorithmException when algorithm is invalid
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testSecretKeyFactory04() throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ SecretKeyFactory.getInstance(null, defaultProviderName);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ SecretKeyFactory.getInstance(invalidValues[i],
+ defaultProviderName);
+ fail("NoSuchAlgorithmException was not thrown as expected (algorithm: "
+ .concat(invalidValues[i]).concat(")"));
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code>
+ * method
+ * Assertion:
+ * throws IllegalArgumentException when provider is null or empty;
+ * throws NoSuchProviderException when provider has invalid value
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testSecretKeyFactory05() throws NoSuchAlgorithmException,
+ NoSuchProviderException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ String prov = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ SecretKeyFactory.getInstance(validValues[i], prov);
+ fail("IllegalArgumentException was not thrown as expected (algorithm: "
+ .concat(validValues[i]).concat(" provider: null"));
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ SecretKeyFactory.getInstance(validValues[i], "");
+ fail("IllegalArgumentException was not thrown as expected (algorithm: "
+ .concat(validValues[i]).concat(" provider: empty"));
+ } catch (IllegalArgumentException e) {
+ }
+ for (int j = 1; j < invalidValues.length; j++) {
+ try {
+ SecretKeyFactory.getInstance(validValues[i],
+ invalidValues[j]);
+ fail("NoSuchProviderException was not thrown as expected (algorithm: "
+ .concat(validValues[i]).concat(" provider: ")
+ .concat(invalidValues[j]).concat(")"));
+ } catch (NoSuchProviderException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, String provider)</code>
+ * method
+ * Assertion: returns SecretKeyFactory object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.lang.String.class}
+ )
+ public void testSecretKeyFactory06() throws NoSuchProviderException,
+ NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ for (int i = 0; i < validValues.length; i++) {
+ SecretKeyFactory secKF = SecretKeyFactory.getInstance(
+ validValues[i], defaultProviderName);
+ assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
+ validValues[i]);
+ assertEquals("Incorrect provider", secKF.getProvider().getName(),
+ defaultProviderName);
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code>
+ * method
+ * Assertion: throws NullPointerException when algorithm is null;
+ * throws NoSuchAlgorithmException when algorithm is invalid
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testSecretKeyFactory07() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ try {
+ SecretKeyFactory.getInstance(null, defaultProvider);
+ fail("NullPointerException or NoSuchAlgorithmException should be thrown if algorithm is null");
+ } catch (NullPointerException e) {
+ } catch (NoSuchAlgorithmException e) {
+ }
+ for (int i = 0; i < invalidValues.length; i++) {
+ try {
+ SecretKeyFactory.getInstance(invalidValues[i], defaultProvider);
+ fail("NoSuchAlgorithmException was not thrown as expected (algorithm: "
+ .concat(invalidValues[i]).concat(")"));
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code>
+ * method
+ * Assertion: throws IllegalArgumentException when provider is null
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testSecretKeyFactory08() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ Provider prov = null;
+ for (int i = 0; i < validValues.length; i++) {
+ try {
+ SecretKeyFactory.getInstance(validValues[i], prov);
+ fail("IllegalArgumentException was not thrown as expected (provider is null, algorithm: "
+ .concat(validValues[i]).concat(")"));
+ } catch (IllegalArgumentException e) {
+ }
+ }
+ }
+
+ /**
+ * Test for <code>getInstance(String algorithm, Provider provider)</code>
+ * method
+ * Assertion: returns SecretKeyFactory object
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "This is a complete subset of tests for getInstance method.",
+ method = "getInstance",
+ args = {java.lang.String.class, java.security.Provider.class}
+ )
+ public void testSecretKeyFactory09() throws NoSuchAlgorithmException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ for (int i = 0; i < validValues.length; i++) {
+ SecretKeyFactory secKF = SecretKeyFactory.getInstance(
+ validValues[i], defaultProvider);
+ assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
+ validValues[i]);
+ assertEquals("Incorrect provider", secKF.getProvider(),
+ defaultProvider);
+ }
+ }
+
+ /**
+ * Test for <code>generateSecret(KeySpec keySpec)</code> and
+ * <code>getKeySpec(SecretKey key, Class keySpec)
+ * methods
+ * Assertion:
+ * throw InvalidKeySpecException if parameter is inappropriate
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tis test is checking two methods.",
+ method = "generateSecret",
+ args = {java.security.spec.KeySpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tis test is checking two methods.",
+ clazz = SecretKeyFactorySpi.class,
+ method = "engineGenerateSecret",
+ args = {java.security.spec.KeySpec.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tis test is checking two methods.",
+ method = "getKeySpec",
+ args = {javax.crypto.SecretKey.class, java.lang.Class.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Tis test is checking two methods.",
+ clazz = SecretKeyFactorySpi.class,
+ method = "engineGetKeySpec",
+ args = {javax.crypto.SecretKey.class, java.lang.Class.class}
+ )
+ })
+ public void testSecretKeyFactory10() throws InvalidKeyException,
+ InvalidKeySpecException {
+ if (!DEFSupported) {
+ fail(NotSupportMsg);
+ return;
+ }
+ byte[] bb = new byte[24];
+ KeySpec ks = (defaultAlgorithm.equals(defaultAlgorithm2) ? (KeySpec)new DESKeySpec(bb) :
+ (KeySpec)new DESedeKeySpec(bb));
+ KeySpec rks = null;
+ SecretKeySpec secKeySpec = new SecretKeySpec(bb, defaultAlgorithm);
+ SecretKey secKey = null;
+ SecretKeyFactory[] skF = createSKFac();
+ assertNotNull("SecretKeyFactory object were not created", skF);
+ for (int i = 0; i < skF.length; i++) {
+ try {
+ skF[i].generateSecret(null);
+ fail("generateSecret(null): InvalidKeySpecException must be thrown");
+ } catch (InvalidKeySpecException e) {
+ }
+
+ secKey = skF[i].generateSecret(ks);
+ try {
+ skF[i].getKeySpec(null, null);
+ fail("getKeySpec(null,null): InvalidKeySpecException must be thrown");
+ } catch (InvalidKeySpecException e) {
+ }
+ try {
+ skF[i].getKeySpec(null, ks.getClass());
+ fail("getKeySpec(null, Class): InvalidKeySpecException must be thrown");
+ } catch (InvalidKeySpecException e) {
+ }
+ try {
+ skF[i].getKeySpec(secKey, null);
+ fail("getKeySpec(secKey, null): NullPointerException or InvalidKeySpecException must be thrown");
+ } catch (InvalidKeySpecException e) {
+ // Expected
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ Class c;
+ if (defaultAlgorithm.equals(defaultAlgorithm2)) {
+ c = DESedeKeySpec.class;
+ } else {
+ c = DESKeySpec.class;
+ }
+ skF[i].getKeySpec(secKeySpec, c);
+ fail("getKeySpec(secKey, Class): InvalidKeySpecException must be thrown");
+ } catch (InvalidKeySpecException e) {
+ }
+ rks = skF[i].getKeySpec(secKeySpec, ks.getClass());
+ if (defaultAlgorithm.equals(defaultAlgorithm1)) {
+ assertTrue("Incorrect getKeySpec() result 1",
+ rks instanceof DESedeKeySpec);
+ } else {
+ assertTrue("Incorrect getKeySpec() result 1",
+ rks instanceof DESKeySpec);
+ }
+
+ rks = skF[i].getKeySpec(secKey, ks.getClass());
+ if (defaultAlgorithm.equals(defaultAlgorithm1)) {
+ assertTrue("Incorrect getKeySpec() result 2",
+ rks instanceof DESedeKeySpec);
+ } else {
+ assertTrue("Incorrect getKeySpec() result 2",
+ rks instanceof DESKeySpec);
+ }
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void test_getAlgorithm() throws NoSuchAlgorithmException {
+ for (int i = 0; i < validValues.length; i++) {
+ SecretKeyFactory secKF = SecretKeyFactory
+ .getInstance(validValues[i]);
+ assertEquals("Incorrect algorithm", secKF.getAlgorithm(),
+ validValues[i]);
+ }
+
+ Mock_SecretKeyFactory msf = new Mock_SecretKeyFactory(null, null, null);
+ assertNull(msf.getAlgorithm());
+ }
+
+ class Mock_SecretKeyFactory extends SecretKeyFactory{
+ protected Mock_SecretKeyFactory(SecretKeyFactorySpi arg0, Provider arg1, String arg2) {
+ super(arg0, arg1, arg2);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getProvider",
+ args = {}
+ )
+ public void test_getProvider() throws NoSuchAlgorithmException {
+ for (int i = 0; i < validValues.length; i++) {
+ SecretKeyFactory secKF = SecretKeyFactory
+ .getInstance(validValues[i]);
+ assertNotNull(secKF.getProvider());
+ }
+
+ Mock_SecretKeyFactory msf = new Mock_SecretKeyFactory(null, null, null);
+ assertNull(msf.getProvider());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "translateKey",
+ args = {javax.crypto.SecretKey.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SecretKeyFactorySpi.class,
+ method = "engineTranslateKey",
+ args = {javax.crypto.SecretKey.class}
+ )
+ })
+ public void test_translateKeyLjavax_crypto_SecretKey()
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ KeyGenerator kg = null;
+ Key key = null;
+ SecretKeyFactory secKF = null;
+
+ for (int i = 0; i < validValues.length; i++) {
+ secKF = SecretKeyFactory
+ .getInstance(validValues[i]);
+ assertNotNull(secKF.getProvider());
+ kg = KeyGenerator.getInstance(secKF.getAlgorithm());
+ kg.init(new SecureRandom());
+ key = kg.generateKey();
+
+ secKF.translateKey((SecretKey) key);
+ }
+ try {
+ secKF.translateKey(null);
+ fail("InvalidKeyException expected");
+ } catch (InvalidKeyException e) {
+ //expected
+ }
+ }
+}
+
+class mySecretKeyFactory extends SecretKeyFactory {
+ public mySecretKeyFactory(SecretKeyFactorySpi spi, Provider prov, String alg) {
+ super(spi, prov, alg);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java
new file mode 100644
index 0000000..4e34ed2
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SecretKeyTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.SecretKey;
+
+import junit.framework.TestCase;
+
+
+@TestTargetClass(SecretKey.class)
+/**
+ * Tests for <code>SecretKey</code> class field
+ *
+ */
+public class SecretKeyTest extends TestCase {
+
+ /**
+ * Test for <code>serialVersionUID</code> field
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "!Constants",
+ args = {}
+ )
+ public void testField() {
+ checkSecretKey sk = new checkSecretKey();
+ assertEquals("Incorrect serialVersionUID",
+ sk.getSerVerUID(), //SecretKey.serialVersionUID
+ -4795878709595146952L);
+ }
+
+ public class checkSecretKey implements SecretKey {
+ public String getAlgorithm() {
+ return "SecretKey";
+ }
+ public String getFormat() {
+ return "Format";
+ }
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ public long getSerVerUID() {
+ return serialVersionUID;
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java
new file mode 100644
index 0000000..4390994
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ShortBufferExceptionTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import javax.crypto.ShortBufferException;
+
+import junit.framework.TestCase;
+
+@TestTargetClass(ShortBufferException.class)
+/**
+ * Tests for <code>ShortBufferException</code> class constructors and methods.
+ *
+ */
+public class ShortBufferExceptionTest extends TestCase {
+
+ static String[] msgs = {
+ "",
+ "Check new message",
+ "Check new message Check new message Check new message Check new message Check new message" };
+
+ static Throwable tCause = new Throwable("Throwable for exception");
+
+ /**
+ * Test for <code>ShortBufferException()</code> constructor Assertion:
+ * constructs ShortBufferException with no detail message
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ShortBufferException",
+ args = {}
+ )
+ public void testShortBufferException01() {
+ ShortBufferException tE = new ShortBufferException();
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+
+ /**
+ * Test for <code>ShortBufferException(String)</code> constructor
+ * Assertion: constructs ShortBufferException with detail message msg.
+ * Parameter <code>msg</code> is not null.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ShortBufferException",
+ args = {java.lang.String.class}
+ )
+ public void testShortBufferException02() {
+ ShortBufferException tE;
+ for (int i = 0; i < msgs.length; i++) {
+ tE = new ShortBufferException(msgs[i]);
+ assertEquals("getMessage() must return: ".concat(msgs[i]), tE
+ .getMessage(), msgs[i]);
+ assertNull("getCause() must return null", tE.getCause());
+ }
+ }
+
+ /**
+ * Test for <code>ShortBufferException(String)</code> constructor
+ * Assertion: constructs ShortBufferException when <code>msg</code> is
+ * null
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ShortBufferException",
+ args = {java.lang.String.class}
+ )
+ public void testShortBufferException03() {
+ String msg = null;
+ ShortBufferException tE = new ShortBufferException(msg);
+ assertNull("getMessage() must return null.", tE.getMessage());
+ assertNull("getCause() must return null", tE.getCause());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
new file mode 100644
index 0000000..862cced
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/AllTests.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.apache.harmony.crypto.tests.javax.crypto;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.func;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(CipherDesTest.class);
+ suite.addTestSuite(CipherAesTest.class);
+ suite.addTestSuite(CipherAesWrapTest.class);
+ suite.addTestSuite(CipherDESedeTest.class);
+ suite.addTestSuite(CipherDESedeWrapTest.class);
+ suite.addTestSuite(CipherPBETest.class);
+ suite.addTestSuite(CipherRSATest.class);
+ suite.addTestSuite(KeyGeneratorFunctionalTest.class);
+ suite.addTestSuite(KeyAgreementFunctionalTest.class);
+ suite.addTestSuite(MacFunctionalTest.class);
+ suite.addTestSuite(SecretKeyFactoryFunctionalTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
new file mode 100644
index 0000000..ce62332
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.AES.class)
+public class CipherAesTest extends TestCase {
+// 76 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_AesNoISO() {
+ CipherSymmetricKeyThread aesNoISO = new CipherSymmetricKeyThread("AES",
+ new int[]{128},//Keysize must be equal to 128, 192, or 256.
+ new String[] {"ECB", "CBC", "CTR", "CTS", "CFB", "CFB8",
+ "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", "CFB64",
+ "CFB72", "CFB80", "CFB88", "CFB96", "CFB104", "CFB112", "CFB120",
+ "CFB128", "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
+ "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96",
+ "OFB104", "OFB112", "OFB120", "OFB128"},
+ new String[]{"NoPadding", "PKCS5Padding"});
+
+ aesNoISO.launcher();
+
+ assertEquals(aesNoISO.getFailureMessages(), 0, aesNoISO.getTotalFailuresNumber());
+ }
+
+// 36 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_AesISO() {
+ CipherSymmetricKeyThread aesISO = new CipherSymmetricKeyThread("AES",
+ new int[]{128},//Keysize must be equal to 128, 192, or 256.
+ new String[] {"ECB", "CBC", "CFB", "CFB8",
+ "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", "CFB64",
+ "CFB72", "CFB80", "CFB88", "CFB96", "CFB104", "CFB112", "CFB120",
+ "CFB128", "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
+ "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96",
+ "OFB104", "OFB112", "OFB120", "OFB128"},
+ new String[] {"ISO10126PADDING"});
+
+ aesISO.launcher();
+
+ assertEquals(aesISO.getFailureMessages(), 0, aesISO.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
new file mode 100644
index 0000000..2c75abd
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherAesWrapTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.AESWrap.class)
+public class CipherAesWrapTest extends TestCase {
+// one case checked. Mode "ECB" not supported.
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_AesWrap() {
+ CipherWrapThread aesWrap = new CipherWrapThread("AESWrap",
+ new int[]{128},
+ new String[] {"ECB"},
+ new String[] {"NoPadding"});
+
+ aesWrap.launcher();
+
+ assertEquals(aesWrap.getFailureMessages(), 0, aesWrap.getTotalFailuresNumber());
+ }
+
+ public void test_AesWrap1() {
+ CipherWrapThread aesWrap = new CipherWrapThread("AES",
+ new int[]{128},
+ new String[] {"ECB"},
+ new String[] {"NoPadding"});
+
+ aesWrap.launcher();
+
+ assertEquals(aesWrap.getFailureMessages(), 0, aesWrap.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
new file mode 100644
index 0000000..c6053b6
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.DESede.class)
+public class CipherDESedeTest extends TestCase {
+// 88 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_DESedeNoISO() {
+ CipherSymmetricKeyThread DESedeNoISO = new CipherSymmetricKeyThread("DESede",
+ new int[]{112, 168},//Keysize must be equal to 112 or 168.
+ new String[] {"ECB", "CBC", "CTR", "CTS", "CFB", "CFB8", "CFB16",
+ "CFB24", "CFB32", "CFB40", "CFB48", "CFB56", "CFB64", "OFB",
+ "OFB8", "OFB16", "OFB24", "OFB32","OFB40", "OFB48", "OFB56",
+ "OFB64"},
+ new String[]{"NoPadding", "PKCS5Padding"});
+
+ DESedeNoISO.launcher();
+
+ assertEquals(DESedeNoISO.getFailureMessages(), 0, DESedeNoISO.getTotalFailuresNumber());
+ }
+
+// 40 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_DESedeISO() {
+ CipherSymmetricKeyThread DESedeISO = new CipherSymmetricKeyThread("DESede",
+ new int[]{112, 168},//Keysize must be equal to 112 or 168.
+ new String[] {"ECB", "CBC", "CFB", "CFB8", "CFB16", "CFB24",
+ "CFB32", "CFB40", "CFB48", "CFB56", "CFB64", "OFB",
+ "OFB8", "OFB16", "OFB24", "OFB32","OFB40", "OFB48",
+ "OFB56", "OFB64"},
+ new String[]{"ISO10126PADDING"});
+
+ DESedeISO.launcher();
+
+ assertEquals(DESedeISO.getFailureMessages(), 0, DESedeISO.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java
new file mode 100644
index 0000000..e2c9c9e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDESedeWrapTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.DESedeWrap.class)
+public class CipherDESedeWrapTest extends TestCase {
+// 2 cases checked. Mode "CBC" not supported.
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_DESedeWrap() {
+ CipherWrapThread DESedeWrap = new CipherWrapThread("DESedeWrap",
+ new int[]{112, 168},
+ new String[] {"CBC"},
+ new String[]{"NoPadding"});
+
+ DESedeWrap.launcher();
+
+ assertEquals(DESedeWrap.getFailureMessages(), 0, DESedeWrap.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java
new file mode 100644
index 0000000..7b11ae9
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherDesTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.DES.class)
+public class CipherDesTest extends TestCase {
+// 44 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_DesNoISO() {
+ CipherSymmetricKeyThread desNoISO = new CipherSymmetricKeyThread("DES",
+ new int[]{56},//Keysize must be equal to 56.
+ new String[] {"ECB", "CBC", "CTR", "CTS", "CFB", "CFB8",
+ "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56",
+ "CFB64", "OFB", "OFB8", "OFB16", "OFB24", "OFB32",
+ "OFB40", "OFB48", "OFB56", "OFB64"},
+ new String[]{"NoPadding", "PKCS5Padding"});
+
+ desNoISO.launcher();
+
+ assertEquals(desNoISO.getFailureMessages(), 0, desNoISO.getTotalFailuresNumber());
+ }
+
+// 20 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_DesISO() {
+ CipherSymmetricKeyThread desISO = new CipherSymmetricKeyThread("DES",
+ new int[]{56},//Keysize must be equal to 56.
+ new String[] {"ECB", "CBC", "CFB", "CFB8",
+ "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56",
+ "CFB64", "OFB", "OFB8", "OFB16", "OFB24", "OFB32",
+ "OFB40", "OFB48", "OFB56", "OFB64"},
+ new String[]{"ISO10126PADDING"});
+
+ desISO.launcher();
+
+ assertEquals(desISO.getFailureMessages(), 0, desISO.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
new file mode 100644
index 0000000..a3fb3c2
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBETest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.PBE.class)
+public class CipherPBETest extends TestCase {
+// 2 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_PBEWithMD5AndDES() throws Exception {
+ CipherPBEThread PBEWithMD5AndDES = new CipherPBEThread("PBEWithMD5AndDES",
+ new int[]{40, 128},
+ new String[] {"CBC"},
+ new String[]{"PKCS5Padding"});
+
+ PBEWithMD5AndDES.launcher();
+
+ assertEquals(PBEWithMD5AndDES.getFailureMessages(), 0, PBEWithMD5AndDES.getTotalFailuresNumber());
+ }
+
+// 2 cases checked. Not supported on Android.
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_PBEWithSHA1AndDESede() throws Exception {
+ CipherPBEThread PBEWithSHA1AndDESede = new CipherPBEThread("PBEWithSHA1AndDESede",
+ new int[]{40, 128},
+ new String[] {"CBC"},
+ new String[]{"PKCS5Padding"});
+
+ PBEWithSHA1AndDESede.launcher();
+
+ assertEquals(PBEWithSHA1AndDESede.getFailureMessages(), 0, PBEWithSHA1AndDESede.getTotalFailuresNumber());
+ }
+
+// 2 cases checked. Not supported on Android.
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_PBEWithSHA1AndRC2_40() throws Exception {
+ CipherPBEThread PBEWithSHA1AndRC2_40 = new CipherPBEThread("PBEWithSHA1AndRC2_40",
+ new int[]{40, 128},
+ new String[] {"CBC"},
+ new String[]{"PKCS5Padding"});
+
+ PBEWithSHA1AndRC2_40.launcher();
+
+ assertEquals(PBEWithSHA1AndRC2_40.getFailureMessages(), 0, PBEWithSHA1AndRC2_40.getTotalFailuresNumber());
+ }
+
+// Key factory does not supported.
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_PBEWITHSHAAND3() throws Exception {
+ CipherPBEThread PBEWithSHA1AndRC2_40 = new CipherPBEThread("PBEWITHSHAAND3",
+ new int[]{40, 128},
+ new String[] {"CBC"},
+ new String[]{"NoPadding", "PKCS5Padding", "ISO10126PADDING"});
+
+ PBEWithSHA1AndRC2_40.launcher();
+
+ assertEquals(PBEWithSHA1AndRC2_40.getFailureMessages(), 0, PBEWithSHA1AndRC2_40.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBEThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBEThread.java
new file mode 100644
index 0000000..0e8dc4d
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherPBEThread.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+public class CipherPBEThread extends CipherThread {
+
+ CipherPBEThread(String name, int[] keys, String[] modes, String[] paddings) {
+ super(name, keys, modes, paddings);
+ }
+
+ @Override
+ public void crypt() throws Exception {
+ byte[] output = new byte[128];
+ byte[] decrypted = new byte[128];
+ byte[] input = getData().getBytes();
+ byte[] salt = new byte[8];
+ SecureRandom sr = new SecureRandom();
+
+ PBEKeySpec keySpec = new PBEKeySpec("top sicret password".toCharArray());
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(getAlgName());
+ SecretKey key = skf.generateSecret(keySpec);
+
+ Cipher cip = Cipher.getInstance(getAlgName() + "/" + getMode() + "/" +
+ getPadding());
+
+ sr.nextBytes(salt);
+ PBEParameterSpec parSpec = new PBEParameterSpec(salt, getKeyLength());
+
+ cip.init(Cipher.ENCRYPT_MODE, key, parSpec);
+ cip.doFinal(input, 0, input.length, output);
+ int outputSize = cip.getOutputSize(input.length);
+ cip.init(Cipher.DECRYPT_MODE, key, parSpec);
+ cip.doFinal(output, 0, outputSize, decrypted);
+
+ checkEncodedData(getData().getBytes(), decrypted);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java
new file mode 100644
index 0000000..90cb956
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSATest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.Cipher;
+
+@TestTargetClass(Cipher.RSA.class)
+public class CipherRSATest extends TestCase {
+// 3 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_RSAShortKey() {
+ CipherRSAThread rsa = new CipherRSAThread("RSA",
+ new int[]{512},
+ new String[] {"ECB"},
+ new String[]{"PKCS1Padding",
+ "OAEPWITHMD5ANDMGF1Padding", "OAEPWITHSHA1ANDMGF1Padding"});
+
+ rsa.launcher();
+
+ assertEquals(rsa.getFailureMessages(), 0, rsa.getTotalFailuresNumber());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_RSALongKey() {
+ CipherRSAThread rsa = new CipherRSAThread("RSA",
+ new int[]{1024},
+ new String[] {"ECB"},
+ new String[]{"OAEPWITHSHA-384ANDMGF1Padding"});
+
+ rsa.launcher();
+
+ assertEquals(rsa.getFailureMessages(), 0, rsa.getTotalFailuresNumber());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void _test_RSAXXXLKey() {
+ CipherRSAThread rsa = new CipherRSAThread("RSA",
+ new int[]{2048},
+ new String[] {"ECB"},
+ new String[]{"OAEPWITHSHA-512ANDMGF1Padding"});
+
+ rsa.launcher();
+
+ assertEquals(rsa.getFailureMessages(), 0, rsa.getTotalFailuresNumber());
+ }
+
+// 2 cases checked
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_RSANoPadding() {
+ CipherRSAThread rsa = new CipherRSAThread("RSA",
+ new int[]{512},
+ new String[] {"ECB"},
+ new String[]{"NoPadding", "ISO9796-1PADDING"});
+
+ rsa.launcher();
+
+ assertEquals(rsa.getFailureMessages(), 0, rsa.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSAThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSAThread.java
new file mode 100644
index 0000000..8efc0f6
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherRSAThread.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+import javax.crypto.Cipher;
+
+public class CipherRSAThread extends CipherThread {
+
+ CipherRSAThread(String name, int[] keys, String[] modes, String[] paddings) {
+ super(name, keys, modes, paddings);
+ }
+
+ @Override
+ public void crypt() throws Exception {
+ byte[] output = new byte[256];
+ byte[] decrypted = new byte[256];
+ int dataBlock = 20;
+ byte[] input = getData().substring(0, dataBlock).getBytes();
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(getKeyLength());
+ KeyPair kp = kpg.generateKeyPair();
+
+ Cipher cip = Cipher.getInstance(getAlgName() + "/" + getMode() + "/" +
+ getPadding());
+ cip.init(Cipher.ENCRYPT_MODE, kp.getPublic());
+ cip.doFinal(input, 0, input.length, output);
+ int outputSize = cip.getOutputSize(input.length);
+ cip.init(Cipher.DECRYPT_MODE, kp.getPrivate());
+ cip.doFinal(output, 0, outputSize, decrypted);
+
+ checkEncodedData(input, decrypted);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherSymmetricKeyThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherSymmetricKeyThread.java
new file mode 100644
index 0000000..63faada
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherSymmetricKeyThread.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.IvParameterSpec;
+
+public class CipherSymmetricKeyThread extends CipherThread {
+ CipherSymmetricKeyThread(String name, int[] keys, String[] modes, String[] paddings) {
+ super(name, keys, modes, paddings);
+ }
+
+
+ @Override
+ public void crypt() throws Exception {
+ byte[] output = new byte[128];
+ byte[] decrypted = new byte[128];
+ byte[] input = getData().getBytes();
+ SecureRandom sr = new SecureRandom();
+ byte[] iv = null;//new byte[16];
+ int outputSize = 0;
+
+ KeyGenerator kg = KeyGenerator.getInstance(getAlgName());
+ kg.init(getKeyLength(), new SecureRandom());
+ Key key = kg.generateKey();
+
+ Cipher cip = Cipher.getInstance(getAlgName() + "/" + getMode() + "/" +
+ getPadding());
+ if (getAlgName() != "AES") {
+ iv = new byte[8];
+ } else {
+ iv = new byte[16];
+ }
+ sr.nextBytes(iv);
+ IvParameterSpec ivspec = new IvParameterSpec(iv);
+ if (getMode() != "ECB") {
+ cip.init(Cipher.ENCRYPT_MODE, key, ivspec);
+ cip.doFinal(input, 0, input.length, output);
+ outputSize = cip.getOutputSize(input.length);
+ iv = cip.getIV();
+ ivspec = new IvParameterSpec(iv);
+ cip.init(Cipher.DECRYPT_MODE, key, ivspec);
+ cip.doFinal(output, 0, outputSize, decrypted);
+ } else {
+ cip.init(Cipher.ENCRYPT_MODE, key);
+ cip.doFinal(input, 0, input.length, output);
+ outputSize = cip.getOutputSize(input.length);
+ cip.init(Cipher.DECRYPT_MODE, key);
+ cip.doFinal(output, 0, outputSize, decrypted);
+ }
+
+ checkEncodedData(getData().getBytes(), decrypted);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherThread.java
new file mode 100644
index 0000000..25d51c4
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherThread.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import javax.crypto.Cipher;
+
+public abstract class CipherThread implements Runnable {
+ private int[] keyLengthAr = null;
+ private String[] modeAr = null;
+ private String[] paddingModeAr = null;
+ private int kCounter = 0;
+ private int mCounter = 0;
+ private int pCounter = 0;
+ private StringBuffer errorSB = null;
+
+ private boolean flagTestResult = false;
+ private String data = " Albert Einstein was a German-born " +
+ "theoretical physicist. ";
+ private String algName = null;
+ private int keyLength = 0;
+ private String mode = null;
+ private String paddingMode = null;
+ private int fails = 0;
+
+ abstract public void crypt() throws Exception;
+
+ CipherThread(String name, int[] keys, String[] modes, String[] paddings) {
+ algName = name;
+ keyLengthAr = keys;
+ modeAr = modes;
+ paddingModeAr = paddings;
+ kCounter = 0;
+ mCounter = 0;
+ pCounter = 0;
+ }
+
+ public void checkEncodedData(byte[] original, byte[] encoded)
+ throws Exception {
+ for(int i = 0; i < original.length; i++) {
+ if (original[i] != encoded[i]) {
+ throw new Exception("Source and encoded data not match " +
+ getCipherParameters());
+ }
+ }
+ }
+
+ public void launcher() {
+ Thread thread = null;
+
+ do {
+ keyLength = getNextKey();
+ do {
+ mode = getNextMode();
+ do {
+ paddingMode = getNextPadding();
+ thread = new Thread(this);
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ } while (hasNextPadding());
+ } while (hasNextMode());
+ } while (hasNextKey());
+ }
+
+ public void run() {
+ try {
+ crypt();
+ } catch (Exception e) {
+ if(errorSB == null) {
+ errorSB = new StringBuffer();
+ }
+ errorSB.append(e.getMessage());
+ errorSB.append("\n");
+ errorSB.append(getCipherParameters());
+ errorSB.append("\n");
+ StackTraceElement[] st = e.getStackTrace();
+ for (int i = 0; i < st.length; i++) {
+ errorSB.append(st[i].toString());
+ errorSB.append("\n");
+ }
+ fails++;
+ return;
+ }
+ flagTestResult = true;
+ }
+
+ public String getAlgName() {
+ return algName;
+ }
+
+ public int getKeyLength() {
+ return keyLength;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public String getPadding() {
+ return paddingMode;
+ }
+
+ public String getMode() {
+ return mode;
+ }
+
+ public String getCipherParameters() {
+ return "Alg name:" + algName + " Key:" + keyLength + " Mode:" + mode +
+ " Padding:" + paddingMode;
+ }
+
+ public boolean getTestStatus() {
+ return flagTestResult;
+ }
+
+ public String getAlgorithmName() {
+ return algName;
+ }
+
+ public boolean hasNextKey() {
+ return (kCounter < keyLengthAr.length);
+ }
+
+ public boolean hasNextMode() {
+ return (mCounter < modeAr.length);
+ }
+
+ public boolean hasNextPadding() {
+ return (pCounter < paddingModeAr.length);
+ }
+
+ public int getNextKey() {
+ kCounter = (hasNextKey()) ? kCounter : 0;
+ return keyLengthAr[kCounter++];
+ }
+
+ public String getNextMode() {
+ mCounter = (hasNextMode()) ? mCounter : 0;
+ return modeAr[mCounter++];
+ }
+
+ public String getNextPadding() {
+ pCounter = (hasNextPadding()) ? pCounter : 0;
+ return paddingModeAr[pCounter++];
+ }
+
+ public long getTotalCasesNumber() {
+ return keyLengthAr.length * modeAr.length * paddingModeAr.length;
+ }
+
+ public long getTotalFailuresNumber() {
+ return fails;
+ }
+
+ public String getFailureMessages() {
+ return (errorSB == null) ? "" : new String(errorSB);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherWrapThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherWrapThread.java
new file mode 100644
index 0000000..2b34c1c
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/CipherWrapThread.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+
+import java.security.Key;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+
+public class CipherWrapThread extends CipherThread {
+ CipherWrapThread(String name, int[] keys, String[] modes, String[] paddings) {
+ super(name, keys, modes, paddings);
+ }
+
+ @Override
+ public void crypt() throws Exception {
+ KeyGenerator kg = KeyGenerator.getInstance(getAlgName().replace("Wrap", ""));
+ kg.init(getKeyLength(), new SecureRandom());
+ Key key = kg.generateKey();
+
+ Cipher cip = Cipher.getInstance(getAlgName() + "/" + getMode() + "/" +
+ getPadding());
+
+ cip.init(Cipher.WRAP_MODE, key);
+ byte[] output = cip.wrap(key);
+ cip.init(Cipher.UNWRAP_MODE, key);
+ Key decrypted = cip.unwrap(output, getAlgName(), Cipher.SECRET_KEY);
+
+ checkEncodedData(key.getFormat().getBytes(), decrypted.getFormat().getBytes());
+ checkEncodedData(key.getEncoded(), decrypted.getEncoded());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
new file mode 100644
index 0000000..d0e5f6a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementFunctionalTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import targets.KeyAgreement;
+
+@TestTargetClass(KeyAgreement.DH.class)
+public class KeyAgreementFunctionalTest extends TestCase {
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ )
+ public void test_KeyAgreement() throws Exception {
+ String[] algArray = {"DES", "DESede"};
+
+ KeyAgreementThread kat = new KeyAgreementThread(algArray);
+ kat.launcher();
+
+ assertEquals(kat.getFailureMessages(), 0, kat.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementThread.java
new file mode 100644
index 0000000..51c9fb7
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyAgreementThread.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import java.security.AlgorithmParameterGenerator;
+import java.security.AlgorithmParameters;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.X509EncodedKeySpec;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.DHParameterSpec;
+
+public class KeyAgreementThread extends TestThread {
+ class KeyAgreementGen {
+ private PrivateKey privateKey = null;
+ private byte[] publicKeyBytes = null;
+
+ KeyAgreementGen(DHParameterSpec parameterSpec)
+ throws Exception {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH");
+ keyGen.initialize(parameterSpec);
+ KeyPair keypair = keyGen.generateKeyPair();
+
+ privateKey = keypair.getPrivate();
+ publicKeyBytes = keypair.getPublic().getEncoded();
+ }
+
+ public byte[] getPublicKeyBytes () {
+ return publicKeyBytes;
+ }
+
+ public SecretKey getSecretKey(String alg, byte[] publicKey) throws Exception {
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
+ KeyFactory keyFact = KeyFactory.getInstance("DH");
+ PublicKey pubKey = keyFact.generatePublic(x509KeySpec);
+
+ KeyAgreement ka = KeyAgreement.getInstance("DH");
+ ka.init(privateKey);
+ ka.doPhase(pubKey, true);
+
+ return ka.generateSecret(alg);
+ }
+ }
+
+ public KeyAgreementThread(String[] names) {
+ super(names);
+ }
+
+ @Override
+ public void test() throws Exception {
+ AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH");
+ apg.init(1024, new SecureRandom());
+ AlgorithmParameters ap = apg.generateParameters();
+ DHParameterSpec ps = ap.getParameterSpec(DHParameterSpec.class);
+
+ KeyAgreementGen kag1 = new KeyAgreementGen(ps);
+ KeyAgreementGen kag2 = new KeyAgreementGen(ps);
+
+ byte[] bArray1 = kag1.getPublicKeyBytes();
+ byte[] bArray2 = kag2.getPublicKeyBytes();
+
+ SecretKey sk1 = kag1.getSecretKey(algName, bArray2);
+ SecretKey sk2 = kag2.getSecretKey(algName, bArray1);
+
+ if (sk1.equals(sk2) == false) {
+ throw new Exception ("Generated keys are not the same");
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java
new file mode 100644
index 0000000..dde6fbd
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorFunctionalTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import targets.KeyGenerator;
+
+@TestTargetClass(KeyGenerator.AES.class)
+public class KeyGeneratorFunctionalTest extends TestCase {
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.DES.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.DESede.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.HMACMD5.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.HMACSHA1.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.HMACSHA256.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.HMACSHA384.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = KeyGenerator.HMACSHA512.class,
+ method = "method",
+ args = {}
+ )})
+ public void test_() throws Exception {
+ String[] algArray = {/*"DH",*/ "AES", "DES", "DESEDE", "DESede",
+ "HMACMD5", "HmacMD5", "HMACSHA1", "HmacSHA1", "HMACSHA256",
+ "HmacSHA256", "HMACSHA384", "HmacSHA384", "HMACSHA512",
+ "HmacSHA512"};
+
+ KeyGeneratorThread kgt = new KeyGeneratorThread(algArray);
+ kgt.launcher();
+
+ assertEquals(kgt.getFailureMessages(), 0, kgt.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorThread.java
new file mode 100644
index 0000000..52a7b5d
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/KeyGeneratorThread.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.KeyGenerator;
+
+public class KeyGeneratorThread extends TestThread {
+ KeyGeneratorThread(String[] names) {
+ super(names);
+ }
+
+ public void test() throws Exception {
+ KeyGenerator kg = KeyGenerator.getInstance(algName);
+ Key k = kg.generateKey();
+ if(kg.getAlgorithm().toLowerCase().equals(k.getAlgorithm().toLowerCase()) != true) {
+ throw new Exception ("Algorithm names not matched for KeyGenerator" +
+ " and for Key objects");
+ }
+ if(kg.getAlgorithm().toLowerCase().equals(algName.toLowerCase()) != true) {
+ throw new Exception ("Algorithm names not matched for KeyGenerator" +
+ " and for Key objects");
+ }
+ byte[] array1 = k.getEncoded();
+ k = kg.generateKey();
+ byte[] array2 = k.getEncoded();
+ int matches = 0;
+ for (int i = 0; i < array1.length; i++) {
+ if (array1[i] == array2[i]) {
+ matches++;
+ }
+ }
+ if (matches > array1.length / 2) {
+ throw new Exception("Generated keys are simular");
+ }
+ SecureRandom random = new SecureRandom();
+ kg.init(random);
+ matches = 0;
+ k = kg.generateKey();
+ array1 = k.getEncoded();
+ random = new SecureRandom();
+ kg.init(random);
+ k = kg.generateKey();
+ array2 = k.getEncoded();
+ for (int i = 0; i < array1.length; i++) {
+ if (array1[i] == array2[i]) {
+ matches++;
+ }
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java
new file mode 100644
index 0000000..bfe486a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacFunctionalTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import targets.Mac;
+
+@TestTargetClass(Mac.HMACMD5.class)
+public class MacFunctionalTest extends TestCase {
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA1.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA256.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA384.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = Mac.HMACSHA512.class,
+ method = "method",
+ args = {}
+ )
+})
+ public void test_Mac() throws Exception {
+ String[] algArray = {"HMACSHA1", "HMACSHA256", "HMACSHA384",
+ "HMACSHA512", "HMACMD5"};
+
+ MacThread mt = new MacThread(algArray);
+ mt.launcher();
+
+ assertEquals(mt.getFailureMessages(), 0, mt.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacThread.java
new file mode 100644
index 0000000..de519d7
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/MacThread.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public class MacThread extends TestThread {
+ MacThread(String[] names) {
+ super(names);
+ }
+
+ @Override
+ public void test() throws Exception {
+ int size = 256;
+ byte[] src1 = new byte[size];
+ byte[] src2 = new byte[size];
+ byte[] src3 = new byte[size];
+ int i;
+
+ for (i = 0; i < size; i++) {
+ src1[i] = (byte)i;
+ src2[i] = (byte)i;
+ src3[i] = (byte)(size - i - 1);
+ }
+ Mac m = Mac.getInstance(algName);
+ byte[] b = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)0};
+ SecretKeySpec sks = new SecretKeySpec(b, "SHA1");
+ m.init(sks);
+
+ byte[] res = m.doFinal(src1);
+ String sign1 = new String(res);
+ m.init(sks);
+ res = m.doFinal(src2);
+ String sign2 = new String(res);
+ m.init(sks);
+ res = m.doFinal(src3);
+ String sign3 = new String(res);
+ if (sign1.compareTo(sign2) != 0 || sign1.compareTo(sign3) == 0 ||
+ sign2.compareTo(sign3) == 0) {
+ throw new Exception ("Signature is not correct for algorithm " + algName);
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java
new file mode 100644
index 0000000..286bb5b
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryFunctionalTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import targets.SecretKeyFactory;
+
+@TestTargetClass(SecretKeyFactory.DES.class)
+public class SecretKeyFactoryFunctionalTest extends TestCase {
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SecretKeyFactory.DESede.class,
+ method = "method",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = SecretKeyFactory.PBEWITHMD5ANDDES.class,
+ method = "method",
+ args = {}
+ )
+})
+ public void test_() throws Exception {
+ String[] algArray = {"DES", "DESede", "PBEWITHMD5ANDDES",
+ "PBEWithSHA1AndDESede", "PBEWithSHA1AndRC2_40"};
+
+ SecretKeyFactoryThread skft = new SecretKeyFactoryThread(algArray);
+ skft.launcher();
+
+ assertEquals(skft.getFailureMessages(), 0, skft.getTotalFailuresNumber());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryThread.java
new file mode 100644
index 0000000..d426939
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/SecretKeyFactoryThread.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import javax.crypto.spec.DESedeKeySpec;
+import javax.crypto.spec.PBEKeySpec;
+
+public class SecretKeyFactoryThread extends TestThread {
+ SecretKeyFactoryThread(String[] names) {
+ super(names);
+ }
+
+ @Override
+ public void test() throws Exception {
+ SecretKeyFactory skf = SecretKeyFactory.getInstance(algName);
+ byte[] b = new byte[24];
+ KeySpec ks = (KeySpec) ((algName == "DES") ? new DESKeySpec(b) :
+ (algName == "DESede") ? new DESedeKeySpec(b) :
+ new PBEKeySpec("passw".toCharArray()));
+ skf.generateSecret(ks);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/TestThread.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/TestThread.java
new file mode 100644
index 0000000..f970b1a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/func/TestThread.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.crypto.tests.javax.crypto.func;
+
+public abstract class TestThread implements Runnable {
+ public String[] algNamesArray = null;
+ public int aCounter = 0;
+ public String algName = null;
+ public StringBuffer errorSB = null;
+ public int fails = 0;
+ public boolean flagTestResult = false;
+
+ TestThread(String[] names) {
+ algNamesArray = names;
+ aCounter = 0;
+ }
+
+ public abstract void test() throws Exception;
+
+ public void launcher() {
+ Thread thread = null;
+
+ do {
+ algName = getNextAlgorithmName();
+ thread = new Thread(this);
+ thread.start();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ } while (hasAlgorithmName());
+ }
+
+ public void run() {
+ try {
+ test();
+ } catch (Exception e) {
+ if(errorSB == null) {
+ errorSB = new StringBuffer();
+ }
+ errorSB.append(e.getMessage());
+ errorSB.append("\n");
+ errorSB.append(getAlgorithmName());
+ errorSB.append("\n");
+ StackTraceElement[] st = e.getStackTrace();
+ for (int i = 0; i < st.length; i++) {
+ errorSB.append(st[i].toString());
+ errorSB.append("\n");
+ }
+ fails++;
+ return;
+ }
+ flagTestResult = true;
+ }
+
+ public String getAlgorithmName() {
+ return algName;
+ }
+
+ public boolean hasAlgorithmName() {
+ return (aCounter < algNamesArray.length);
+ }
+
+ public String getNextAlgorithmName() {
+ aCounter = (hasAlgorithmName()) ? aCounter : 0;
+ return algNamesArray[aCounter++];
+ }
+
+ public long getTotalFailuresNumber() {
+ return fails;
+ }
+
+ public String getFailureMessages() {
+ return (errorSB == null) ? "" : new String(errorSB);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java
new file mode 100644
index 0000000..b66a384
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/AllTests.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.interfaces;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(DHPrivateKeyTest.class);
+ suite.addTestSuite(DHPublicKeyTest.class);
+ suite.addTestSuite(PBEKeyTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
new file mode 100644
index 0000000..f47d693
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPrivateKeyTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+import javax.crypto.interfaces.DHKey;
+import javax.crypto.interfaces.DHPrivateKey;
+import javax.crypto.spec.DHParameterSpec;
+
+import junit.framework.TestCase;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+
+/**
+ * Tests for <code>DHPrivateKey</code> class field
+ *
+ */
+@TestTargetClass(DHPrivateKey.class)
+public class DHPrivateKeyTest extends TestCase {
+
+ /**
+ * Test for <code>serialVersionUID</code> field
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "tests serialVersionUID for a fixed value",
+ method = "!field:serialVersionUID"
+ )
+ public void testField() {
+ checkDHPrivateKey key = new checkDHPrivateKey();
+ assertEquals("Incorrect serialVersionUID",
+ key.getSerVerUID(), //DHPrivateKey.serialVersionUID
+ 2211791113380396553L);
+ }
+
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getX",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ clazz = DHKey.class,
+ method = "getParams",
+ args = {}
+ )
+ })
+ public void test_getParams() throws Exception {
+ KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
+ kg.initialize(512);
+ KeyPair kp1 = kg.genKeyPair();
+ KeyPair kp2 = kg.genKeyPair();
+ DHPrivateKey pk1 = (DHPrivateKey) kp1.getPrivate();
+ DHPrivateKey pk2 = (DHPrivateKey) kp2.getPrivate();
+
+ assertTrue(pk1.getX().getClass().getCanonicalName().equals("java.math.BigInteger"));
+ assertTrue(pk1.getParams().getClass().getCanonicalName().equals("javax.crypto.spec.DHParameterSpec"));
+ assertFalse(pk1.getX().equals(pk2.getX()));
+ assertTrue(pk1.getX().equals(pk1.getX()));
+ }
+
+ public class checkDHPrivateKey implements DHPrivateKey {
+ public String getAlgorithm() {
+ return "SecretKey";
+ }
+ public String getFormat() {
+ return "Format";
+ }
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ public long getSerVerUID() {
+ return serialVersionUID;
+ }
+ public BigInteger getX() {
+ return null;
+ }
+ public DHParameterSpec getParams() {
+ return null;
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
new file mode 100644
index 0000000..2ca738e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/DHPublicKeyTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+import javax.crypto.interfaces.DHKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+
+
+/**
+ * Tests for <code>DHPublicKey</code> class field
+ *
+ */
+@TestTargetClass(DHPublicKey.class)
+public class DHPublicKeyTest extends TestCase {
+
+ /**
+ * Test for <code>serialVersionUID</code> field
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "tests serialVersionUID for a fixed value",
+ method = "!field:serialVersionUID"
+ )
+ public void testField() {
+ checkDHPublicKey key = new checkDHPublicKey();
+ assertEquals("Incorrect serialVersionUID",
+ key.getSerVerUID(), //DHPublicKey.serialVersionUID
+ -6628103563352519193L);
+ }
+
+@TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getY",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ clazz = DHKey.class,
+ method = "getParams",
+ args = {}
+ )
+ })
+ public void test_getParams() throws Exception {
+ KeyPairGenerator kg = KeyPairGenerator.getInstance("DH");
+ kg.initialize(512);
+ KeyPair kp1 = kg.genKeyPair();
+ KeyPair kp2 = kg.genKeyPair();
+ DHPublicKey pk1 = (DHPublicKey) kp1.getPublic();
+ DHPublicKey pk2 = (DHPublicKey) kp2.getPublic();
+
+ assertTrue(pk1.getY().getClass().getCanonicalName().equals("java.math.BigInteger"));
+ assertTrue(pk2.getParams().getClass().getCanonicalName().equals("javax.crypto.spec.DHParameterSpec"));
+ assertFalse(pk1.getY().equals(pk2.getY()));
+ assertTrue(pk1.getY().equals(pk1.getY()));
+ }
+
+ public class checkDHPublicKey implements DHPublicKey {
+ public String getAlgorithm() {
+ return "SecretKey";
+ }
+ public String getFormat() {
+ return "Format";
+ }
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ public long getSerVerUID() {
+ return serialVersionUID;
+ }
+ public BigInteger getY() {
+ return null;
+ }
+ public DHParameterSpec getParams() {
+ return null;
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java
new file mode 100644
index 0000000..43d9265
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/interfaces/PBEKeyTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.interfaces;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+
+import javax.crypto.interfaces.PBEKey;
+
+
+/**
+ * Tests for <code>PBEKey</code> class field
+ *
+ */
+@TestTargetClass(PBEKey.class)
+public class PBEKeyTest extends TestCase {
+
+
+ /**
+ * Test for <code>serialVersionUID</code> field
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "tests serialVersionUID for a fixed value",
+ method = "!field:serialVersionUID"
+ )
+ public void testField() {
+ checkPBEKey key = new checkPBEKey();
+ assertEquals("Incorrect serialVersionUID",
+ key.getSerVerUID(), //PBEKey.serialVersionUID
+ -1430015993304333921L);
+ }
+
+@TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getIterationCount",
+ args = {}
+ )
+ public void test_getIterationCount() throws Exception {
+ checkPBEKey key = new checkPBEKey();
+
+ key.getIterationCount();
+ }
+
+@TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getPassword",
+ args = {}
+ )
+ public void test_getPassword() throws Exception {
+ checkPBEKey key = new checkPBEKey();
+
+ key.getPassword();
+ }
+
+@TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getSalt",
+ args = {}
+ )
+ public void test_getSalt() throws Exception {
+ checkPBEKey key = new checkPBEKey();
+
+ key.getSalt();
+ }
+
+ public class checkPBEKey implements PBEKey {
+ public String getAlgorithm() {
+ return "SecretKey";
+ }
+ public String getFormat() {
+ return "Format";
+ }
+ public byte[] getEncoded() {
+ return new byte[0];
+ }
+ public long getSerVerUID() {
+ return serialVersionUID;
+ }
+ public BigInteger getY() {
+ return null;
+ }
+ public int getIterationCount() {
+ return 0;
+ }
+ public byte[] getSalt() {
+ return new byte[0];
+ }
+ public char[] getPassword() {
+ return new char[0];
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java
new file mode 100644
index 0000000..0be596e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/AllTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.serialization;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(BadPaddingExceptionTest.class);
+ suite.addTestSuite(ExemptionMechanismExceptionTest.class);
+ suite.addTestSuite(IllegalBlockSizeExceptionTest.class);
+ suite.addTestSuite(NoSuchPaddingExceptionTest.class);
+ suite.addTestSuite(ShortBufferExceptionTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java
new file mode 100644
index 0000000..2f632ae
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import javax.crypto.BadPaddingException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+/**
+ * Test for BadPaddingException serialization
+ *
+ */
+
+public class BadPaddingExceptionTest extends SerializationTest {
+
+ public static String[] msgs = {
+ "New message",
+ "Long message for Exception. Long message for Exception. Long message for Exception." };
+
+ protected Object[] getData() {
+ return new Object[] { new BadPaddingException(),
+ new BadPaddingException(null), new BadPaddingException(msgs[1]) };
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(BadPaddingExceptionTest.class);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java
new file mode 100644
index 0000000..7fd8cd0
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import javax.crypto.ExemptionMechanismException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+/**
+ * Test for ExemptionMechanismException serialization
+ *
+ */
+
+public class ExemptionMechanismExceptionTest extends SerializationTest {
+
+ public static String[] msgs = {
+ "New message",
+ "Long message for Exception. Long message for Exception. Long message for Exception." };
+
+ protected Object[] getData() {
+ return new Object[] { new ExemptionMechanismException(),
+ new ExemptionMechanismException(null), new ExemptionMechanismException(msgs[1]) };
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(ExemptionMechanismExceptionTest.class);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java
new file mode 100644
index 0000000..2cc1daa
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import javax.crypto.IllegalBlockSizeException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+/**
+ * Test for IllegalBlockSizeException serialization
+ *
+ */
+
+public class IllegalBlockSizeExceptionTest extends SerializationTest {
+
+ public static String[] msgs = {
+ "New message",
+ "Long message for Exception. Long message for Exception. Long message for Exception." };
+
+ protected Object[] getData() {
+ return new Object[] { new IllegalBlockSizeException(),
+ new IllegalBlockSizeException(null), new IllegalBlockSizeException(msgs[1]) };
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(IllegalBlockSizeExceptionTest.class);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java
new file mode 100644
index 0000000..475bd2f
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import javax.crypto.NoSuchPaddingException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+/**
+ * Test for NuSuchPaddingException serialization
+ *
+ */
+
+public class NoSuchPaddingExceptionTest extends SerializationTest {
+
+ public static String[] msgs = {
+ "New message",
+ "Long message for Exception. Long message for Exception. Long message for Exception." };
+
+ protected Object[] getData() {
+ return new Object[] { new NoSuchPaddingException(),
+ new NoSuchPaddingException(null), new NoSuchPaddingException(msgs[1]) };
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(NoSuchPaddingExceptionTest.class);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java
new file mode 100644
index 0000000..ab696e8
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.serialization;
+
+import javax.crypto.ShortBufferException;
+
+import org.apache.harmony.testframework.serialization.SerializationTest;
+
+
+/**
+ * Test for ShortBufferException serialization
+ *
+ */
+
+public class ShortBufferExceptionTest extends SerializationTest {
+
+ public static String[] msgs = {
+ "New message",
+ "Long message for Exception. Long message for Exception. Long message for Exception." };
+
+ protected Object[] getData() {
+ return new Object[] { new ShortBufferException(),
+ new ShortBufferException(null), new ShortBufferException(msgs[1]) };
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(ShortBufferExceptionTest.class);
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java
new file mode 100644
index 0000000..d31dc54
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/AllTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * This is autogenerated source file. Includes tests for package org.apache.harmony.crypto.tests.javax.crypto.spec;
+ */
+
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All tests for package org.apache.harmony.crypto.tests.javax.crypto.spec;");
+ // $JUnit-BEGIN$
+
+ suite.addTestSuite(DESKeySpecTest.class);
+ suite.addTestSuite(DESedeKeySpecTest.class);
+ suite.addTestSuite(DHGenParameterSpecTest.class);
+ suite.addTestSuite(DHParameterSpecTest.class);
+ suite.addTestSuite(DHPrivateKeySpecTest.class);
+ suite.addTestSuite(DHPublicKeySpecTest.class);
+ suite.addTestSuite(IvParameterSpecTest.class);
+ suite.addTestSuite(OAEPParameterSpecTest.class);
+ suite.addTestSuite(PBEKeySpecTest.class);
+ suite.addTestSuite(PBEParameterSpecTest.class);
+ suite.addTestSuite(PSourceTest.class);
+ suite.addTestSuite(RC2ParameterSpecTest.class);
+ suite.addTestSuite(RC5ParameterSpecTest.class);
+ suite.addTestSuite(SecretKeySpecTest.class);
+
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java
new file mode 100644
index 0000000..9904eed
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESKeySpecTest.java
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.NullPointerException;
+import java.security.InvalidKeyException;
+import java.util.Arrays;
+
+import javax.crypto.spec.DESKeySpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DESKeySpec.class)
+/**
+ */
+
+public class DESKeySpecTest extends TestCase {
+
+ // DES weak and semi-weak keys
+ // Got from:
+ // FIP PUB 74
+ // FEDERAL INFORMATION PROCESSING STANDARDS PUBLICATION 1981
+ // GUIDELINES FOR IMPLEMENTING AND USING THE NBS DATA ENCRYPTION STANDARD
+ // http://www.dice.ucl.ac.be/crypto/standards/fips/fip74/fip74-1.pdf
+ private static final byte[][] semiweaks = {
+ {(byte) 0xE0, (byte) 0x01, (byte) 0xE0, (byte) 0x01,
+ (byte) 0xF1, (byte) 0x01, (byte) 0xF1, (byte) 0x01},
+
+ {(byte) 0x01, (byte) 0xE0, (byte) 0x01, (byte) 0xE0,
+ (byte) 0x01, (byte) 0xF1, (byte) 0x01, (byte) 0xF1},
+
+ {(byte) 0xFE, (byte) 0x1F, (byte) 0xFE, (byte) 0x1F,
+ (byte) 0xFE, (byte) 0x0E, (byte) 0xFE, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0xFE, (byte) 0x1F, (byte) 0xFE,
+ (byte) 0x0E, (byte) 0xFE, (byte) 0x0E, (byte) 0xFE},
+
+ {(byte) 0xE0, (byte) 0x1F, (byte) 0xE0, (byte) 0x1F,
+ (byte) 0xF1, (byte) 0x0E, (byte) 0xF1, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0xE0, (byte) 0x1F, (byte) 0xE0,
+ (byte) 0x0E, (byte) 0xF1, (byte) 0x0E, (byte) 0xF1},
+
+ {(byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE,
+ (byte) 0x01, (byte) 0xFE, (byte) 0x01, (byte) 0xFE},
+
+ {(byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01,
+ (byte) 0xFE, (byte) 0x01, (byte) 0xFE, (byte) 0x01},
+
+ {(byte) 0x01, (byte) 0x1F, (byte) 0x01, (byte) 0x1F,
+ (byte) 0x01, (byte) 0x0E, (byte) 0x01, (byte) 0x0E},
+
+ {(byte) 0x1F, (byte) 0x01, (byte) 0x1F, (byte) 0x01,
+ (byte) 0x0E, (byte) 0x01, (byte) 0x0E, (byte) 0x01},
+
+ {(byte) 0xE0, (byte) 0xFE, (byte) 0xE0, (byte) 0xFE,
+ (byte) 0xF1, (byte) 0xFE, (byte) 0xF1, (byte) 0xFE},
+
+ {(byte) 0xFE, (byte) 0xE0, (byte) 0xFE, (byte) 0xE0,
+ (byte) 0xFE, (byte) 0xF1, (byte) 0xFE, (byte) 0xF1},
+
+ {(byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01},
+
+ {(byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE,
+ (byte) 0xFE, (byte) 0xFE, (byte) 0xFE, (byte) 0xFE},
+
+ {(byte) 0xE0, (byte) 0xE0, (byte) 0xE0, (byte) 0xE0,
+ (byte) 0xF1, (byte) 0xF1, (byte) 0xF1, (byte) 0xF1},
+
+ {(byte) 0x1F, (byte) 0x1F, (byte) 0x1F, (byte) 0x1F,
+ (byte) 0x0E, (byte) 0x0E, (byte) 0x0E, (byte) 0x0E},
+ };
+
+ /* DES not weak or semi-weak keys */
+ private static final byte[][] notsemiweaks = {
+ {(byte) 0x1f, (byte) 0x1f, (byte) 0x1f, (byte) 0x1f,
+ (byte) 0x1f, (byte) 0x1f, (byte) 0x1f, (byte) 0x1f},
+
+ {(byte) 0xe0, (byte) 0xe0, (byte) 0xe0, (byte) 0xe0,
+ (byte) 0xe0, (byte) 0xe0, (byte) 0xe0, (byte) 0xe0}
+ };
+ /**
+ * Constructors testing. Tests behavior of each of two constructors
+ * in the cases of: null array, short array, normal array.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks both constructors.",
+ method = "DESKeySpec",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks both constructors.",
+ method = "DESKeySpec",
+ args = {byte[].class, int.class}
+ )
+ })
+ public void testDESKeySpec() {
+ try {
+ new DESKeySpec((byte []) null);
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ } catch (InvalidKeyException e) {
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ }
+ try {
+ new DESKeySpec(new byte [] {1, 2, 3});
+ fail("Should raise an InvalidKeyException on a short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ new DESKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8});
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ try {
+ new DESKeySpec((byte []) null, 1);
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ } catch (InvalidKeyException e) {
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ }
+ try {
+ new DESKeySpec(new byte [] {1, 2, 3, 4, 5, 6, 7, 8}, 1);
+ fail("Should raise an InvalidKeyException on a short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ new DESKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, 1);
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+
+ /**
+ * getKey() method testing. Checks that modification of returned key
+ * does not affect the internal key. Also test check an equality of
+ * the key with the key specified in the constructor. The object under
+ * the test is created by different constructors.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getKey",
+ args = {}
+ )
+ public void testGetKey() {
+ byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
+ DESKeySpec ks;
+ try {
+ ks = new DESKeySpec(key);
+ } catch (InvalidKeyException e) {
+ fail("InvalidKeyException should not be thrown.");
+ return;
+ }
+ byte[] res = ks.getKey();
+ assertTrue("The returned array should be equal to the specified "
+ + "in constructor.", Arrays.equals(key, res));
+ res[0] += 1;
+ assertFalse("The modification of returned key should not affect"
+ + "the underlying key.", key[0] == res[0]);
+
+ byte[] key1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
+ try {
+ ks = new DESKeySpec(key1, 2);
+ } catch (InvalidKeyException e) {
+ fail("InvalidKeyException should not be thrown.");
+ return;
+ }
+ res = ks.getKey();
+ assertNotSame("The returned array should not be the same object "
+ + "as specified in a constructor.", key1, res);
+ byte[] exp = new byte[8];
+ System.arraycopy(key1, 2, exp, 0, 8);
+ assertTrue("The returned array should be equal to the specified "
+ + "in constructor.", Arrays.equals(exp, res));
+ }
+
+ /**
+ * isParityAdjusted(byte[] key, offset) method testing. Tests if the
+ * method throws appropriate exceptions on incorrect byte array, if
+ * it returns false on the key which is not parity adjusted, and if
+ * it returns true on parity adjusted key.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isParityAdjusted",
+ args = {byte[].class, int.class}
+ )
+ public void testIsParityAdjusted() {
+ try {
+ DESKeySpec.isParityAdjusted(null, 1);
+ fail("Should raise an InvalidKeyException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+
+ byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
+ try {
+ DESKeySpec.isParityAdjusted(key, 1);
+ fail("Should raise an InvalidKeyException "
+ + "in case of short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+
+ byte[] key_not_pa = {1, 2, 3, 4, 5, 6, 7, 8};
+ try {
+ assertFalse("Method returns true when false is expected.",
+ DESKeySpec.isParityAdjusted(key_not_pa, 0));
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+
+ byte[] key_pa = {(byte) 128, (byte) 131, (byte) 133, (byte) 134,
+ (byte) 137, (byte) 138, (byte) 140, (byte) 143};
+ try {
+ assertTrue("Method returns false when true is expected.",
+ DESKeySpec.isParityAdjusted(key_pa, 0));
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+
+ /**
+ * isWeak(byte[] key, int offset) method testing. Tests if the
+ * method throws appropriate exceptions on incorrect byte array, if
+ * it returns true on weak or semi-weak keys, and if it returns
+ * false on other keys.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isWeak",
+ args = {byte[].class, int.class}
+ )
+ public void testIsWeak() {
+ try {
+ DESKeySpec.isWeak(null, 1);
+ fail("Should raise an InvalidKeyException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+
+ byte[] key = {1, 2, 3, 4, 5, 6, 7, 8};
+ try {
+ DESKeySpec.isWeak(key, 1);
+ fail("Should raise an InvalidKeyException "
+ + "in case of short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+
+ for (int i=0; i<semiweaks.length; i++) {
+ try {
+ assertTrue("Method returns false when true is expected",
+ DESKeySpec.isWeak(semiweaks[i], 0));
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+ for (int i=0; i<notsemiweaks.length; i++) {
+ try {
+ assertFalse("Method returns true when false is expected",
+ DESKeySpec.isWeak(notsemiweaks[i], 0));
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DESKeySpecTest.class);
+ }
+
+ public static void main(String args[]) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java
new file mode 100644
index 0000000..5c312a4
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DESedeKeySpecTest.java
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.NullPointerException;
+import java.security.InvalidKeyException;
+import java.util.Arrays;
+
+import javax.crypto.spec.DESedeKeySpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DESedeKeySpec.class)
+/**
+ */
+
+public class DESedeKeySpecTest extends TestCase {
+
+ /**
+ * Constructors testing. Tests behavior of each of two constructors
+ * in the cases of: null array, short array, normal array.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks both constructors.",
+ method = "DESedeKeySpec",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Checks both constructors.",
+ method = "DESedeKeySpec",
+ args = {byte[].class, int.class}
+ )
+ })
+ public void testDESedeKeySpec() {
+ try {
+ new DESedeKeySpec((byte []) null);
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ } catch (InvalidKeyException e) {
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ }
+ try {
+ new DESedeKeySpec(new byte [] {1, 2, 3});
+ fail("Should raise an InvalidKeyException on a short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ new DESedeKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4});
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ try {
+ new DESedeKeySpec((byte []) null, 1);
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ } catch (InvalidKeyException e) {
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ }
+ try {
+ new DESedeKeySpec(new byte [] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4}, 1);
+ fail("Should raise an InvalidKeyException on a short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+ try {
+ new DESedeKeySpec(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5}, 1);
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+
+ /**
+ * getKey() method testing. Checks that modification of returned key
+ * does not affect the internal key. Also test check an equality of
+ * the key with the key specified in the constructor. The object under
+ * the test is created by different constructors.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getKey",
+ args = {}
+ )
+ public void testGetKey() {
+ byte[] key = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2};
+ DESedeKeySpec ks;
+ try {
+ ks = new DESedeKeySpec(key);
+ } catch (InvalidKeyException e) {
+ fail("InvalidKeyException should not be thrown.");
+ return;
+ }
+ byte[] res = ks.getKey();
+ assertTrue("The returned array should be equal to the specified "
+ + "in constructor.", Arrays.equals(key, res));
+ res[0] += 1;
+ assertFalse("The modification of returned key should not affect"
+ + "the underlying key.", key[0] == res[0]);
+
+ byte[] key1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3};
+ try {
+ ks = new DESedeKeySpec(key1, 2);
+ } catch (InvalidKeyException e) {
+ fail("InvalidKeyException should not be thrown.");
+ return;
+ }
+ res = ks.getKey();
+ assertNotSame("The returned array should not be the same object "
+ + "as specified in a constructor.", key1, res);
+ byte[] exp = new byte[24];
+ System.arraycopy(key1, 2, exp, 0, 24);
+ assertTrue("The returned array should be equal to the specified "
+ + "in constructor.", Arrays.equals(exp, res));
+ }
+
+ /**
+ * isParityAdjusted(byte[] key, offset) method testing. Tests if the
+ * method throws appropriate exceptions on incorrect byte array, if
+ * it returns false on the key which is not parity adjusted, and if
+ * it returns true on parity adjusted key.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isParityAdjusted",
+ args = {byte[].class, int.class}
+ )
+ public void testIsParityAdjusted() {
+ try {
+ DESedeKeySpec.isParityAdjusted(null, 1);
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ } catch (NullPointerException e) {
+ } catch (InvalidKeyException e) {
+ fail("Should raise an NullPointerException "
+ + "in case of null byte array.");
+ }
+
+ byte[] key = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
+ try {
+ DESedeKeySpec.isParityAdjusted(key, 1);
+ fail("Should raise an InvalidKeyException "
+ + "in case of short byte array.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ }
+
+ byte[] key_not_pa = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2};
+ try {
+ assertFalse("Method returns true when false is expected.",
+ DESedeKeySpec.isParityAdjusted(key_not_pa, 0));
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+
+ byte[] key_pa = {(byte) 128, (byte) 131, (byte) 133, (byte) 134,
+ (byte) 137, (byte) 138, (byte) 140, (byte) 143,
+ (byte) 145, (byte) 146, (byte) 148, (byte) 151,
+ (byte) 152, (byte) 155, (byte) 157, (byte) 158,
+ (byte) 161, (byte) 162, (byte) 164, (byte) 167,
+ (byte) 168, (byte) 171, (byte) 173, (byte) 174};
+ try {
+ assertTrue("Method returns false when true is expected.",
+ DESedeKeySpec.isParityAdjusted(key_pa, 0));
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ } catch (InvalidKeyException e) {
+ fail("Unexpected InvalidKeyException was thrown.");
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DESedeKeySpecTest.class);
+ }
+
+ public static void main(String args[]) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java
new file mode 100644
index 0000000..7b09cb6
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHGenParameterSpecTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.Integer;
+
+import javax.crypto.spec.DHGenParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DHGenParameterSpec.class)
+/**
+ */
+
+public class DHGenParameterSpecTest extends TestCase {
+
+ /**
+ * DHGenParameterSpec class testing. Tests the equivalence of
+ * parameters specified in the constructor with the values returned
+ * by getters.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "DHGenParameterSpec",
+ args = {int.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getExponentSize",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getPrimeSize",
+ args = {}
+ )
+ })
+ public void testDHGenParameterSpec() {
+ int[] primes = {Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
+ int[] exponents = {Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
+ for (int i=0; i<primes.length; i++) {
+ DHGenParameterSpec ps = new DHGenParameterSpec(primes[i],
+ exponents[i]);
+ assertEquals("The value returned by getPrimeSize() must be "
+ + "equal to the value specified in the constructor",
+ ps.getPrimeSize(), primes[i]);
+ assertEquals("The value returned by getExponentSize() must be "
+ + "equal to the value specified in the constructor",
+ ps.getPrimeSize(), exponents[i]);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DHGenParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java
new file mode 100644
index 0000000..0c0ac3b
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHParameterSpecTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.Integer;
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DHParameterSpec.class)
+/**
+ */
+
+public class DHParameterSpecTest extends TestCase {
+
+ /**
+ * DHParameterSpec class testing. Tests the equivalence of parameters
+ * specified in the constructor with the values returned by getters.
+ * The tested object is created by different constructors.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "DHParameterSpec",
+ args = {java.math.BigInteger.class, java.math.BigInteger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "DHParameterSpec",
+ args = {java.math.BigInteger.class, java.math.BigInteger.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getG",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getL",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getP",
+ args = {}
+ )
+ })
+ public void testDHParameterSpec() {
+ BigInteger[] ps = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ BigInteger[] gs = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ int[] ls = {Integer.MIN_VALUE, 0, 1, Integer.MAX_VALUE};
+ for (int i=0; i<ps.length; i++) {
+ DHParameterSpec dhps = new DHParameterSpec(ps[i], gs[i]);
+ assertEquals("The value returned by getP() must be "
+ + "equal to the value specified in the constructor",
+ dhps.getP(), ps[i]);
+ assertEquals("The value returned by getG() must be "
+ + "equal to the value specified in the constructor",
+ dhps.getG(), gs[i]);
+ }
+ for (int i=0; i<ps.length; i++) {
+ DHParameterSpec dhps = new DHParameterSpec(ps[i], gs[i], ls[i]);
+ assertEquals("The value returned by getP() must be "
+ + "equal to the value specified in the constructor",
+ dhps.getP(), ps[i]);
+ assertEquals("The value returned by getG() must be "
+ + "equal to the value specified in the constructor",
+ dhps.getG(), gs[i]);
+ assertEquals("The value returned by getL() must be "
+ + "equal to the value specified in the constructor",
+ dhps.getL(), ls[i]);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DHParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java
new file mode 100644
index 0000000..7181623
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPrivateKeySpecTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHPrivateKeySpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DHPrivateKeySpec.class)
+/**
+ */
+
+public class DHPrivateKeySpecTest extends TestCase {
+
+ /**
+ * DHPrivateKeySpec class testing. Tests the equivalence of parameters
+ * specified in the constructor with the values returned by getters.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "DHPrivateKeySpec",
+ args = {java.math.BigInteger.class, java.math.BigInteger.class, java.math.BigInteger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getG",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getP",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getX",
+ args = {}
+ )
+ })
+ public void testDHPrivateKeySpec() {
+ BigInteger[] xs = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ BigInteger[] ps = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ BigInteger[] gs = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ for (int i=0; i<ps.length; i++) {
+ DHPrivateKeySpec dhpks = new DHPrivateKeySpec(xs[i], ps[i], gs[i]);
+ assertEquals("The value returned by getX() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getX(), xs[i]);
+ assertEquals("The value returned by getP() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getP(), ps[i]);
+ assertEquals("The value returned by getG() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getG(), gs[i]);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DHPrivateKeySpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java
new file mode 100644
index 0000000..064c713
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/DHPublicKeySpecTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.math.BigInteger;
+
+import javax.crypto.spec.DHPublicKeySpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(DHPublicKeySpec.class)
+/**
+ */
+
+public class DHPublicKeySpecTest extends TestCase {
+
+ /**
+ * DHPublicKeySpec class testing. Tests the equivalence of parameters
+ * specified in the constructor with the values returned by getters.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "DHPublicKeySpec",
+ args = {java.math.BigInteger.class, java.math.BigInteger.class, java.math.BigInteger.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getG",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getP",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "All functionality tested in one method. Probably it should be divided into several tests.",
+ method = "getY",
+ args = {}
+ )
+ })
+ public void testDHPrivateKeySpec() {
+ BigInteger[] ys = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ BigInteger[] ps = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ BigInteger[] gs = {new BigInteger("-1000000000000"), BigInteger.ZERO,
+ BigInteger.ONE, new BigInteger("1000000000000")};
+ for (int i=0; i<ps.length; i++) {
+ DHPublicKeySpec dhpks = new DHPublicKeySpec(ys[i], ps[i], gs[i]);
+ assertEquals("The value returned by getY() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getY(), ys[i]);
+ assertEquals("The value returned by getP() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getP(), ps[i]);
+ assertEquals("The value returned by getG() must be "
+ + "equal to the value specified in the constructor",
+ dhpks.getG(), gs[i]);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(DHPublicKeySpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java
new file mode 100644
index 0000000..fda566a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/IvParameterSpecTest.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.NullPointerException;
+import java.lang.IllegalArgumentException;
+import java.lang.ArrayIndexOutOfBoundsException;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(IvParameterSpec.class)
+/**
+ */
+
+public class IvParameterSpecTest extends TestCase {
+
+ /**
+ * IvParameterSpec(byte[] iv) constructor testing. Checks that
+ * NullPointerException is thrown in the case of null input
+ * array and that input array is copied during initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "IvParameterSpec",
+ args = {byte[].class}
+ )
+ public void testIvParameterSpec1() {
+ try {
+ new IvParameterSpec(null);
+ fail("Should raise an NullPointerException "
+ + "in the case of null byte array.");
+ } catch(NullPointerException e) {
+ }
+
+ byte[] iv = new byte[] {1, 2, 3, 4, 5};
+ IvParameterSpec ivps = new IvParameterSpec(iv);
+ iv[0] ++;
+ assertFalse("The change of input array's content should not cause "
+ + "the change of internal array", iv[0] == ivps.getIV()[0]);
+ }
+
+ /**
+ * IvParameterSpec(byte[] iv) constructor testing. Checks that
+ * NullPointerException is thrown in the case of null input
+ * array and that input array is copied during initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "IvParameterSpec",
+ args = {byte[].class, int.class, int.class}
+ )
+ public void testIvParameterSpec2() {
+ try {
+ new IvParameterSpec(null, 1, 1);
+ fail("Should raise an IllegalArgumentException "
+ + "in the case of null byte array.");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ fail("Unexpected ArrayIndexOutOfBoundsException was thrown");
+ } catch(IllegalArgumentException e) {
+ } catch(NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown");
+ }
+
+ try {
+ new IvParameterSpec(new byte[] {1, 2, 3}, 2, 2);
+ fail("Should raise an IllegalArgumentException "
+ + "if (iv.length - offset < len).");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ fail("Unexpected ArrayIndexOutOfBoundsException was thrown");
+ } catch(IllegalArgumentException e) {
+ } catch(NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown");
+ }
+
+ try {
+ new IvParameterSpec(new byte[] {1, 2, 3}, -1, 1);
+ fail("Should raise an ArrayIndexOutOfBoundsException "
+ + "if offset index bytes outside the iv.");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ } catch(IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown");
+ } catch(NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown");
+ }
+
+ /* TODO: DRL fail with java.lang.NegativeArraySizeException
+ try {
+ new IvParameterSpec(new byte[] {1, 2, 3}, 1, -2);
+ fail("Should raise an ArrayIndexOutOfBoundsException "
+ + "if len index bytes outside the iv.");
+ } catch(ArrayIndexOutOfBoundsException e) {
+ } catch(IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown");
+ } catch(NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown");
+ }
+ */
+
+ byte[] iv = new byte[] {1, 2, 3, 4, 5};
+ IvParameterSpec ivps = new IvParameterSpec(iv, 0, iv.length);
+ iv[0] ++;
+ assertFalse("The change of input array's content should not cause "
+ + "the change of internal array", iv[0] == ivps.getIV()[0]);
+
+ //Regression for HARMONY-1089
+ try {
+ new IvParameterSpec(new byte[2], 2, -1);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getIV",
+ args = {}
+ )
+ public void testGetIV() {
+ byte[] iv = new byte[] {1, 2, 3, 4, 5};
+ IvParameterSpec ivps = new IvParameterSpec(iv);
+ iv = ivps.getIV();
+ iv[0] ++;
+ assertFalse("The change of returned array should not cause "
+ + "the change of internal array", iv[0] == ivps.getIV()[0]);
+ }
+
+ public static Test suite() {
+ return new TestSuite(IvParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java
new file mode 100644
index 0000000..6b2c673
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/OAEPParameterSpecTest.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(OAEPParameterSpec.class)
+/**
+ */
+
+public class OAEPParameterSpecTest extends TestCase {
+
+ /**
+ * OAEPParameterSpec(String mdName, String mgfName, AlgorithmParameterSpec
+ * mgfSpec, PSource pSrc) method testing. Tests that NullPointerException
+ * is thrown in the case of inappropriate constructor parameters and checks
+ * the value of DEFAULT field.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "OAEPParameterSpec",
+ args = {java.lang.String.class, java.lang.String.class, java.security.spec.AlgorithmParameterSpec.class, javax.crypto.spec.PSource.class}
+ )
+ public void testOAEPParameterSpec() {
+ // using init values for OAEPParameterSpec.DEFAULT
+ String mdName = "SHA-1";
+ String mgfName = "MGF1";
+ AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+ PSource pSrc = PSource.PSpecified.DEFAULT;
+
+ try {
+ new OAEPParameterSpec(null, mgfName, mgfSpec, pSrc);
+ fail("NullPointerException should be thrown in the case of "
+ + "null mdName.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new OAEPParameterSpec(mdName, null, mgfSpec, pSrc);
+ fail("NullPointerException should be thrown in the case of "
+ + "null mgfName.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new OAEPParameterSpec(mdName, mgfName, mgfSpec, null);
+ fail("NullPointerException should be thrown in the case of "
+ + "null pSrc.");
+ } catch (NullPointerException e) {
+ }
+
+ assertTrue("The message digest algorithm name of "
+ + "OAEPParameterSpec.DEFAULT field should be " + mdName,
+ OAEPParameterSpec.DEFAULT.getDigestAlgorithm().equals(mdName));
+
+ assertTrue("The mask generation function algorithm name of "
+ + "OAEPParameterSpec.DEFAULT field should be " + mgfName,
+ OAEPParameterSpec.DEFAULT.getMGFAlgorithm().equals(mgfName));
+
+ assertTrue("The mask generation function parameters of "
+ + "OAEPParameterSpec.DEFAULT field should be the same object "
+ + "as MGF1ParameterSpec.SHA1",
+ OAEPParameterSpec.DEFAULT.getMGFParameters()
+ == MGF1ParameterSpec.SHA1);
+ assertTrue("The source of the encoding input P of "
+ + "OAEPParameterSpec.DEFAULT field should be the same object "
+ + "PSource.PSpecified.DEFAULT",
+ OAEPParameterSpec.DEFAULT.getPSource()
+ == PSource.PSpecified.DEFAULT);
+ }
+
+ /**
+ * getDigestAlgorithm() method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getDigestAlgorithm",
+ args = {}
+ )
+ public void testGetDigestAlgorithm() {
+ String mdName = "SHA-1";
+ String mgfName = "MGF1";
+ AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+ PSource pSrc = PSource.PSpecified.DEFAULT;
+
+ OAEPParameterSpec ps = new OAEPParameterSpec(mdName, mgfName,
+ mgfSpec, pSrc);
+ assertTrue("The returned value does not equal to the "
+ + "value specified in the constructor.",
+ ps.getDigestAlgorithm().equals(mdName));
+ }
+
+ /**
+ * getMGFAlgorithm() method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMGFAlgorithm",
+ args = {}
+ )
+ public void testGetMGFAlgorithm() {
+ String mdName = "SHA-1";
+ String mgfName = "MGF1";
+ AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+ PSource pSrc = PSource.PSpecified.DEFAULT;
+
+ OAEPParameterSpec ps = new OAEPParameterSpec(mdName, mgfName,
+ mgfSpec, pSrc);
+ assertTrue("The returned value does not equal to the "
+ + "value specified in the constructor.",
+ ps.getMGFAlgorithm().equals(mgfName));
+ }
+
+ /**
+ * getMGFParameters() method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMGFParameters",
+ args = {}
+ )
+ public void testGetMGFParameters() {
+ String mdName = "SHA-1";
+ String mgfName = "MGF1";
+ AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+ PSource pSrc = PSource.PSpecified.DEFAULT;
+
+ OAEPParameterSpec ps = new OAEPParameterSpec(mdName, mgfName,
+ mgfSpec, pSrc);
+ assertTrue("The returned value does not equal to the "
+ + "value specified in the constructor.",
+ ps.getMGFParameters() == mgfSpec);
+ }
+
+ /**
+ * getPSource() method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getPSource",
+ args = {}
+ )
+ public void testGetPSource() {
+ String mdName = "SHA-1";
+ String mgfName = "MGF1";
+ AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
+ PSource pSrc = PSource.PSpecified.DEFAULT;
+
+ OAEPParameterSpec ps = new OAEPParameterSpec(mdName, mgfName,
+ mgfSpec, pSrc);
+ assertTrue("The returned value does not equal to the "
+ + "value specified in the constructor.",
+ ps.getPSource() == pSrc);
+ }
+
+ public static Test suite() {
+ return new TestSuite(OAEPParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java
new file mode 100644
index 0000000..1cb017e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEKeySpecTest.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Arrays;
+
+import javax.crypto.spec.PBEKeySpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(PBEKeySpec.class)
+/**
+ */
+
+public class PBEKeySpecTest extends TestCase {
+
+ /**
+ * PBEKeySpec(char[] password) method testing. Tests the behavior of
+ * the method in the case of null input char array and tests that input
+ * array is copied during the object initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "PBEKeySpec",
+ args = {char[].class}
+ )
+ public void testPBEKeySpec1() {
+ try {
+ PBEKeySpec pbeks = new PBEKeySpec(null);
+ assertTrue("An empty char[] should be used in case of null "
+ + "char array.", pbeks.getPassword().length == 0);
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ }
+
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ PBEKeySpec pbeks = new PBEKeySpec(password);
+ password[0] ++;
+ assertFalse("The change of password specified in the constructor "
+ + "should not cause the change of internal array.",
+ password[0] == pbeks.getPassword()[0]);
+ }
+
+ /**
+ * PBEKeySpec(char[] password, byte[] salt, int iterationCount, int
+ * keyLength) method testing. Tests the behavior of the method in the case
+ * of inappropriate parameters and checks that array objects specified as
+ * a parameters are copied during the object initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "PBEKeySpec",
+ args = {char[].class, byte[].class, int.class, int.class}
+ )
+ public void testPBEKeySpec2() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ int keyLength = 10;
+
+ try {
+ PBEKeySpec pbeks = new PBEKeySpec(null, salt,
+ iterationCount, keyLength);
+ assertTrue("An empty char[] should be used in case of null input "
+ + "char array.", pbeks.getPassword().length == 0);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ }
+
+ try {
+ new PBEKeySpec(password, null, iterationCount, keyLength);
+ fail("A NullPointerException should be was thrown "
+ + "in the case of null salt.");
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, new byte [0], iterationCount, keyLength);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of empty salt.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, -1, keyLength);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of negative iterationCount.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, iterationCount, -1);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of negative keyLength.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, 0, keyLength);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of zero iterationCount.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, iterationCount, 0);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of zero keyLength.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ PBEKeySpec pbeks = new PBEKeySpec(password, salt,
+ iterationCount, keyLength);
+ password[0] ++;
+ assertFalse("The change of password specified in the constructor "
+ + "should not cause the change of internal array.",
+ password[0] == pbeks.getPassword()[0]);
+ salt[0] ++;
+ assertFalse("The change of salt specified in the constructor "
+ + " should not cause the change of internal array.",
+ salt[0] == pbeks.getSalt()[0]);
+ }
+
+ /**
+ * PBEKeySpec(char[] password, byte[] salt, int iterationCount) method
+ * testing. Tests the behavior of the method in the case
+ * of inappropriate parameters and checks that array objects specified as
+ * a parameters are copied during the object initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "PBEKeySpec",
+ args = {char[].class, byte[].class, int.class}
+ )
+ public void testPBEKeySpec3() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+
+ try {
+ PBEKeySpec pbeks = new PBEKeySpec(null, salt, iterationCount);
+ assertTrue("An empty char[] should be used in case of null input "
+ + "char array.", pbeks.getPassword().length == 0);
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown.");
+ } catch (NullPointerException e) {
+ fail("Unexpected NullPointerException was thrown.");
+ }
+
+ try {
+ new PBEKeySpec(password, null, iterationCount);
+ fail("A NullPointerException should be was thrown "
+ + "in the case of null salt.");
+ } catch (IllegalArgumentException e) {
+ fail("Unexpected IllegalArgumentException was thrown.");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, new byte [0],
+ iterationCount);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of empty salt.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, -1);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of negative iterationCount.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new PBEKeySpec(password, salt, 0);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of zero iterationCount.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ PBEKeySpec pbeks = new PBEKeySpec(password, salt, iterationCount);
+ password[0] ++;
+ assertFalse("The change of password specified in the constructor "
+ + "should not cause the change of internal array.",
+ password[0] == pbeks.getPassword()[0]);
+ salt[0] ++;
+ assertFalse("The change of salt specified in the constructor "
+ + " should not cause the change of internal array.",
+ salt[0] == pbeks.getSalt()[0]);
+ }
+
+ /**
+ * clearPassword() method testing. Tests that internal copy of password
+ * is cleared after the method call.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "clearPassword",
+ args = {}
+ )
+ public void testClearPassword() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ PBEKeySpec pbeks = new PBEKeySpec(password);
+ pbeks.clearPassword();
+ try {
+ pbeks.getPassword();
+ fail("An IllegalStateException should be was thrown "
+ + "after the clearing the password.");
+ } catch (IllegalStateException e) {
+ }
+ }
+
+ /**
+ * getPassword() method testing. Tests that returned password is equal
+ * to the password specified in the constructor and that the change of
+ * returned array does not cause the change of internal array.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Exception was checked in testClearPassword() method.",
+ method = "getPassword",
+ args = {}
+ )
+ public void testGetPassword() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ PBEKeySpec pbeks = new PBEKeySpec(password);
+ char[] result = pbeks.getPassword();
+ if (! Arrays.equals(password, result)) {
+ fail("The returned password is not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getPassword() method password "
+ + "should not cause the change of internal array.",
+ result[0] == pbeks.getPassword()[0]);
+ }
+
+ /**
+ * getSalt() method testing. Tests that returned salt is equal
+ * to the salt specified in the constructor and that the change of
+ * returned array does not cause the change of internal array.
+ * Also it checks that the method returns null if salt is not
+ * specified.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSalt",
+ args = {}
+ )
+ public void testGetSalt() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ PBEKeySpec pbeks = new PBEKeySpec(password, salt, iterationCount);
+ byte[] result = pbeks.getSalt();
+ if (! Arrays.equals(salt, result)) {
+ fail("The returned salt is not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getSalt() method salt"
+ + "should not cause the change of internal array.",
+ result[0] == pbeks.getSalt()[0]);
+ pbeks = new PBEKeySpec(password);
+ assertNull("The getSalt() method should return null if the salt "
+ + "is not specified.", pbeks.getSalt());
+ }
+
+ /**
+ * getIterationCount() method testing. Tests that returned value is equal
+ * to the value specified in the constructor.
+ * Also it checks that the method returns 0 if iterationCount is not
+ * specified.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getIterationCount",
+ args = {}
+ )
+ public void testGetIterationCount() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ PBEKeySpec pbeks = new PBEKeySpec(password, salt, iterationCount);
+ assertTrue("The returned iterationCount is not equal to the specified "
+ + "in the constructor.",
+ pbeks.getIterationCount() == iterationCount);
+ pbeks = new PBEKeySpec(password);
+ assertTrue("The getIterationCount() method should return 0 "
+ + "if the iterationCount is not specified.",
+ pbeks.getIterationCount() == 0);
+ }
+
+ /**
+ * getKeyLength() method testing.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getKeyLength",
+ args = {}
+ )
+ public void testGetKeyLength() {
+ char[] password = new char[] {'1', '2', '3', '4', '5'};
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ int keyLength = 10;
+ PBEKeySpec pbeks = new PBEKeySpec(password, salt,
+ iterationCount, keyLength);
+ assertTrue("The returned keyLength is not equal to the value specified "
+ + "in the constructor.",
+ pbeks.getKeyLength() == keyLength);
+ pbeks = new PBEKeySpec(password);
+ assertTrue("The getKeyLength() method should return 0 "
+ + "if the keyLength is not specified.",
+ pbeks.getKeyLength() == 0);
+ }
+
+ public static Test suite() {
+ return new TestSuite(PBEKeySpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java
new file mode 100644
index 0000000..b294995
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PBEParameterSpecTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Arrays;
+
+import javax.crypto.spec.PBEParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(PBEParameterSpec.class)
+/**
+ */
+
+public class PBEParameterSpecTest extends TestCase {
+
+ /**
+ * PBEParameterSpec(byte[] salt, int iterationCount) method testing.
+ * Tests the behavior of the method in the case of null input array
+ * and tests that input array is copied during the object initialization.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "PBEParameterSpec",
+ args = {byte[].class, int.class}
+ )
+ public void testPBEParameterSpec() {
+ byte[] salt = {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+
+ try {
+ new PBEParameterSpec(null, iterationCount);
+ fail("A NullPointerException should be was thrown "
+ + "in the case of null salt.");
+ } catch (NullPointerException e) {
+ }
+
+ PBEParameterSpec pbeps = new PBEParameterSpec(salt, iterationCount);
+ salt[0] ++;
+ assertFalse("The change of salt specified in the constructor "
+ + "should not cause the change of internal array.",
+ salt[0] == pbeps.getSalt()[0]);
+ }
+
+ /**
+ * getSalt() method testing. Tests that returned salt is equal
+ * to the salt specified in the constructor and that the change of
+ * returned array does not cause the change of internal array.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getSalt",
+ args = {}
+ )
+ public void testGetSalt() {
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ PBEParameterSpec pbeps = new PBEParameterSpec(salt, iterationCount);
+ byte[] result = pbeps.getSalt();
+ if (! Arrays.equals(salt, result)) {
+ fail("The returned salt is not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getSalt() method salt"
+ + "should not cause the change of internal array.",
+ result[0] == pbeps.getSalt()[0]);
+ }
+
+ /**
+ * getIterationCount() method testing. Tests that returned value is equal
+ * to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getIterationCount",
+ args = {}
+ )
+ public void testGetIterationCount() {
+ byte[] salt = new byte[] {1, 2, 3, 4, 5};
+ int iterationCount = 10;
+ PBEParameterSpec pbeps = new PBEParameterSpec(salt, iterationCount);
+ assertTrue("The returned iterationCount is not equal to the specified "
+ + "in the constructor.",
+ pbeps.getIterationCount() == iterationCount);
+ }
+
+ public static Test suite() {
+ return new TestSuite(PBEParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java
new file mode 100644
index 0000000..08e8acd
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/PSourceTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Alexander Y. Kleymenov
+ * @version $Revision$
+ */
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Arrays;
+import javax.crypto.spec.PSource;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(PSource.class)
+/**
+ */
+public class PSourceTest extends TestCase {
+
+ /**
+ * PSpecified(byte[] p) method testing. Tests that NullPointerException
+ * is thrown in the case of null p array. Also it checks the value of
+ * DEFAULT field, and that input p array is copied to protect against
+ * subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Nested class.",
+ clazz = PSource.PSpecified.class,
+ method = "PSpecified",
+ args = { byte[].class }
+ )
+ public void testPSpecified() {
+ try {
+ new PSource.PSpecified(null);
+ fail("NullPointerException should be thrown in the case of "
+ + "null p array.");
+ } catch (NullPointerException e) {
+ }
+
+ assertEquals("The PSource.PSpecified DEFAULT value should be byte[0]",
+ 0, PSource.PSpecified.DEFAULT.getValue().length);
+
+ byte[] p = new byte[] {1, 2, 3, 4, 5};
+ PSource.PSpecified ps = new PSource.PSpecified(p);
+ p[0]++;
+ assertFalse("The change of p specified in the constructor "
+ + "should not cause the change of internal array.", p[0] == ps
+ .getValue()[0]);
+ }
+
+ /**
+ * getValue() method testing. Tests that returned array is equal to the
+ * array specified in the constructor. Checks that modification
+ * of returned array does not affect the internal array.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = PSource.PSpecified.class,
+ method = "PSpecified",
+ args = {byte[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ clazz = PSource.PSpecified.class,
+ method = "getValue",
+ args = {}
+ )
+ })
+ public void testGetValue() {
+ byte[] p = new byte[] {1, 2, 3, 4, 5};
+
+ PSource.PSpecified ps = new PSource.PSpecified(p);
+ byte[] result = ps.getValue();
+ if (!Arrays.equals(p, result)) {
+ fail("The returned array does not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0]++;
+ assertFalse("The change of returned by getValue() array "
+ + "should not cause the change of internal array.",
+ result[0] == ps.getValue()[0]);
+ }
+
+
+ /**
+ * PSource(String pSrcName) method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Checks NullPointerException",
+ method = "PSource",
+ args = {java.lang.String.class}
+ )
+ public void testPSource() {
+ try {
+ new PSource(null) {};
+ fail("NullPointerException should be thrown in the case of "
+ + "null pSrcName.");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ /**
+ * getAlgorithm() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "PSource",
+ args = {java.lang.String.class}
+ )
+ })
+ public void testGetAlgorithm() {
+ String pSrcName = "pSrcName";
+ PSource ps = new PSource(pSrcName) {};
+ assertTrue("The returned value is not equal to the value specified "
+ + "in constructor", pSrcName.equals(ps.getAlgorithm()));
+ }
+
+ public static Test suite() {
+ return new TestSuite(PSourceTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java
new file mode 100644
index 0000000..cf72d23
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC2ParameterSpecTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.lang.IllegalArgumentException;
+import java.util.Arrays;
+
+import javax.crypto.spec.RC2ParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(RC2ParameterSpec.class)
+/**
+ */
+
+public class RC2ParameterSpecTest extends TestCase {
+
+ /**
+ * RC2ParameterSpec(int effectiveKeyBits, byte[] iv) method testing.
+ * Tests that IllegalArgumentException is thrown in the case of
+ * inappropriate constructor parameters and that input iv array is
+ * copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "RC2ParameterSpec",
+ args = {int.class, byte[].class}
+ )
+ public void testRC2ParameterSpec1() {
+ int effectiveKeyBits = 10;
+ byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ try {
+ new RC2ParameterSpec(effectiveKeyBits, null);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC2ParameterSpec(effectiveKeyBits, new byte[] {1, 2, 3, 4, 5});
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ RC2ParameterSpec ps = new RC2ParameterSpec(effectiveKeyBits, iv);
+ iv[0] ++;
+ assertFalse("The change of iv specified in the constructor "
+ + "should not cause the change of internal array.",
+ iv[0] == ps.getIV()[0]);
+ }
+
+ /**
+ * RC2ParameterSpec(int effectiveKeyBits, byte[] iv, int offset) method
+ * testing. Tests that IllegalArgumentException is thrown in the case of
+ * inappropriate constructor parameters and that input iv array is
+ * copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "RC2ParameterSpec",
+ args = {int.class, byte[].class, int.class}
+ )
+ public void testRC2ParameterSpec2() {
+ int effectiveKeyBits = 10;
+ byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
+ int offset = 2;
+
+ try {
+ new RC2ParameterSpec(effectiveKeyBits, null, offset);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC2ParameterSpec(effectiveKeyBits, iv, 4);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ RC2ParameterSpec ps = new RC2ParameterSpec(effectiveKeyBits, iv, offset);
+ iv[offset] ++;
+ assertFalse("The change of iv specified in the constructor "
+ + "should not cause the change of internal array.",
+ iv[offset] == ps.getIV()[0]);
+ }
+
+ /**
+ * getEffectiveKeyBits() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getEffectiveKeyBits",
+ args = {}
+ )
+ public void testGetEffectiveKeyBits() {
+ int effectiveKeyBits = 10;
+ byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ RC2ParameterSpec ps = new RC2ParameterSpec(effectiveKeyBits, iv);
+ assertTrue("The returned effectiveKeyBits value is not equal to the "
+ + "value specified in the constructor.",
+ effectiveKeyBits == ps.getEffectiveKeyBits());
+ }
+
+ /**
+ * getIV() method testing. Tests that returned array is equal to the
+ * array specified in the constructor. Checks that modification
+ * of returned array does not affect the internal array. Also it checks
+ * that getIV() method returns null if iv is not specified.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getIV",
+ args = {}
+ )
+ public void testGetIV() {
+ int effectiveKeyBits = 10;
+ byte[] iv = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+
+ RC2ParameterSpec ps = new RC2ParameterSpec(effectiveKeyBits, iv);
+ byte[] result = ps.getIV();
+ if (! Arrays.equals(iv, result)) {
+ fail("The returned iv is not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getIV() method iv "
+ + "should not cause the change of internal array.",
+ result[0] == ps.getIV()[0]);
+ ps = new RC2ParameterSpec(effectiveKeyBits);
+ assertNull("The getIV() method should return null if the parameter "
+ + "set does not contain iv.", ps.getIV());
+ }
+
+ /**
+ * equals(Object obj) method testing. Tests the correctness of equal
+ * operation: it should be reflexive, symmetric, transitive, consistent
+ * and should be false on null object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals() {
+ int effectiveKeyBits = 10;
+ byte[] iv = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+
+ RC2ParameterSpec ps1 = new RC2ParameterSpec(effectiveKeyBits, iv);
+ RC2ParameterSpec ps2 = new RC2ParameterSpec(effectiveKeyBits, iv);
+ RC2ParameterSpec ps3 = new RC2ParameterSpec(10,
+ new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9});
+
+ // checking for reflexive law:
+ assertTrue("The equivalence relation should be reflexive.",
+ ps1.equals(ps1));
+
+ assertTrue("Objects built on the same parameters should be equal.",
+ ps1.equals(ps2));
+ // checking for symmetric law:
+ assertTrue("The equivalence relation should be symmetric.",
+ ps2.equals(ps1));
+
+ assertTrue("Objects built on the equal parameters should be equal.",
+ ps2.equals(ps3));
+
+ // checking for transitive law:
+ assertTrue("The equivalence relation should be transitive.",
+ ps1.equals(ps3));
+
+ assertFalse("Should return not be equal to null object.",
+ ps1.equals(null));
+
+ ps2 = new RC2ParameterSpec(11, iv);
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+
+ ps2 = new RC2ParameterSpec(11, new byte[] {9, 8, 7, 6, 5, 4, 3, 2, 1});
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+ }
+
+ /**
+ * hashCode() method testing. Tests that for equal objects hash codes
+ * are equal.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "hashCode",
+ args = {}
+ )
+ public void testHashCode() {
+ int effectiveKeyBits = 0;
+ byte[] iv = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
+
+ RC2ParameterSpec ps1 = new RC2ParameterSpec(effectiveKeyBits, iv);
+ RC2ParameterSpec ps2 = new RC2ParameterSpec(effectiveKeyBits, iv);
+
+ assertTrue("Equal objects should have the same hash codes.",
+ ps1.hashCode() == ps2.hashCode());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "RC2ParameterSpec",
+ args = {int.class}
+ )
+ public void test_constructorI() {
+ int effectiveKeyBits = 0;
+
+ RC2ParameterSpec ps1 = new RC2ParameterSpec(effectiveKeyBits);
+ RC2ParameterSpec ps2 = new RC2ParameterSpec(effectiveKeyBits);
+
+ assertTrue(ps1.equals(ps2));
+ }
+
+ public static Test suite() {
+ return new TestSuite(RC2ParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java
new file mode 100644
index 0000000..6182615
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/RC5ParameterSpecTest.java
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Arrays;
+
+import javax.crypto.spec.RC5ParameterSpec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@TestTargetClass(RC5ParameterSpec.class)
+/**
+ */
+
+public class RC5ParameterSpecTest extends TestCase {
+
+ /**
+ * RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) method
+ * testing. Tests that IllegalArgumentException is thrown in the case of
+ * inappropriate constructor parameters and that input iv array is
+ * copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "RC5ParameterSpec",
+ args = {int.class, int.class, int.class, byte[].class}
+ )
+ public void testRC5ParameterSpec1() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ byte[] iv = {1, 2, 3, 4};
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize, null);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize+8, iv);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize, new byte[] {1, 2, 3});
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ iv[0] ++;
+ assertFalse("The change of iv specified in the constructor "
+ + "should not cause the change of internal array.",
+ iv[0] == ps.getIV()[0]);
+ }
+
+ /**
+ * RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv, int
+ * offset) method testing. Tests that IllegalArgumentException is thrown in
+ * the case of inappropriate constructor parameters and that input iv array
+ * is copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "RC5ParameterSpec",
+ args = {int.class, int.class, int.class, byte[].class, int.class}
+ )
+ public void testRC5ParameterSpec2() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ byte[] iv = {1, 2, 3, 4, 5, 6};
+ int offset = 2;
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize, null, offset);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize+8, iv, offset);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize, iv, offset+1);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new RC5ParameterSpec(version, rounds, wordSize, new byte[] { 1, 2,
+ 3, 4 }, offset);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short iv.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds, wordSize,
+ iv, offset);
+ iv[offset] ++;
+ assertFalse("The change of iv specified in the constructor "
+ + "should not cause the change of internal array.",
+ iv[offset] == ps.getIV()[0]);
+
+ // Regression test for HARMONY-1077
+ try {
+ new RC5ParameterSpec(0, 9, 77, new byte[] { 2 }, -100);
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * getVersion() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getVersion",
+ args = {}
+ )
+ public void testGetVersion() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds, wordSize);
+ assertTrue("The returned version value should be equal to the "
+ + "value specified in the constructor.",
+ ps.getVersion() == version);
+ }
+
+ /**
+ * getRounds() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getRounds",
+ args = {}
+ )
+ public void testGetRounds() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds, wordSize);
+ assertTrue("The returned rounds value should be equal to the "
+ + "value specified in the constructor.",
+ ps.getRounds() == rounds);
+ }
+
+ /**
+ * getWordSize() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getWordSize",
+ args = {}
+ )
+ public void testGetWordSize() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds, wordSize);
+ assertTrue("The returned wordSize value should be equal to the "
+ + "value specified in the constructor.",
+ ps.getWordSize() == wordSize);
+ }
+
+ /**
+ * getIV() method testing. Tests that returned array is equal to the
+ * array specified in the constructor. Checks that modification
+ * of returned array does not affect the internal array. Also it checks
+ * that getIV() method returns null if iv is not specified.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getIV",
+ args = {}
+ )
+ public void testGetIV() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ byte[] iv = {1, 2, 3, 4};
+
+ RC5ParameterSpec ps = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ byte[] result = ps.getIV();
+ if (! Arrays.equals(iv, result)) {
+ fail("The returned iv is not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getIV() method iv "
+ + "should not cause the change of internal array.",
+ result[0] == ps.getIV()[0]);
+ ps = new RC5ParameterSpec(version, rounds, wordSize);
+ assertNull("The getIV() method should return null if the parameter "
+ + "set does not contain IV.", ps.getIV());
+ }
+
+ /**
+ * equals(Object obj) method testing. Tests the correctness of equal
+ * operation: it should be reflexive, symmetric, transitive, consistent
+ * and should be false on null object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ byte[] iv = {1, 2, 3, 4, 5, 6};
+
+ RC5ParameterSpec ps1 = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ RC5ParameterSpec ps2 = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ RC5ParameterSpec ps3 = new RC5ParameterSpec(version, rounds, wordSize,
+ new byte[] {1, 2, 3, 4});
+ // checking for reflexive law:
+ assertTrue("The equivalence relation should be reflexive.",
+ ps1.equals(ps1));
+
+ assertTrue("Objects built on the same parameters should be equal.",
+ ps1.equals(ps2));
+ // checking for symmetric law:
+ assertTrue("The equivalence relation should be symmetric.",
+ ps2.equals(ps1));
+
+ assertTrue("Objects built on the equal parameters should be equal.",
+ ps2.equals(ps3));
+
+ // checking for transitive law:
+ assertTrue("The equivalence relation should be transitive.",
+ ps1.equals(ps3));
+
+ assertFalse("Should return not be equal to null object.",
+ ps1.equals(null));
+
+ ps2 = new RC5ParameterSpec(version+1, rounds, wordSize, iv);
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+
+ ps2 = new RC5ParameterSpec(version, rounds+1, wordSize, iv);
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+
+ ps2 = new RC5ParameterSpec(version, rounds, wordSize/2, iv);
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+
+ ps2 = new RC5ParameterSpec(version, rounds, wordSize,
+ new byte[] {4, 3, 2, 1});
+ assertFalse("Objects should not be equal.", ps1.equals(ps2));
+ }
+
+ /**
+ * hashCode() method testing. Tests that for equal objects hash codes
+ * are equal.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "hashCode",
+ args = {}
+ )
+ public void testHashCode() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ byte[] iv = {1, 2, 3, 4, 5, 6};
+
+ RC5ParameterSpec ps1 = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ RC5ParameterSpec ps2 = new RC5ParameterSpec(version, rounds,
+ wordSize, iv);
+ assertTrue("Equal objects should have the same hash codes.",
+ ps1.hashCode() == ps2.hashCode());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "RC5ParameterSpec",
+ args = {int.class, int.class, int.class}
+ )
+ public void test_constructorIII() {
+ int version = 1;
+ int rounds = 5;
+ int wordSize = 16;
+ RC5ParameterSpec ps1 = new RC5ParameterSpec(version, rounds, wordSize);
+ RC5ParameterSpec ps2 = new RC5ParameterSpec(version, rounds, wordSize);
+ RC5ParameterSpec ps3 = new RC5ParameterSpec(version, rounds, wordSize + 1);
+
+ assertTrue(ps1.equals(ps2));
+ assertFalse(ps1.equals(ps3));
+ }
+
+ public static Test suite() {
+ return new TestSuite(RC5ParameterSpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
new file mode 100644
index 0000000..5eeb76f
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/spec/SecretKeySpecTest.java
@@ -0,0 +1,323 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.javax.crypto.spec;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Arrays;
+
+import javax.crypto.spec.SecretKeySpec;
+
+@TestTargetClass(SecretKeySpec.class)
+/**
+ */
+
+public class SecretKeySpecTest extends TestCase {
+
+ /**
+ * SecretKeySpec(byte[] key, String algorithm) method testing. Tests that
+ * IllegalArgumentException is thrown in the case of inappropriate
+ * constructor parameters and that input iv array is
+ * copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SecretKeySpec",
+ args = {byte[].class, java.lang.String.class}
+ )
+ public void testSecretKeySpec1() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ try {
+ new SecretKeySpec(new byte[] {}, algorithm);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of empty key.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(null, algorithm);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null key.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(key, null);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null algorithm.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ SecretKeySpec ks = new SecretKeySpec(key, algorithm);
+ key[0] ++;
+ assertFalse("The change of key specified in the constructor "
+ + "should not cause the change of internal array.",
+ key[0] == ks.getEncoded()[0]);
+ }
+
+ /**
+ * SecretKeySpec(byte[] key, int offset, int len, String algorithm) method
+ * testing. Tests that IllegalArgumentException is thrown in
+ * the case of inappropriate constructor parameters and that input iv array
+ * is copied to protect against subsequent modification.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SecretKeySpec",
+ args = {byte[].class, int.class, int.class, java.lang.String.class}
+ )
+ public void testSecretKeySpec2() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ int offset = 1;
+ int len = 4;
+ String algorithm = "Algorithm";
+
+ try {
+ new SecretKeySpec(new byte[] {}, 0, 0, algorithm);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of empty key.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(null, 0, 0, algorithm);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null key.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(key, offset, len, null);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of short key algorithm.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(key, offset, key.length, algorithm);
+ fail("An IllegalArgumentException should be thrown "
+ + "in the case of null key.");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ new SecretKeySpec(key, 0, -1, algorithm);
+ fail("An ArrayIndexOutOfBoundsException should be thrown "
+ + "in the case of illegal length.");
+ } catch (IllegalArgumentException e) {
+ fail("Not expected IllegalArgumentException was thrown.");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+
+ SecretKeySpec ks = new SecretKeySpec(key, algorithm);
+ key[offset] ++;
+ assertFalse("The change of key specified in the constructor "
+ + "should not cause the change of internal array.",
+ key[offset] == ks.getEncoded()[0]);
+
+ // Regression test for HARMONY-1077
+ try {
+ new SecretKeySpec(new byte[] { 2 }, 4, -100, "CCC");
+ fail("ArrayIndexOutOfBoundsException expected");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //expected
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "SecretKeySpec",
+ args = {byte[].class, int.class, int.class, java.lang.String.class}
+ )
+ public void testSecretKeySpec3() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ int offset = 1;
+ int len = 4;
+ String algorithm = "Algorithm";
+
+ try {
+ new SecretKeySpec(key, -1, key.length, algorithm);
+ fail("An ArrayIndexOutOfBoundsException should be thrown "
+ + "in the case of illegal offset.");
+ } catch (IllegalArgumentException e) {
+ fail("Not expected IllegalArgumentException was thrown.");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ }
+
+ /**
+ * getAlgorithm() method testing. Tests that returned value is
+ * equal to the value specified in the constructor.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getAlgorithm",
+ args = {}
+ )
+ public void testGetAlgorithm() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ SecretKeySpec ks = new SecretKeySpec(key, algorithm);
+ assertEquals("The returned value does not equal to the "
+ + "value specified in the constructor.",
+ algorithm, ks.getAlgorithm());
+ }
+
+ /**
+ * getFormat() method testing. Tests that returned value is "RAW".
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getFormat",
+ args = {}
+ )
+ public void testGetFormat() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ SecretKeySpec ks = new SecretKeySpec(key, algorithm);
+ assertTrue("The returned value is not \"RAW\".",
+ ks.getFormat() == "RAW");
+ }
+
+ /**
+ * getEncoded() method testing. Tests that returned array is equal to the
+ * array specified in the constructor. Checks that modification
+ * of returned array does not affect the internal array.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getEncoded",
+ args = {}
+ )
+ public void testGetEncoded() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ SecretKeySpec ks = new SecretKeySpec(key, algorithm);
+ byte[] result = ks.getEncoded();
+ if (! Arrays.equals(key, result)) {
+ fail("The returned key does not equal to the specified "
+ + "in the constructor.");
+ }
+ result[0] ++;
+ assertFalse("The change of returned by getEncoded() method key "
+ + "should not cause the change of internal array.",
+ result[0] == ks.getEncoded()[0]);
+
+ // Regression for HARMONY-78
+ int offset = 1;
+ int len = 4;
+ SecretKeySpec sks = new SecretKeySpec(key, offset, len, algorithm);
+ assertEquals("Key length is incorrect", len, sks.getEncoded().length);
+ }
+
+ /**
+ * hashCode() method testing. Tests that for equal objects hash codes
+ * are equal.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "hashCode",
+ args = {}
+ )
+ public void testHashCode() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
+ SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
+ assertTrue("Equal objects should have the same hash codes.",
+ ks1.hashCode() == ks2.hashCode());
+ }
+
+ /**
+ * equals(Object obj) method testing. Tests the correctness of equal
+ * operation: it should be reflexive, symmetric, transitive, consistent
+ * and should be false on null object.
+ */
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "equals",
+ args = {java.lang.Object.class}
+ )
+ public void testEquals() {
+ byte[] key = new byte[] {1, 2, 3, 4, 5};
+ String algorithm = "Algorithm";
+
+ SecretKeySpec ks1 = new SecretKeySpec(key, algorithm);
+ SecretKeySpec ks2 = new SecretKeySpec(key, algorithm);
+ SecretKeySpec ks3 = new SecretKeySpec(key, algorithm);
+
+ // checking for reflexive law:
+ assertTrue("The equivalence relation should be reflexive.",
+ ks1.equals(ks1));
+
+ assertTrue("Objects built on the same parameters should be equal.",
+ ks1.equals(ks2));
+ // checking for symmetric law:
+ assertTrue("The equivalence relation should be symmetric.",
+ ks2.equals(ks1));
+
+ assertTrue("Objects built on the equal parameters should be equal.",
+ ks2.equals(ks3));
+ // checking for transitive law:
+ assertTrue("The equivalence relation should be transitive.",
+ ks1.equals(ks3));
+
+ assertFalse("Should not be equal to null object.",
+ ks1.equals(null));
+
+ ks2 = new SecretKeySpec(new byte[] {1}, algorithm);
+ assertFalse("Objects should not be equal.", ks1.equals(ks2));
+
+ ks2 = new SecretKeySpec(key, "Another Algorithm");
+ assertFalse("Objects should not be equal.", ks1.equals(ks2));
+ }
+
+ public static Test suite() {
+ return new TestSuite(SecretKeySpecTest.class);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ }
+}
+
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/EncryptedPrivateKeyInfoData.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/EncryptedPrivateKeyInfoData.java
new file mode 100644
index 0000000..7ca0e6a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/EncryptedPrivateKeyInfoData.java
@@ -0,0 +1,1229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+
+/**
+ *
+ * Support class for EncryptedPrivateKeyInfo_ImplTest and EncryptedPrivateKeyInfo_Test
+ *
+ * All binary data for these tests were generated using
+ * BEA JRockit j2sdk1.4.2_04 (http://www.bea.com) with
+ * security providers list extended by Bouncy Castle's one
+ * (http://www.bouncycastle.org)
+ */
+public class EncryptedPrivateKeyInfoData {
+
+
+ /**
+ * "valid" encoding for DSA with alg params
+ */
+ private static final byte[] dsaEncryptedPrivateKeyInfo = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x05, (byte) 0x33, (byte) 0x30,
+ (byte) 0x82, (byte) 0x01, (byte) 0x2b, (byte) 0x06, (byte) 0x07,
+ (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
+ (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01,
+ (byte) 0x1e, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00,
+ (byte) 0x9f, (byte) 0x5e, (byte) 0x76, (byte) 0x19, (byte) 0x59,
+ (byte) 0xd8, (byte) 0xf7, (byte) 0x6b, (byte) 0x91, (byte) 0x6d,
+ (byte) 0x15, (byte) 0x7e, (byte) 0x14, (byte) 0x27, (byte) 0x25,
+ (byte) 0x6e, (byte) 0x59, (byte) 0x2c, (byte) 0xec, (byte) 0x21,
+ (byte) 0x7a, (byte) 0xb7, (byte) 0xd4, (byte) 0xf4, (byte) 0xa0,
+ (byte) 0x26, (byte) 0x4e, (byte) 0x72, (byte) 0x29, (byte) 0x18,
+ (byte) 0x4a, (byte) 0x1c, (byte) 0x9a, (byte) 0xc9, (byte) 0xcd,
+ (byte) 0x85, (byte) 0x1b, (byte) 0x39, (byte) 0x41, (byte) 0x9e,
+ (byte) 0x58, (byte) 0x16, (byte) 0xeb, (byte) 0x20, (byte) 0x84,
+ (byte) 0x28, (byte) 0x2a, (byte) 0xb9, (byte) 0xce, (byte) 0xc7,
+ (byte) 0x6d, (byte) 0x74, (byte) 0x99, (byte) 0xfe, (byte) 0xa5,
+ (byte) 0xe8, (byte) 0x66, (byte) 0xe1, (byte) 0x48, (byte) 0xdd,
+ (byte) 0x2e, (byte) 0xcf, (byte) 0xfe, (byte) 0xb9, (byte) 0x6a,
+ (byte) 0x8e, (byte) 0x12, (byte) 0x4b, (byte) 0xa4, (byte) 0xa8,
+ (byte) 0x87, (byte) 0xd7, (byte) 0xab, (byte) 0x26, (byte) 0xd6,
+ (byte) 0xc3, (byte) 0xd1, (byte) 0x3b, (byte) 0x95, (byte) 0xc4,
+ (byte) 0x97, (byte) 0x2c, (byte) 0xdc, (byte) 0xab, (byte) 0x5d,
+ (byte) 0xf5, (byte) 0x55, (byte) 0xae, (byte) 0x58, (byte) 0x68,
+ (byte) 0x84, (byte) 0x41, (byte) 0x99, (byte) 0x1b, (byte) 0xd3,
+ (byte) 0xd0, (byte) 0xd9, (byte) 0xd3, (byte) 0xdd, (byte) 0xf5,
+ (byte) 0x48, (byte) 0x04, (byte) 0xa2, (byte) 0x92, (byte) 0x61,
+ (byte) 0xf8, (byte) 0xb1, (byte) 0xe6, (byte) 0x24, (byte) 0x65,
+ (byte) 0x8f, (byte) 0xa4, (byte) 0x97, (byte) 0x40, (byte) 0x1d,
+ (byte) 0x3f, (byte) 0x2b, (byte) 0x85, (byte) 0x00, (byte) 0xd5,
+ (byte) 0xcb, (byte) 0x8d, (byte) 0x66, (byte) 0x9a, (byte) 0xac,
+ (byte) 0x7b, (byte) 0x5f, (byte) 0xc7, (byte) 0x02, (byte) 0x15,
+ (byte) 0x00, (byte) 0x9a, (byte) 0xfb, (byte) 0x6f, (byte) 0x72,
+ (byte) 0x15, (byte) 0x01, (byte) 0x03, (byte) 0x16, (byte) 0x2a,
+ (byte) 0xd6, (byte) 0xca, (byte) 0x60, (byte) 0x10, (byte) 0x47,
+ (byte) 0xde, (byte) 0x4b, (byte) 0x0f, (byte) 0xd6, (byte) 0x73,
+ (byte) 0x37, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x5d,
+ (byte) 0x51, (byte) 0x28, (byte) 0x64, (byte) 0xb2, (byte) 0x2b,
+ (byte) 0xeb, (byte) 0x85, (byte) 0xb4, (byte) 0x14, (byte) 0x0d,
+ (byte) 0xad, (byte) 0xec, (byte) 0xc8, (byte) 0x1f, (byte) 0x96,
+ (byte) 0x1e, (byte) 0x6a, (byte) 0x52, (byte) 0xd4, (byte) 0x0b,
+ (byte) 0x69, (byte) 0xb0, (byte) 0x33, (byte) 0xa1, (byte) 0xd1,
+ (byte) 0xbc, (byte) 0x64, (byte) 0xd6, (byte) 0x64, (byte) 0xef,
+ (byte) 0x2c, (byte) 0x89, (byte) 0xc7, (byte) 0x39, (byte) 0x75,
+ (byte) 0x87, (byte) 0x82, (byte) 0x61, (byte) 0xbe, (byte) 0xd1,
+ (byte) 0xcd, (byte) 0x70, (byte) 0x41, (byte) 0x85, (byte) 0x99,
+ (byte) 0x55, (byte) 0x75, (byte) 0x6f, (byte) 0x16, (byte) 0xc0,
+ (byte) 0x40, (byte) 0xf1, (byte) 0x0c, (byte) 0x78, (byte) 0x1f,
+ (byte) 0xe8, (byte) 0x63, (byte) 0x5d, (byte) 0xfa, (byte) 0x37,
+ (byte) 0xc1, (byte) 0xce, (byte) 0x97, (byte) 0x76, (byte) 0xa5,
+ (byte) 0x48, (byte) 0x5b, (byte) 0x88, (byte) 0xe4, (byte) 0xd5,
+ (byte) 0xb8, (byte) 0x06, (byte) 0xf5, (byte) 0x7f, (byte) 0x92,
+ (byte) 0xda, (byte) 0x99, (byte) 0xa5, (byte) 0x5a, (byte) 0x64,
+ (byte) 0xc9, (byte) 0x30, (byte) 0x2c, (byte) 0x77, (byte) 0x58,
+ (byte) 0x60, (byte) 0xa6, (byte) 0x35, (byte) 0x1d, (byte) 0x71,
+ (byte) 0xfb, (byte) 0x49, (byte) 0x24, (byte) 0x6c, (byte) 0x34,
+ (byte) 0x29, (byte) 0xa0, (byte) 0x47, (byte) 0xf1, (byte) 0x14,
+ (byte) 0xad, (byte) 0xc2, (byte) 0x85, (byte) 0x41, (byte) 0xdd,
+ (byte) 0x2c, (byte) 0x78, (byte) 0x2a, (byte) 0x5a, (byte) 0x24,
+ (byte) 0x7f, (byte) 0x19, (byte) 0xf4, (byte) 0x0a, (byte) 0x2e,
+ (byte) 0x1d, (byte) 0x92, (byte) 0x80, (byte) 0xe5, (byte) 0xe4,
+ (byte) 0x05, (byte) 0x28, (byte) 0x48, (byte) 0x5c, // 38
+ (byte) 0x34, (byte) 0xc8, (byte) 0x22, (byte) 0x04, (byte) 0x82,
+ (byte) 0x04, (byte) 0x00, (byte) 0x00, //
+ (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14,
+ (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19,
+ (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e,
+ (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23,
+ (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28,
+ (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d,
+ (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32,
+ (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37,
+ (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c,
+ (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41,
+ (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46,
+ (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b,
+ (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50,
+ (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55,
+ (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a,
+ (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f,
+ (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+ (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69,
+ (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e,
+ (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73,
+ (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78,
+ (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d,
+ (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82,
+ (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
+ (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c,
+ (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91,
+ (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
+ (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b,
+ (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0,
+ (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5,
+ (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa,
+ (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf,
+ (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4,
+ (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9,
+ (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe,
+ (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3,
+ (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8,
+ (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd,
+ (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2,
+ (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7,
+ (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc,
+ (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1,
+ (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6,
+ (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb,
+ (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0,
+ (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5,
+ (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa,
+ (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
+ (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
+ (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18,
+ (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d,
+ (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22,
+ (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27,
+ (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c,
+ (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31,
+ (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36,
+ (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b,
+ (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40,
+ (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45,
+ (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a,
+ (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f,
+ (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54,
+ (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59,
+ (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e,
+ (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63,
+ (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68,
+ (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d,
+ (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72,
+ (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77,
+ (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c,
+ (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81,
+ (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86,
+ (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b,
+ (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90,
+ (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95,
+ (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a,
+ (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f,
+ (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4,
+ (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9,
+ (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae,
+ (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3,
+ (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8,
+ (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd,
+ (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2,
+ (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7,
+ (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc,
+ (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1,
+ (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6,
+ (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb,
+ (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0,
+ (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5,
+ (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea,
+ (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef,
+ (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4,
+ (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9,
+ (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe,
+ (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12,
+ (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17,
+ (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c,
+ (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21,
+ (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26,
+ (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b,
+ (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30,
+ (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35,
+ (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a,
+ (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f,
+ (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44,
+ (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
+ (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e,
+ (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53,
+ (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58,
+ (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d,
+ (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62,
+ (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67,
+ (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+ (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71,
+ (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76,
+ (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b,
+ (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80,
+ (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85,
+ (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a,
+ (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f,
+ (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94,
+ (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99,
+ (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e,
+ (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3,
+ (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8,
+ (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad,
+ (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2,
+ (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7,
+ (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc,
+ (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1,
+ (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6,
+ (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb,
+ (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0,
+ (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5,
+ (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda,
+ (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf,
+ (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4,
+ (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9,
+ (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee,
+ (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3,
+ (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8,
+ (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd,
+ (byte) 0xfe, (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11,
+ (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16,
+ (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b,
+ (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20,
+ (byte) 0x21, (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25,
+ (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a,
+ (byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f,
+ (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34,
+ (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39,
+ (byte) 0x3a, (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e,
+ (byte) 0x3f, (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43,
+ (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48,
+ (byte) 0x49, (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d,
+ (byte) 0x4e, (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52,
+ (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57,
+ (byte) 0x58, (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c,
+ (byte) 0x5d, (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61,
+ (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66,
+ (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b,
+ (byte) 0x6c, (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70,
+ (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75,
+ (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a,
+ (byte) 0x7b, (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f,
+ (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84,
+ (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89,
+ (byte) 0x8a, (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e,
+ (byte) 0x8f, (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93,
+ (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
+ (byte) 0x99, (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d,
+ (byte) 0x9e, (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2,
+ (byte) 0xa3, (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7,
+ (byte) 0xa8, (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac,
+ (byte) 0xad, (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1,
+ (byte) 0xb2, (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6,
+ (byte) 0xb7, (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb,
+ (byte) 0xbc, (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0,
+ (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5,
+ (byte) 0xc6, (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca,
+ (byte) 0xcb, (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf,
+ (byte) 0xd0, (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4,
+ (byte) 0xd5, (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9,
+ (byte) 0xda, (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde,
+ (byte) 0xdf, (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3,
+ (byte) 0xe4, (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8,
+ (byte) 0xe9, (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed,
+ (byte) 0xee, (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2,
+ (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7,
+ (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc,
+ (byte) 0xfd, (byte) 0xfe, (byte) 0xff };
+
+ /**
+ * "valid" encoding for DSA - no alg params
+ */
+ private static final byte[] dsaEncryptedPrivateKeyInfoNP = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x11, (byte) 0x30,
+ (byte) 0x0b, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04, (byte) 0x01,
+ (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, (byte) 0x04,
+ (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12,
+ (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17,
+ (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c,
+ (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21,
+ (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26,
+ (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b,
+ (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30,
+ (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35,
+ (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a,
+ (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f,
+ (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44,
+ (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
+ (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e,
+ (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53,
+ (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58,
+ (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d,
+ (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62,
+ (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67,
+ (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+ (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71,
+ (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76,
+ (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b,
+ (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80,
+ (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85,
+ (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a,
+ (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f,
+ (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94,
+ (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99,
+ (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e,
+ (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3,
+ (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8,
+ (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad,
+ (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2,
+ (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7,
+ (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc,
+ (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1,
+ (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6,
+ (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb,
+ (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0,
+ (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5,
+ (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda,
+ (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf,
+ (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4,
+ (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9,
+ (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee,
+ (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3,
+ (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8,
+ (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd,
+ (byte) 0xfe, (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11,
+ (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16,
+ (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b,
+ (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20,
+ (byte) 0x21, (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25,
+ (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a,
+ (byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f,
+ (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34,
+ (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39,
+ (byte) 0x3a, (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e,
+ (byte) 0x3f, (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43,
+ (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48,
+ (byte) 0x49, (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d,
+ (byte) 0x4e, (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52,
+ (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57,
+ (byte) 0x58, (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c,
+ (byte) 0x5d, (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61,
+ (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66,
+ (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b,
+ (byte) 0x6c, (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70,
+ (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75,
+ (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a,
+ (byte) 0x7b, (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f,
+ (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84,
+ (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89,
+ (byte) 0x8a, (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e,
+ (byte) 0x8f, (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93,
+ (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
+ (byte) 0x99, (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d,
+ (byte) 0x9e, (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2,
+ (byte) 0xa3, (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7,
+ (byte) 0xa8, (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac,
+ (byte) 0xad, (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1,
+ (byte) 0xb2, (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6,
+ (byte) 0xb7, (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb,
+ (byte) 0xbc, (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0,
+ (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5,
+ (byte) 0xc6, (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca,
+ (byte) 0xcb, (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf,
+ (byte) 0xd0, (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4,
+ (byte) 0xd5, (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9,
+ (byte) 0xda, (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde,
+ (byte) 0xdf, (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3,
+ (byte) 0xe4, (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8,
+ (byte) 0xe9, (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed,
+ (byte) 0xee, (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2,
+ (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7,
+ (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc,
+ (byte) 0xfd, (byte) 0xfe, (byte) 0xff, (byte) 0x00, (byte) 0x01,
+ (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
+ (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
+ (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10,
+ (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15,
+ (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a,
+ (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f,
+ (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, (byte) 0x24,
+ (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29,
+ (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e,
+ (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33,
+ (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38,
+ (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c, (byte) 0x3d,
+ (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41, (byte) 0x42,
+ (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47,
+ (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b, (byte) 0x4c,
+ (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50, (byte) 0x51,
+ (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56,
+ (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a, (byte) 0x5b,
+ (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f, (byte) 0x60,
+ (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65,
+ (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a,
+ (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e, (byte) 0x6f,
+ (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74,
+ (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79,
+ (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d, (byte) 0x7e,
+ (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83,
+ (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88,
+ (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c, (byte) 0x8d,
+ (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91, (byte) 0x92,
+ (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97,
+ (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b, (byte) 0x9c,
+ (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0, (byte) 0xa1,
+ (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5, (byte) 0xa6,
+ (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa, (byte) 0xab,
+ (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf, (byte) 0xb0,
+ (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4, (byte) 0xb5,
+ (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9, (byte) 0xba,
+ (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe, (byte) 0xbf,
+ (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4,
+ (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8, (byte) 0xc9,
+ (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd, (byte) 0xce,
+ (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2, (byte) 0xd3,
+ (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7, (byte) 0xd8,
+ (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc, (byte) 0xdd,
+ (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1, (byte) 0xe2,
+ (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6, (byte) 0xe7,
+ (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb, (byte) 0xec,
+ (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0, (byte) 0xf1,
+ (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6,
+ (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb,
+ (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff, (byte) 0x00,
+ (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14,
+ (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19,
+ (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e,
+ (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23,
+ (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28,
+ (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d,
+ (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32,
+ (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37,
+ (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c,
+ (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41,
+ (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46,
+ (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b,
+ (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50,
+ (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55,
+ (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a,
+ (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f,
+ (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+ (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69,
+ (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e,
+ (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73,
+ (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78,
+ (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d,
+ (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82,
+ (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
+ (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c,
+ (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91,
+ (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
+ (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b,
+ (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0,
+ (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5,
+ (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa,
+ (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf,
+ (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4,
+ (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9,
+ (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe,
+ (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3,
+ (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8,
+ (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd,
+ (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2,
+ (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7,
+ (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc,
+ (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1,
+ (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6,
+ (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb,
+ (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0,
+ (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5,
+ (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa,
+ (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff, };
+
+ /**
+ * "valid" encoding for DH with alg params
+ */
+ private static final byte[] dhEncryptedPrivateKeyInfo = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x05, (byte) 0x22, (byte) 0x30,
+ (byte) 0x82, (byte) 0x01, (byte) 0x1a, (byte) 0x06, (byte) 0x09,
+ (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+ (byte) 0x0d, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x30,
+ (byte) 0x82, (byte) 0x01, (byte) 0x0b, (byte) 0x02, (byte) 0x81,
+ (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x2c, (byte) 0x4f,
+ (byte) 0xea, (byte) 0xf2, (byte) 0x83, (byte) 0xc5, (byte) 0x38,
+ (byte) 0xc9, (byte) 0xb6, (byte) 0xd4, (byte) 0xf8, (byte) 0xb8,
+ (byte) 0x17, (byte) 0xa1, (byte) 0x7d, (byte) 0x4c, (byte) 0xec,
+ (byte) 0x6b, (byte) 0xd7, (byte) 0xc2, (byte) 0x1a, (byte) 0x35,
+ (byte) 0x85, (byte) 0x54, (byte) 0x14, (byte) 0x6c, (byte) 0x52,
+ (byte) 0x24, (byte) 0xbf, (byte) 0xe6, (byte) 0x32, (byte) 0xd8,
+ (byte) 0x42, (byte) 0xac, (byte) 0xb3, (byte) 0x28, (byte) 0x4f,
+ (byte) 0x77, (byte) 0xf6, (byte) 0xfc, (byte) 0xea, (byte) 0xea,
+ (byte) 0x72, (byte) 0xcf, (byte) 0x1d, (byte) 0x7b, (byte) 0xe1,
+ (byte) 0x72, (byte) 0xfa, (byte) 0x77, (byte) 0x12, (byte) 0xa9,
+ (byte) 0x42, (byte) 0xba, (byte) 0xc4, (byte) 0xf4, (byte) 0xfb,
+ (byte) 0xbd, (byte) 0x9f, (byte) 0x63, (byte) 0x9a, (byte) 0x58,
+ (byte) 0x6b, (byte) 0xb6, (byte) 0xa2, (byte) 0x6e, (byte) 0x3a,
+ (byte) 0x71, (byte) 0xf3, (byte) 0x43, (byte) 0x5e, (byte) 0x6f,
+ (byte) 0x8a, (byte) 0xd0, (byte) 0xac, (byte) 0xe5, (byte) 0x60,
+ (byte) 0x76, (byte) 0x57, (byte) 0x1f, (byte) 0x83, (byte) 0x4d,
+ (byte) 0xbc, (byte) 0xaa, (byte) 0xb1, (byte) 0x18, (byte) 0x40,
+ (byte) 0x19, (byte) 0xac, (byte) 0x31, (byte) 0xd4, (byte) 0xfc,
+ (byte) 0x39, (byte) 0x01, (byte) 0x46, (byte) 0xab, (byte) 0xab,
+ (byte) 0x53, (byte) 0x19, (byte) 0x2d, (byte) 0xf8, (byte) 0x4c,
+ (byte) 0xd3, (byte) 0x9f, (byte) 0x4d, (byte) 0xa6, (byte) 0x71,
+ (byte) 0x92, (byte) 0x06, (byte) 0xc7, (byte) 0x89, (byte) 0x70,
+ (byte) 0xc4, (byte) 0xc6, (byte) 0xa2, (byte) 0x1f, (byte) 0x05,
+ (byte) 0x4a, (byte) 0x5b, (byte) 0x84, (byte) 0xf9, (byte) 0xfb,
+ (byte) 0x98, (byte) 0x63, (byte) 0xc9, (byte) 0x9c, (byte) 0x13,
+ (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x36, (byte) 0x55,
+ (byte) 0x93, (byte) 0xb3, (byte) 0x22, (byte) 0x0c, (byte) 0xcd,
+ (byte) 0x7c, (byte) 0xc3, (byte) 0xe3, (byte) 0xa3, (byte) 0x8a,
+ (byte) 0xd7, (byte) 0xb4, (byte) 0xe9, (byte) 0xe0, (byte) 0xfa,
+ (byte) 0xa9, (byte) 0xa8, (byte) 0x69, (byte) 0xd6, (byte) 0xa6,
+ (byte) 0x20, (byte) 0xb8, (byte) 0xd4, (byte) 0xe7, (byte) 0x87,
+ (byte) 0x4e, (byte) 0xf3, (byte) 0x90, (byte) 0x10, (byte) 0xdd,
+ (byte) 0x75, (byte) 0x5d, (byte) 0xff, (byte) 0xee, (byte) 0xf0,
+ (byte) 0xef, (byte) 0x6a, (byte) 0x0a, (byte) 0xb0, (byte) 0xf1,
+ (byte) 0x8a, (byte) 0xb6, (byte) 0x7b, (byte) 0x39, (byte) 0x95,
+ (byte) 0xd5, (byte) 0x24, (byte) 0x83, (byte) 0x10, (byte) 0x95,
+ (byte) 0x34, (byte) 0x08, (byte) 0x77, (byte) 0x1d, (byte) 0xaf,
+ (byte) 0x69, (byte) 0xf0, (byte) 0xb5, (byte) 0xdb, (byte) 0x24,
+ (byte) 0x89, (byte) 0x72, (byte) 0xb2, (byte) 0x0d, (byte) 0x57,
+ (byte) 0x94, (byte) 0xb0, (byte) 0xe8, (byte) 0xc2, (byte) 0x37,
+ (byte) 0x45, (byte) 0x5a, (byte) 0xfc, (byte) 0xa1, (byte) 0xa0,
+ (byte) 0x41, (byte) 0xe4, (byte) 0x0c, (byte) 0xa3, (byte) 0x40,
+ (byte) 0x8b, (byte) 0x9c, (byte) 0x19, (byte) 0x63, (byte) 0x61,
+ (byte) 0xd9, (byte) 0x05, (byte) 0xbf, (byte) 0xc5, (byte) 0xe8,
+ (byte) 0xf7, (byte) 0xbd, (byte) 0x3a, (byte) 0xf5, (byte) 0x78,
+ (byte) 0xc2, (byte) 0x92, (byte) 0xe8, (byte) 0x60, (byte) 0x07,
+ (byte) 0x3e, (byte) 0x57, (byte) 0x12, (byte) 0xf6, (byte) 0x97,
+ (byte) 0x1f, (byte) 0xea, (byte) 0x02, (byte) 0xa3, (byte) 0x19,
+ (byte) 0xa7, (byte) 0x5a, (byte) 0x9b, (byte) 0xf6, (byte) 0xd2,
+ (byte) 0x0f, (byte) 0xe9, (byte) 0x6b, (byte) 0xeb, (byte) 0xd7,
+ (byte) 0x93, (byte) 0x9a, (byte) 0x7e, (byte) 0x4f, (byte) 0xd6,
+ (byte) 0x29, (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0xff,
+ (byte) 0x04, (byte) 0x82, (byte) 0x04, (byte) 0x00, (byte) 0x00,
+ (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14,
+ (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19,
+ (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e,
+ (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23,
+ (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28,
+ (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d,
+ (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32,
+ (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37,
+ (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c,
+ (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41,
+ (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46,
+ (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b,
+ (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50,
+ (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55,
+ (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a,
+ (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f,
+ (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+ (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69,
+ (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e,
+ (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73,
+ (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78,
+ (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d,
+ (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82,
+ (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
+ (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c,
+ (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91,
+ (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
+ (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b,
+ (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0,
+ (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5,
+ (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa,
+ (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf,
+ (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4,
+ (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9,
+ (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe,
+ (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3,
+ (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8,
+ (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd,
+ (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2,
+ (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7,
+ (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc,
+ (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1,
+ (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6,
+ (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb,
+ (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0,
+ (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5,
+ (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa,
+ (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
+ (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
+ (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18,
+ (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d,
+ (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22,
+ (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27,
+ (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c,
+ (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31,
+ (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36,
+ (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b,
+ (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40,
+ (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45,
+ (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a,
+ (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f,
+ (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54,
+ (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59,
+ (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e,
+ (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63,
+ (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68,
+ (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d,
+ (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72,
+ (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77,
+ (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c,
+ (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81,
+ (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86,
+ (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b,
+ (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90,
+ (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95,
+ (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a,
+ (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f,
+ (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4,
+ (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9,
+ (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae,
+ (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3,
+ (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8,
+ (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd,
+ (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2,
+ (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7,
+ (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc,
+ (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1,
+ (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6,
+ (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb,
+ (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0,
+ (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5,
+ (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea,
+ (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef,
+ (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4,
+ (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9,
+ (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe,
+ (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12,
+ (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17,
+ (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c,
+ (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21,
+ (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26,
+ (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b,
+ (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30,
+ (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35,
+ (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a,
+ (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f,
+ (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44,
+ (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
+ (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e,
+ (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53,
+ (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58,
+ (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d,
+ (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62,
+ (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67,
+ (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+ (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71,
+ (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76,
+ (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b,
+ (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80,
+ (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85,
+ (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a,
+ (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f,
+ (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94,
+ (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99,
+ (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e,
+ (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3,
+ (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8,
+ (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad,
+ (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2,
+ (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7,
+ (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc,
+ (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1,
+ (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6,
+ (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb,
+ (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0,
+ (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5,
+ (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda,
+ (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf,
+ (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4,
+ (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9,
+ (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee,
+ (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3,
+ (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8,
+ (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd,
+ (byte) 0xfe, (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02,
+ (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07,
+ (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c,
+ (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11,
+ (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16,
+ (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b,
+ (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20,
+ (byte) 0x21, (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25,
+ (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a,
+ (byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f,
+ (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34,
+ (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39,
+ (byte) 0x3a, (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e,
+ (byte) 0x3f, (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43,
+ (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48,
+ (byte) 0x49, (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d,
+ (byte) 0x4e, (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52,
+ (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57,
+ (byte) 0x58, (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c,
+ (byte) 0x5d, (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61,
+ (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66,
+ (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b,
+ (byte) 0x6c, (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70,
+ (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75,
+ (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a,
+ (byte) 0x7b, (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f,
+ (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84,
+ (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89,
+ (byte) 0x8a, (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e,
+ (byte) 0x8f, (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93,
+ (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98,
+ (byte) 0x99, (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d,
+ (byte) 0x9e, (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2,
+ (byte) 0xa3, (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7,
+ (byte) 0xa8, (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac,
+ (byte) 0xad, (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1,
+ (byte) 0xb2, (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6,
+ (byte) 0xb7, (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb,
+ (byte) 0xbc, (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0,
+ (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5,
+ (byte) 0xc6, (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca,
+ (byte) 0xcb, (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf,
+ (byte) 0xd0, (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4,
+ (byte) 0xd5, (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9,
+ (byte) 0xda, (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde,
+ (byte) 0xdf, (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3,
+ (byte) 0xe4, (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8,
+ (byte) 0xe9, (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed,
+ (byte) 0xee, (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2,
+ (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7,
+ (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc,
+ (byte) 0xfd, (byte) 0xfe, (byte) 0xff };
+
+ /**
+ * "valid" encoding for DH - no alg params
+ */
+ private static final byte[] dhEncryptedPrivateKeyInfoNP = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x13, (byte) 0x30,
+ (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x03, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04,
+ (byte) 0x82, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x01,
+ (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05, (byte) 0x06,
+ (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a, (byte) 0x0b,
+ (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f, (byte) 0x10,
+ (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15,
+ (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19, (byte) 0x1a,
+ (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e, (byte) 0x1f,
+ (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23, (byte) 0x24,
+ (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28, (byte) 0x29,
+ (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e,
+ (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x33,
+ (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37, (byte) 0x38,
+ (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c, (byte) 0x3d,
+ (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41, (byte) 0x42,
+ (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46, (byte) 0x47,
+ (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b, (byte) 0x4c,
+ (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50, (byte) 0x51,
+ (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55, (byte) 0x56,
+ (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a, (byte) 0x5b,
+ (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f, (byte) 0x60,
+ (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64, (byte) 0x65,
+ (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69, (byte) 0x6a,
+ (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e, (byte) 0x6f,
+ (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73, (byte) 0x74,
+ (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78, (byte) 0x79,
+ (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d, (byte) 0x7e,
+ (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82, (byte) 0x83,
+ (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88,
+ (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c, (byte) 0x8d,
+ (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91, (byte) 0x92,
+ (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97,
+ (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b, (byte) 0x9c,
+ (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0, (byte) 0xa1,
+ (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5, (byte) 0xa6,
+ (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa, (byte) 0xab,
+ (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf, (byte) 0xb0,
+ (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4, (byte) 0xb5,
+ (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9, (byte) 0xba,
+ (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe, (byte) 0xbf,
+ (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3, (byte) 0xc4,
+ (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8, (byte) 0xc9,
+ (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd, (byte) 0xce,
+ (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2, (byte) 0xd3,
+ (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7, (byte) 0xd8,
+ (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc, (byte) 0xdd,
+ (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1, (byte) 0xe2,
+ (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6, (byte) 0xe7,
+ (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb, (byte) 0xec,
+ (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0, (byte) 0xf1,
+ (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5, (byte) 0xf6,
+ (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa, (byte) 0xfb,
+ (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff, (byte) 0x00,
+ (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09, (byte) 0x0a,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e, (byte) 0x0f,
+ (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14,
+ (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18, (byte) 0x19,
+ (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d, (byte) 0x1e,
+ (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22, (byte) 0x23,
+ (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27, (byte) 0x28,
+ (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c, (byte) 0x2d,
+ (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32,
+ (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37,
+ (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b, (byte) 0x3c,
+ (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40, (byte) 0x41,
+ (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45, (byte) 0x46,
+ (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a, (byte) 0x4b,
+ (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f, (byte) 0x50,
+ (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54, (byte) 0x55,
+ (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59, (byte) 0x5a,
+ (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e, (byte) 0x5f,
+ (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63, (byte) 0x64,
+ (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68, (byte) 0x69,
+ (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d, (byte) 0x6e,
+ (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72, (byte) 0x73,
+ (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77, (byte) 0x78,
+ (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c, (byte) 0x7d,
+ (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81, (byte) 0x82,
+ (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86, (byte) 0x87,
+ (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b, (byte) 0x8c,
+ (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90, (byte) 0x91,
+ (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95, (byte) 0x96,
+ (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a, (byte) 0x9b,
+ (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f, (byte) 0xa0,
+ (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4, (byte) 0xa5,
+ (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9, (byte) 0xaa,
+ (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae, (byte) 0xaf,
+ (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3, (byte) 0xb4,
+ (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8, (byte) 0xb9,
+ (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd, (byte) 0xbe,
+ (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2, (byte) 0xc3,
+ (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7, (byte) 0xc8,
+ (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc, (byte) 0xcd,
+ (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1, (byte) 0xd2,
+ (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6, (byte) 0xd7,
+ (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb, (byte) 0xdc,
+ (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0, (byte) 0xe1,
+ (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5, (byte) 0xe6,
+ (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea, (byte) 0xeb,
+ (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef, (byte) 0xf0,
+ (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4, (byte) 0xf5,
+ (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9, (byte) 0xfa,
+ (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe, (byte) 0xff,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
+ (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08, (byte) 0x09,
+ (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d, (byte) 0x0e,
+ (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
+ (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17, (byte) 0x18,
+ (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c, (byte) 0x1d,
+ (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21, (byte) 0x22,
+ (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26, (byte) 0x27,
+ (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b, (byte) 0x2c,
+ (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30, (byte) 0x31,
+ (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36,
+ (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a, (byte) 0x3b,
+ (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f, (byte) 0x40,
+ (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44, (byte) 0x45,
+ (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49, (byte) 0x4a,
+ (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e, (byte) 0x4f,
+ (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53, (byte) 0x54,
+ (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58, (byte) 0x59,
+ (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d, (byte) 0x5e,
+ (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62, (byte) 0x63,
+ (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67, (byte) 0x68,
+ (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c, (byte) 0x6d,
+ (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71, (byte) 0x72,
+ (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76, (byte) 0x77,
+ (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b, (byte) 0x7c,
+ (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80, (byte) 0x81,
+ (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85, (byte) 0x86,
+ (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a, (byte) 0x8b,
+ (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f, (byte) 0x90,
+ (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94, (byte) 0x95,
+ (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99, (byte) 0x9a,
+ (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e, (byte) 0x9f,
+ (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3, (byte) 0xa4,
+ (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8, (byte) 0xa9,
+ (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad, (byte) 0xae,
+ (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2, (byte) 0xb3,
+ (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7, (byte) 0xb8,
+ (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc, (byte) 0xbd,
+ (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1, (byte) 0xc2,
+ (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6, (byte) 0xc7,
+ (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb, (byte) 0xcc,
+ (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0, (byte) 0xd1,
+ (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5, (byte) 0xd6,
+ (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda, (byte) 0xdb,
+ (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf, (byte) 0xe0,
+ (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4, (byte) 0xe5,
+ (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9, (byte) 0xea,
+ (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee, (byte) 0xef,
+ (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3, (byte) 0xf4,
+ (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8, (byte) 0xf9,
+ (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd, (byte) 0xfe,
+ (byte) 0xff, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03,
+ (byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08,
+ (byte) 0x09, (byte) 0x0a, (byte) 0x0b, (byte) 0x0c, (byte) 0x0d,
+ (byte) 0x0e, (byte) 0x0f, (byte) 0x10, (byte) 0x11, (byte) 0x12,
+ (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17,
+ (byte) 0x18, (byte) 0x19, (byte) 0x1a, (byte) 0x1b, (byte) 0x1c,
+ (byte) 0x1d, (byte) 0x1e, (byte) 0x1f, (byte) 0x20, (byte) 0x21,
+ (byte) 0x22, (byte) 0x23, (byte) 0x24, (byte) 0x25, (byte) 0x26,
+ (byte) 0x27, (byte) 0x28, (byte) 0x29, (byte) 0x2a, (byte) 0x2b,
+ (byte) 0x2c, (byte) 0x2d, (byte) 0x2e, (byte) 0x2f, (byte) 0x30,
+ (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35,
+ (byte) 0x36, (byte) 0x37, (byte) 0x38, (byte) 0x39, (byte) 0x3a,
+ (byte) 0x3b, (byte) 0x3c, (byte) 0x3d, (byte) 0x3e, (byte) 0x3f,
+ (byte) 0x40, (byte) 0x41, (byte) 0x42, (byte) 0x43, (byte) 0x44,
+ (byte) 0x45, (byte) 0x46, (byte) 0x47, (byte) 0x48, (byte) 0x49,
+ (byte) 0x4a, (byte) 0x4b, (byte) 0x4c, (byte) 0x4d, (byte) 0x4e,
+ (byte) 0x4f, (byte) 0x50, (byte) 0x51, (byte) 0x52, (byte) 0x53,
+ (byte) 0x54, (byte) 0x55, (byte) 0x56, (byte) 0x57, (byte) 0x58,
+ (byte) 0x59, (byte) 0x5a, (byte) 0x5b, (byte) 0x5c, (byte) 0x5d,
+ (byte) 0x5e, (byte) 0x5f, (byte) 0x60, (byte) 0x61, (byte) 0x62,
+ (byte) 0x63, (byte) 0x64, (byte) 0x65, (byte) 0x66, (byte) 0x67,
+ (byte) 0x68, (byte) 0x69, (byte) 0x6a, (byte) 0x6b, (byte) 0x6c,
+ (byte) 0x6d, (byte) 0x6e, (byte) 0x6f, (byte) 0x70, (byte) 0x71,
+ (byte) 0x72, (byte) 0x73, (byte) 0x74, (byte) 0x75, (byte) 0x76,
+ (byte) 0x77, (byte) 0x78, (byte) 0x79, (byte) 0x7a, (byte) 0x7b,
+ (byte) 0x7c, (byte) 0x7d, (byte) 0x7e, (byte) 0x7f, (byte) 0x80,
+ (byte) 0x81, (byte) 0x82, (byte) 0x83, (byte) 0x84, (byte) 0x85,
+ (byte) 0x86, (byte) 0x87, (byte) 0x88, (byte) 0x89, (byte) 0x8a,
+ (byte) 0x8b, (byte) 0x8c, (byte) 0x8d, (byte) 0x8e, (byte) 0x8f,
+ (byte) 0x90, (byte) 0x91, (byte) 0x92, (byte) 0x93, (byte) 0x94,
+ (byte) 0x95, (byte) 0x96, (byte) 0x97, (byte) 0x98, (byte) 0x99,
+ (byte) 0x9a, (byte) 0x9b, (byte) 0x9c, (byte) 0x9d, (byte) 0x9e,
+ (byte) 0x9f, (byte) 0xa0, (byte) 0xa1, (byte) 0xa2, (byte) 0xa3,
+ (byte) 0xa4, (byte) 0xa5, (byte) 0xa6, (byte) 0xa7, (byte) 0xa8,
+ (byte) 0xa9, (byte) 0xaa, (byte) 0xab, (byte) 0xac, (byte) 0xad,
+ (byte) 0xae, (byte) 0xaf, (byte) 0xb0, (byte) 0xb1, (byte) 0xb2,
+ (byte) 0xb3, (byte) 0xb4, (byte) 0xb5, (byte) 0xb6, (byte) 0xb7,
+ (byte) 0xb8, (byte) 0xb9, (byte) 0xba, (byte) 0xbb, (byte) 0xbc,
+ (byte) 0xbd, (byte) 0xbe, (byte) 0xbf, (byte) 0xc0, (byte) 0xc1,
+ (byte) 0xc2, (byte) 0xc3, (byte) 0xc4, (byte) 0xc5, (byte) 0xc6,
+ (byte) 0xc7, (byte) 0xc8, (byte) 0xc9, (byte) 0xca, (byte) 0xcb,
+ (byte) 0xcc, (byte) 0xcd, (byte) 0xce, (byte) 0xcf, (byte) 0xd0,
+ (byte) 0xd1, (byte) 0xd2, (byte) 0xd3, (byte) 0xd4, (byte) 0xd5,
+ (byte) 0xd6, (byte) 0xd7, (byte) 0xd8, (byte) 0xd9, (byte) 0xda,
+ (byte) 0xdb, (byte) 0xdc, (byte) 0xdd, (byte) 0xde, (byte) 0xdf,
+ (byte) 0xe0, (byte) 0xe1, (byte) 0xe2, (byte) 0xe3, (byte) 0xe4,
+ (byte) 0xe5, (byte) 0xe6, (byte) 0xe7, (byte) 0xe8, (byte) 0xe9,
+ (byte) 0xea, (byte) 0xeb, (byte) 0xec, (byte) 0xed, (byte) 0xee,
+ (byte) 0xef, (byte) 0xf0, (byte) 0xf1, (byte) 0xf2, (byte) 0xf3,
+ (byte) 0xf4, (byte) 0xf5, (byte) 0xf6, (byte) 0xf7, (byte) 0xf8,
+ (byte) 0xf9, (byte) 0xfa, (byte) 0xfb, (byte) 0xfc, (byte) 0xfd,
+ (byte) 0xfe, (byte) 0xff, };
+
+ /**
+ * Valid DSA parameters encoding
+ */
+ private static final byte[] dsaParamsEncoded = { (byte) 0x30, (byte) 0x82,
+ (byte) 0x01, (byte) 0x1e, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0x9f, (byte) 0x5e, (byte) 0x76, (byte) 0x19,
+ (byte) 0x59, (byte) 0xd8, (byte) 0xf7, (byte) 0x6b, (byte) 0x91,
+ (byte) 0x6d, (byte) 0x15, (byte) 0x7e, (byte) 0x14, (byte) 0x27,
+ (byte) 0x25, (byte) 0x6e, (byte) 0x59, (byte) 0x2c, (byte) 0xec,
+ (byte) 0x21, (byte) 0x7a, (byte) 0xb7, (byte) 0xd4, (byte) 0xf4,
+ (byte) 0xa0, (byte) 0x26, (byte) 0x4e, (byte) 0x72, (byte) 0x29,
+ (byte) 0x18, (byte) 0x4a, (byte) 0x1c, (byte) 0x9a, (byte) 0xc9,
+ (byte) 0xcd, (byte) 0x85, (byte) 0x1b, (byte) 0x39, (byte) 0x41,
+ (byte) 0x9e, (byte) 0x58, (byte) 0x16, (byte) 0xeb, (byte) 0x20,
+ (byte) 0x84, (byte) 0x28, (byte) 0x2a, (byte) 0xb9, (byte) 0xce,
+ (byte) 0xc7, (byte) 0x6d, (byte) 0x74, (byte) 0x99, (byte) 0xfe,
+ (byte) 0xa5, (byte) 0xe8, (byte) 0x66, (byte) 0xe1, (byte) 0x48,
+ (byte) 0xdd, (byte) 0x2e, (byte) 0xcf, (byte) 0xfe, (byte) 0xb9,
+ (byte) 0x6a, (byte) 0x8e, (byte) 0x12, (byte) 0x4b, (byte) 0xa4,
+ (byte) 0xa8, (byte) 0x87, (byte) 0xd7, (byte) 0xab, (byte) 0x26,
+ (byte) 0xd6, (byte) 0xc3, (byte) 0xd1, (byte) 0x3b, (byte) 0x95,
+ (byte) 0xc4, (byte) 0x97, (byte) 0x2c, (byte) 0xdc, (byte) 0xab,
+ (byte) 0x5d, (byte) 0xf5, (byte) 0x55, (byte) 0xae, (byte) 0x58,
+ (byte) 0x68, (byte) 0x84, (byte) 0x41, (byte) 0x99, (byte) 0x1b,
+ (byte) 0xd3, (byte) 0xd0, (byte) 0xd9, (byte) 0xd3, (byte) 0xdd,
+ (byte) 0xf5, (byte) 0x48, (byte) 0x04, (byte) 0xa2, (byte) 0x92,
+ (byte) 0x61, (byte) 0xf8, (byte) 0xb1, (byte) 0xe6, (byte) 0x24,
+ (byte) 0x65, (byte) 0x8f, (byte) 0xa4, (byte) 0x97, (byte) 0x40,
+ (byte) 0x1d, (byte) 0x3f, (byte) 0x2b, (byte) 0x85, (byte) 0x00,
+ (byte) 0xd5, (byte) 0xcb, (byte) 0x8d, (byte) 0x66, (byte) 0x9a,
+ (byte) 0xac, (byte) 0x7b, (byte) 0x5f, (byte) 0xc7, (byte) 0x02,
+ (byte) 0x15, (byte) 0x00, (byte) 0x9a, (byte) 0xfb, (byte) 0x6f,
+ (byte) 0x72, (byte) 0x15, (byte) 0x01, (byte) 0x03, (byte) 0x16,
+ (byte) 0x2a, (byte) 0xd6, (byte) 0xca, (byte) 0x60, (byte) 0x10,
+ (byte) 0x47, (byte) 0xde, (byte) 0x4b, (byte) 0x0f, (byte) 0xd6,
+ (byte) 0x73, (byte) 0x37, (byte) 0x02, (byte) 0x81, (byte) 0x80,
+ (byte) 0x5d, (byte) 0x51, (byte) 0x28, (byte) 0x64, (byte) 0xb2,
+ (byte) 0x2b, (byte) 0xeb, (byte) 0x85, (byte) 0xb4, (byte) 0x14,
+ (byte) 0x0d, (byte) 0xad, (byte) 0xec, (byte) 0xc8, (byte) 0x1f,
+ (byte) 0x96, (byte) 0x1e, (byte) 0x6a, (byte) 0x52, (byte) 0xd4,
+ (byte) 0x0b, (byte) 0x69, (byte) 0xb0, (byte) 0x33, (byte) 0xa1,
+ (byte) 0xd1, (byte) 0xbc, (byte) 0x64, (byte) 0xd6, (byte) 0x64,
+ (byte) 0xef, (byte) 0x2c, (byte) 0x89, (byte) 0xc7, (byte) 0x39,
+ (byte) 0x75, (byte) 0x87, (byte) 0x82, (byte) 0x61, (byte) 0xbe,
+ (byte) 0xd1, (byte) 0xcd, (byte) 0x70, (byte) 0x41, (byte) 0x85,
+ (byte) 0x99, (byte) 0x55, (byte) 0x75, (byte) 0x6f, (byte) 0x16,
+ (byte) 0xc0, (byte) 0x40, (byte) 0xf1, (byte) 0x0c, (byte) 0x78,
+ (byte) 0x1f, (byte) 0xe8, (byte) 0x63, (byte) 0x5d, (byte) 0xfa,
+ (byte) 0x37, (byte) 0xc1, (byte) 0xce, (byte) 0x97, (byte) 0x76,
+ (byte) 0xa5, (byte) 0x48, (byte) 0x5b, (byte) 0x88, (byte) 0xe4,
+ (byte) 0xd5, (byte) 0xb8, (byte) 0x06, (byte) 0xf5, (byte) 0x7f,
+ (byte) 0x92, (byte) 0xda, (byte) 0x99, (byte) 0xa5, (byte) 0x5a,
+ (byte) 0x64, (byte) 0xc9, (byte) 0x30, (byte) 0x2c, (byte) 0x77,
+ (byte) 0x58, (byte) 0x60, (byte) 0xa6, (byte) 0x35, (byte) 0x1d,
+ (byte) 0x71, (byte) 0xfb, (byte) 0x49, (byte) 0x24, (byte) 0x6c,
+ (byte) 0x34, (byte) 0x29, (byte) 0xa0, (byte) 0x47, (byte) 0xf1,
+ (byte) 0x14, (byte) 0xad, (byte) 0xc2, (byte) 0x85, (byte) 0x41,
+ (byte) 0xdd, (byte) 0x2c, (byte) 0x78, (byte) 0x2a, (byte) 0x5a,
+ (byte) 0x24, (byte) 0x7f, (byte) 0x19, (byte) 0xf4, (byte) 0x0a,
+ (byte) 0x2e, (byte) 0x1d, (byte) 0x92, (byte) 0x80, (byte) 0xe5,
+ (byte) 0xe4, (byte) 0x05, (byte) 0x28, (byte) 0x48, (byte) 0x5c,
+ (byte) 0x34, (byte) 0xc8, (byte) 0x22 };
+
+ /**
+ * Valid DH parameters encoding
+ */
+ private static final byte[] dhParamsEncoded = { (byte) 0x30, (byte) 0x82,
+ (byte) 0x01, (byte) 0x0b, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0xce, (byte) 0x2c, (byte) 0x4f, (byte) 0xea,
+ (byte) 0xf2, (byte) 0x83, (byte) 0xc5, (byte) 0x38, (byte) 0xc9,
+ (byte) 0xb6, (byte) 0xd4, (byte) 0xf8, (byte) 0xb8, (byte) 0x17,
+ (byte) 0xa1, (byte) 0x7d, (byte) 0x4c, (byte) 0xec, (byte) 0x6b,
+ (byte) 0xd7, (byte) 0xc2, (byte) 0x1a, (byte) 0x35, (byte) 0x85,
+ (byte) 0x54, (byte) 0x14, (byte) 0x6c, (byte) 0x52, (byte) 0x24,
+ (byte) 0xbf, (byte) 0xe6, (byte) 0x32, (byte) 0xd8, (byte) 0x42,
+ (byte) 0xac, (byte) 0xb3, (byte) 0x28, (byte) 0x4f, (byte) 0x77,
+ (byte) 0xf6, (byte) 0xfc, (byte) 0xea, (byte) 0xea, (byte) 0x72,
+ (byte) 0xcf, (byte) 0x1d, (byte) 0x7b, (byte) 0xe1, (byte) 0x72,
+ (byte) 0xfa, (byte) 0x77, (byte) 0x12, (byte) 0xa9, (byte) 0x42,
+ (byte) 0xba, (byte) 0xc4, (byte) 0xf4, (byte) 0xfb, (byte) 0xbd,
+ (byte) 0x9f, (byte) 0x63, (byte) 0x9a, (byte) 0x58, (byte) 0x6b,
+ (byte) 0xb6, (byte) 0xa2, (byte) 0x6e, (byte) 0x3a, (byte) 0x71,
+ (byte) 0xf3, (byte) 0x43, (byte) 0x5e, (byte) 0x6f, (byte) 0x8a,
+ (byte) 0xd0, (byte) 0xac, (byte) 0xe5, (byte) 0x60, (byte) 0x76,
+ (byte) 0x57, (byte) 0x1f, (byte) 0x83, (byte) 0x4d, (byte) 0xbc,
+ (byte) 0xaa, (byte) 0xb1, (byte) 0x18, (byte) 0x40, (byte) 0x19,
+ (byte) 0xac, (byte) 0x31, (byte) 0xd4, (byte) 0xfc, (byte) 0x39,
+ (byte) 0x01, (byte) 0x46, (byte) 0xab, (byte) 0xab, (byte) 0x53,
+ (byte) 0x19, (byte) 0x2d, (byte) 0xf8, (byte) 0x4c, (byte) 0xd3,
+ (byte) 0x9f, (byte) 0x4d, (byte) 0xa6, (byte) 0x71, (byte) 0x92,
+ (byte) 0x06, (byte) 0xc7, (byte) 0x89, (byte) 0x70, (byte) 0xc4,
+ (byte) 0xc6, (byte) 0xa2, (byte) 0x1f, (byte) 0x05, (byte) 0x4a,
+ (byte) 0x5b, (byte) 0x84, (byte) 0xf9, (byte) 0xfb, (byte) 0x98,
+ (byte) 0x63, (byte) 0xc9, (byte) 0x9c, (byte) 0x13, (byte) 0x02,
+ (byte) 0x81, (byte) 0x80, (byte) 0x36, (byte) 0x55, (byte) 0x93,
+ (byte) 0xb3, (byte) 0x22, (byte) 0x0c, (byte) 0xcd, (byte) 0x7c,
+ (byte) 0xc3, (byte) 0xe3, (byte) 0xa3, (byte) 0x8a, (byte) 0xd7,
+ (byte) 0xb4, (byte) 0xe9, (byte) 0xe0, (byte) 0xfa, (byte) 0xa9,
+ (byte) 0xa8, (byte) 0x69, (byte) 0xd6, (byte) 0xa6, (byte) 0x20,
+ (byte) 0xb8, (byte) 0xd4, (byte) 0xe7, (byte) 0x87, (byte) 0x4e,
+ (byte) 0xf3, (byte) 0x90, (byte) 0x10, (byte) 0xdd, (byte) 0x75,
+ (byte) 0x5d, (byte) 0xff, (byte) 0xee, (byte) 0xf0, (byte) 0xef,
+ (byte) 0x6a, (byte) 0x0a, (byte) 0xb0, (byte) 0xf1, (byte) 0x8a,
+ (byte) 0xb6, (byte) 0x7b, (byte) 0x39, (byte) 0x95, (byte) 0xd5,
+ (byte) 0x24, (byte) 0x83, (byte) 0x10, (byte) 0x95, (byte) 0x34,
+ (byte) 0x08, (byte) 0x77, (byte) 0x1d, (byte) 0xaf, (byte) 0x69,
+ (byte) 0xf0, (byte) 0xb5, (byte) 0xdb, (byte) 0x24, (byte) 0x89,
+ (byte) 0x72, (byte) 0xb2, (byte) 0x0d, (byte) 0x57, (byte) 0x94,
+ (byte) 0xb0, (byte) 0xe8, (byte) 0xc2, (byte) 0x37, (byte) 0x45,
+ (byte) 0x5a, (byte) 0xfc, (byte) 0xa1, (byte) 0xa0, (byte) 0x41,
+ (byte) 0xe4, (byte) 0x0c, (byte) 0xa3, (byte) 0x40, (byte) 0x8b,
+ (byte) 0x9c, (byte) 0x19, (byte) 0x63, (byte) 0x61, (byte) 0xd9,
+ (byte) 0x05, (byte) 0xbf, (byte) 0xc5, (byte) 0xe8, (byte) 0xf7,
+ (byte) 0xbd, (byte) 0x3a, (byte) 0xf5, (byte) 0x78, (byte) 0xc2,
+ (byte) 0x92, (byte) 0xe8, (byte) 0x60, (byte) 0x07, (byte) 0x3e,
+ (byte) 0x57, (byte) 0x12, (byte) 0xf6, (byte) 0x97, (byte) 0x1f,
+ (byte) 0xea, (byte) 0x02, (byte) 0xa3, (byte) 0x19, (byte) 0xa7,
+ (byte) 0x5a, (byte) 0x9b, (byte) 0xf6, (byte) 0xd2, (byte) 0x0f,
+ (byte) 0xe9, (byte) 0x6b, (byte) 0xeb, (byte) 0xd7, (byte) 0x93,
+ (byte) 0x9a, (byte) 0x7e, (byte) 0x4f, (byte) 0xd6, (byte) 0x29,
+ (byte) 0x02, (byte) 0x02, (byte) 0x03, (byte) 0xff };
+
+ /**
+ * pretends to be encrypted private key
+ */
+ public static final byte[] encryptedData;
+
+ private static final HashMap<String, byte[]> validEPKIEncodings = new HashMap<String, byte[]>();
+
+ private static final HashMap<String, byte[]> validEPKIEncodingsNP = new HashMap<String, byte[]>();
+
+ private static final HashMap<String, byte[]> validAPEncodings = new HashMap<String, byte[]>();
+
+ static {
+ validEPKIEncodings.put("DH", dhEncryptedPrivateKeyInfo);
+ validEPKIEncodings.put("DIFFIEHELLMAN", dhEncryptedPrivateKeyInfo);
+ validEPKIEncodings.put("DIFFIE-HELLMAN", dhEncryptedPrivateKeyInfo);
+ validEPKIEncodings.put("1.2.840.113549.1.3.1",
+ dhEncryptedPrivateKeyInfo);
+ validEPKIEncodingsNP.put("DH", dhEncryptedPrivateKeyInfoNP);
+ validEPKIEncodingsNP.put("DIFFIEHELLMAN", dhEncryptedPrivateKeyInfoNP);
+ validEPKIEncodingsNP.put("DIFFIE-HELLMAN", dhEncryptedPrivateKeyInfoNP);
+ validEPKIEncodings.put("DSA", dsaEncryptedPrivateKeyInfo);
+ validEPKIEncodings.put("1.2.840.10040.4.1", dsaEncryptedPrivateKeyInfo);
+ validEPKIEncodingsNP.put("DIFFIE-HELLMAN", dhEncryptedPrivateKeyInfoNP);
+ validEPKIEncodingsNP.put("DSA", dsaEncryptedPrivateKeyInfoNP);
+ validAPEncodings.put("DH", dhParamsEncoded);
+ validAPEncodings.put("DIFFIEHELLMAN", dhParamsEncoded);
+ validAPEncodings.put("DIFFIE-HELLMAN", dhParamsEncoded);
+ validAPEncodings.put("1.2.840.113549.1.3.1", dhParamsEncoded);
+ validAPEncodings.put("DSA", dsaParamsEncoded);
+ validAPEncodings.put("1.2.840.10040.4.1", dsaParamsEncoded);
+
+ encryptedData = new byte[1024];
+ for (int i = 0; i < encryptedData.length; i++) {
+ encryptedData[i] = (byte) i;
+ }
+ }
+
+ /**
+ * Algorithm_names/standard_names to be used in tests "DSA" and "DH" must be
+ * always presented
+ */
+ public final static String[][] algName0 = new String[][] {
+ { "DSA", "DSA" },
+ { "DH", "DiffieHellman", "Diffie-Hellman" },
+ { "1.2.840.10040.4.1", "DSA" },
+ { "1.2.840.113549.1.1.1", "RSA" },
+ { "1.2.840.113549.1.3.1", "DiffieHellman" },
+ { "1.2.840.113549.1.5.3", "pbeWithMD5AndDES-CBC" },
+ { "1.2.840.113549.1.12.1.3", "pbeWithSHAAnd3-KeyTripleDES-CBC" },
+ // {"1.2.840.113549.1.12.1.6", "pbeWithSHAAnd40BitRC2-CBC"},
+ { "1.2.840.113549.3.2", "RC2-CBC" },
+ { "1.2.840.113549.3.3", "RC2-EBC" },
+ { "1.2.840.113549.3.4", "RC4" },
+ { "1.2.840.113549.3.5", "RC4WithMAC" },
+ { "1.2.840.113549.3.6", "DESx-CBC" },
+ { "1.2.840.113549.3.7", "TripleDES-CBC" },
+ { "1.2.840.113549.3.8", "rc5CBC" },
+ { "1.2.840.113549.3.9", "RC5-CBC" },
+ { "1.2.840.113549.3.10", "DESCDMF" }, };
+
+ /**
+ * Returns valid encoding of EncryptedPrivateKeyInfo However encoded private
+ * key field (encryptedData) does not contain valid encrypted data.
+ *
+ * @throws NoSuchAlgorithmException
+ */
+ public static byte[] getValidEncryptedPrivateKeyInfoEncoding(
+ String algName, boolean includingAlgParameters)
+ throws NoSuchAlgorithmException {
+ String algNameUC = algName.toUpperCase();
+ byte[] ret = includingAlgParameters ? validEPKIEncodings
+ .get(algNameUC) : validEPKIEncodingsNP.get(algNameUC);
+ if (ret != null) {
+ return ret.clone();
+ }
+ throw new NoSuchAlgorithmException("No encoding available for "
+ + algName);
+ }
+
+ public static byte[] getValidEncryptedPrivateKeyInfoEncoding(String algName)
+ throws NoSuchAlgorithmException {
+ return getValidEncryptedPrivateKeyInfoEncoding(algName, true);
+ }
+
+ /**
+ * Returns valid encoding of EncryptedPrivateKeyInfo However encoded private
+ * key field (encryptedData) does not contain valid encrypted data.
+ *
+ * @throws NoSuchAlgorithmException
+ */
+ public static byte[] getParametersEncoding(String algName)
+ throws NoSuchAlgorithmException {
+ String algNameUC = algName.toUpperCase();
+ byte[] ret = validAPEncodings.get(algNameUC);
+ if (ret != null) {
+ return ret;
+ }
+ throw new NoSuchAlgorithmException("No AP encoding available for "
+ + algName);
+ }
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java
new file mode 100644
index 0000000..c9eb26e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyCipher.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+* @author Boris V. Kuznetsov
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.CipherSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+/**
+ *
+ * Cipher implementation for testing
+ */
+public class MyCipher extends CipherSpi {
+
+ public MyCipher() {
+ super();
+ }
+
+ @Override
+ protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+ }
+
+ @Override
+ protected void engineSetPadding(String padding)
+ throws NoSuchPaddingException {
+ if (!"PKCS5Padding".equals(padding)) {
+ throw new NoSuchPaddingException(padding);
+ }
+ }
+
+ @Override
+ protected int engineGetBlockSize() {
+ return 111;
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ return inputLen + 10;
+ }
+
+ @Override
+ protected byte[] engineGetIV() {
+ byte[] b = {1,2,3};
+ return b;
+ }
+
+ @Override
+ protected AlgorithmParameters engineGetParameters() {
+ return null;
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException {
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ }
+
+ @Override
+ protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ }
+
+ @Override
+ protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
+ return null;
+ }
+
+ @Override
+ protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException {
+ return 0;
+ }
+
+ @Override
+ protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
+ throws IllegalBlockSizeException, BadPaddingException {
+ return null;
+ }
+
+ @Override
+ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
+ byte[] output, int outputOffset) throws ShortBufferException,
+ IllegalBlockSizeException, BadPaddingException {
+ return 0;
+ }
+
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyExemptionMechanismSpi.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyExemptionMechanismSpi.java
new file mode 100644
index 0000000..ddd6f26
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyExemptionMechanismSpi.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.ExemptionMechanismException;
+import javax.crypto.ExemptionMechanismSpi;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Additional class for verification ExemptionMechanismSpi
+ * and ExemptionMechanism classes
+ *
+ */
+
+public class MyExemptionMechanismSpi extends ExemptionMechanismSpi {
+
+ private static final int byteArrayLength = 5;
+
+ public static final int getLength() {
+ return byteArrayLength;
+ }
+ @Override
+ protected byte[] engineGenExemptionBlob()
+ throws ExemptionMechanismException {
+ return new byte[byteArrayLength];
+ }
+
+ @Override
+ protected int engineGenExemptionBlob(byte[] output, int outputOffset)
+ throws ShortBufferException, ExemptionMechanismException {
+ return byteArrayLength;
+ }
+
+ @Override
+ protected int engineGetOutputSize(int inputLen) {
+ return 10;
+ }
+
+ @Override
+ protected void engineInit(Key key) throws InvalidKeyException,
+ ExemptionMechanismException {
+ if (key == null) {
+ throw new InvalidKeyException("key is null");
+ }
+ if (!(key instanceof tmpKey)) {
+ throw new ExemptionMechanismException("Incorrect key");
+ }
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameters params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException {
+ if (key == null) {
+ throw new InvalidKeyException("key is null");
+ }
+ if (!(key instanceof tmpKey)) {
+ throw new ExemptionMechanismException("Incorrect key");
+ }
+ if (params == null) {
+ throw new InvalidAlgorithmParameterException("params is null");
+ }
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException,
+ ExemptionMechanismException {
+ if (key == null) {
+ throw new InvalidKeyException("key is null");
+ }
+ if (!(key instanceof tmpKey)) {
+ throw new ExemptionMechanismException("Incorrect key");
+ }
+ if (params == null) {
+ throw new InvalidAlgorithmParameterException("params is null");
+ }
+ }
+
+ @SuppressWarnings("serial")
+ public class tmpKey implements Key {
+ private String alg;
+ private byte[] enc;
+ public tmpKey(String alg, byte[] enc) {
+ this.alg = alg;
+ this.enc = enc;
+ }
+ public String getFormat() {
+ return "tmpKey";
+ }
+ public String getAlgorithm() {
+ return alg;
+ }
+ public byte[] getEncoded() {
+ return enc;
+ }
+ }
+ @SuppressWarnings("serial")
+ public class tmp1Key implements Key {
+ private byte[] enc;
+ public tmp1Key(String alg, byte[] enc) {
+ this.enc = enc;
+ }
+ public String getAlgorithm() {
+ return "tmp1Key";
+ }
+ public String getFormat() {
+ return "tmp1Key";
+ }
+ public byte[] getEncoded() {
+ return enc;
+ }
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyAgreementSpi.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyAgreementSpi.java
new file mode 100644
index 0000000..51e541a
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyAgreementSpi.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Additional class for verification of KeyAgreementSpi
+ * and KeyAgreement functionality
+ *
+ */
+
+public class MyKeyAgreementSpi extends KeyAgreementSpi {
+
+ @Override
+ protected Key engineDoPhase(Key key, boolean lastPhase)
+ throws InvalidKeyException, IllegalStateException {
+ if (!lastPhase) {
+ throw new IllegalStateException("last Phase is false");
+ }
+ return null;
+ }
+
+ @Override
+ protected byte[] engineGenerateSecret() throws IllegalStateException {
+ return new byte[0];
+ }
+
+ @Override
+ protected int engineGenerateSecret(byte[] sharedSecret, int offset)
+ throws IllegalStateException, ShortBufferException {
+ return -1;
+ }
+
+ @Override
+ protected SecretKey engineGenerateSecret(String algorithm)
+ throws IllegalStateException, NoSuchAlgorithmException,
+ InvalidKeyException {
+ if (algorithm.length() == 0) {
+ throw new NoSuchAlgorithmException("Algorithm is empty");
+ }
+ return null;
+ }
+
+ @Override
+ protected void engineInit(Key key, SecureRandom random)
+ throws InvalidKeyException {
+ throw new IllegalArgumentException("Invalid parameter");
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params,
+ SecureRandom random) throws InvalidKeyException,
+ InvalidAlgorithmParameterException {
+ throw new IllegalArgumentException("Invalid parameter");
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyGeneratorSpi.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyGeneratorSpi.java
new file mode 100644
index 0000000..86b21c2
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyKeyGeneratorSpi.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.KeyGeneratorSpi;
+import javax.crypto.SecretKey;
+
+/**
+ * Additional class for verification of
+ * KeyGeneratorSpi and KeyGenerator functionality
+ *
+ */
+
+public class MyKeyGeneratorSpi extends KeyGeneratorSpi {
+
+ @Override
+ protected SecretKey engineGenerateKey() {
+ return null;
+ }
+
+ @Override
+ protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidAlgorithmParameterException {
+ if (params == null) {
+ throw new InvalidAlgorithmParameterException("params is null");
+ }
+ }
+
+ @Override
+ protected void engineInit(int keysize, SecureRandom random) {
+ if (keysize <= 77) {
+ throw new IllegalArgumentException("Invalid keysize");
+ }
+ }
+
+ @Override
+ protected void engineInit(SecureRandom random) {
+ throw new IllegalArgumentException("Invalid random");
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyMacSpi.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyMacSpi.java
new file mode 100644
index 0000000..8913c2e
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MyMacSpi.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.MacSpi;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Additional class for verification of MacGeneratorSpi and MacSpi
+ *
+ */
+
+public class MyMacSpi extends MacSpi {
+
+ private int length = 0;
+ @Override
+ protected int engineGetMacLength() {
+ return length;
+ }
+
+ @Override
+ protected void engineInit(Key key, AlgorithmParameterSpec params)
+ throws InvalidKeyException, InvalidAlgorithmParameterException {
+ if (params == null) {
+ if (!(key instanceof SecretKeySpec)) {
+ throw new IllegalArgumentException("params is null and key is SecretKeySpec");
+ }
+ }
+ }
+
+ @Override
+ protected void engineUpdate(byte input) {
+ }
+
+ @Override
+ protected void engineUpdate(byte[] input, int offset, int len) {
+ if (offset >= 0 && len >= 0) {
+ length = len;
+ }
+ }
+
+ @Override
+ protected byte[] engineDoFinal() {
+ return new byte[length];
+ }
+
+ @Override
+ protected void engineReset() {
+ length++;
+ }
+}
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MySecretKeyFactorySpi.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MySecretKeyFactorySpi.java
new file mode 100644
index 0000000..0dbff5d
--- /dev/null
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/support/MySecretKeyFactorySpi.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @author Vera Y. Petrashkova
+* @version $Revision$
+*/
+
+package org.apache.harmony.crypto.tests.support;
+
+import java.security.InvalidKeyException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactorySpi;
+
+/**
+ * Additional class for verification of SecretKeyFactorySpi
+ * and SecretKeyFactory functionality
+ *
+ */
+
+public class MySecretKeyFactorySpi extends SecretKeyFactorySpi {
+ @Override
+ protected SecretKey engineGenerateSecret(KeySpec keySpec)
+ throws InvalidKeySpecException {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec)
+ throws InvalidKeySpecException {
+ return null;
+ }
+
+ @Override
+ protected SecretKey engineTranslateKey(SecretKey key)
+ throws InvalidKeyException {
+ return null;
+ }
+}
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.0.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.0.ser
new file mode 100644
index 0000000..a7d6333
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.0.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.1.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.1.ser
new file mode 100644
index 0000000..447c1f4
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.1.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.2.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.2.ser
new file mode 100644
index 0000000..ae028bd
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/BadPaddingExceptionTest.golden.2.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.0.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.0.ser
new file mode 100644
index 0000000..60c67c0
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.0.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.1.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.1.ser
new file mode 100644
index 0000000..58b303f
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.1.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.2.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.2.ser
new file mode 100644
index 0000000..ee41ad6
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ExemptionMechanismExceptionTest.golden.2.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.0.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.0.ser
new file mode 100644
index 0000000..98823fc
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.0.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.1.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.1.ser
new file mode 100644
index 0000000..a69ae56
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.1.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.2.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.2.ser
new file mode 100644
index 0000000..f23826c
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/IllegalBlockSizeExceptionTest.golden.2.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.0.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.0.ser
new file mode 100644
index 0000000..0cdc09d
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.0.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.1.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.1.ser
new file mode 100644
index 0000000..3a12187
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.1.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.2.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.2.ser
new file mode 100644
index 0000000..5818cd4
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/NoSuchPaddingExceptionTest.golden.2.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.0.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.0.ser
new file mode 100644
index 0000000..1f8e55f
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.0.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.1.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.1.ser
new file mode 100644
index 0000000..b0fadb2
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.1.ser
Binary files differ
diff --git a/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.2.ser b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.2.ser
new file mode 100644
index 0000000..9edf260
--- /dev/null
+++ b/crypto/src/test/java/serialization/org/apache/harmony/crypto/tests/javax/crypto/serialization/ShortBufferExceptionTest.golden.2.ser
Binary files differ
diff --git a/crypto/src/test/java/tests/crypto/AllTests.java b/crypto/src/test/java/tests/crypto/AllTests.java
new file mode 100644
index 0000000..795d0a9
--- /dev/null
+++ b/crypto/src/test/java/tests/crypto/AllTests.java
@@ -0,0 +1,43 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.crypto;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that includes all tests for the regex project.
+ */
+public class AllTests {
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(AllTests.suite());
+//AllTests.java
+ }
+
+ public static Test suite() {
+ TestSuite suite = tests.TestSuiteFactory.createTestSuite("All crypto test suites");
+ // $JUnit-BEGIN$
+ suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.interfaces.AllTests.suite());
+ suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.serialization.AllTests.suite());
+ suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.spec.AllTests.suite());
+ suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.func.AllTests.suite());
+ suite.addTest(org.apache.harmony.crypto.tests.javax.crypto.AllTests.suite());
+ // $JUnit-END$
+ return suite;
+ }
+}
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test1.ciphertext b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.ciphertext
new file mode 100644
index 0000000..2d7b94b
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.ciphertext
@@ -0,0 +1 @@
+!#oN{@ \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test1.iv b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.iv
new file mode 100644
index 0000000..401f335
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.iv
@@ -0,0 +1 @@
+Q2#P\ \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test1.key b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.key
new file mode 100644
index 0000000..2ffb5ea
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.key
@@ -0,0 +1 @@
+igkXܴtyA#{ $ \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test1.plaintext b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.plaintext
new file mode 100644
index 0000000..9787ee2
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test1.plaintext
@@ -0,0 +1 @@
+ C \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test2.ciphertext b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.ciphertext
new file mode 100644
index 0000000..1ae3f96
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.ciphertext
Binary files differ
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test2.iv b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.iv
new file mode 100644
index 0000000..72660fc
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.iv
@@ -0,0 +1 @@
+@"З< \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test2.key b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.key
new file mode 100644
index 0000000..9876f3f
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.key
@@ -0,0 +1 @@
+q<(GΡԑI:' \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test2.plaintext b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.plaintext
new file mode 100644
index 0000000..1b5ef4a
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.plaintext
Binary files differ
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext
new file mode 100644
index 0000000..b9dd600
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext
Binary files differ
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test3.iv b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.iv
new file mode 100644
index 0000000..7a6ded5
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.iv
@@ -0,0 +1 @@
+~Sr[ \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test3.key b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.key
new file mode 100644
index 0000000..e18fd89
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.key
@@ -0,0 +1 @@
+/]oDεPe0?6 \ No newline at end of file
diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test3.plaintext b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.plaintext
new file mode 100644
index 0000000..f45bd88
--- /dev/null
+++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.plaintext
Binary files differ