diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
commit | adc854b798c1cfe3bfd4c27d68d5cee38ca617da (patch) | |
tree | 6aed8b4923ca428942cbaa7e848d50237a3d31e0 /crypto/src | |
parent | 1c0fed63c71ddb230f3b304aac12caffbedf2f21 (diff) | |
download | libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.zip libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.gz libcore-adc854b798c1cfe3bfd4c27d68d5cee38ca617da.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'crypto/src')
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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew 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 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 Binary files differnew file mode 100644 index 0000000..1ae3f96 --- /dev/null +++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.ciphertext 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 Binary files differnew file mode 100644 index 0000000..1b5ef4a --- /dev/null +++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test2.plaintext diff --git a/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext Binary files differnew file mode 100644 index 0000000..b9dd600 --- /dev/null +++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.ciphertext 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 Binary files differnew file mode 100644 index 0000000..f45bd88 --- /dev/null +++ b/crypto/src/test/resources/hyts_des-ede3-cbc.test3.plaintext |