diff options
6 files changed, 454 insertions, 704 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java index ade8841..c2c2172 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java @@ -56,9 +56,15 @@ public final class NativeCrypto { public static native void EVP_PKEY_free(int pkey); - // --- General context handling functions (despite the names) -------------- + // --- Message digest functions -------------- - public static native int EVP_MD_CTX_create(); + public static native int EVP_get_digestbyname(String name); + + public static native int EVP_MD_size(int evp_md); + + public static native int EVP_MD_block_size(int evp_md); + + // --- Message digest context functions -------------- public static native void EVP_MD_CTX_destroy(int ctx); @@ -66,19 +72,15 @@ public final class NativeCrypto { // --- Digest handling functions ------------------------------------------- - public static native void EVP_DigestInit(int ctx, String algorithm); + public static native int EVP_DigestInit(int evp_md); public static native void EVP_DigestUpdate(int ctx, byte[] buffer, int offset, int length); public static native int EVP_DigestFinal(int ctx, byte[] hash, int offset); - public static native int EVP_MD_CTX_size(int ctx); - - public static native int EVP_MD_CTX_block_size(int ctx); - // --- Signature handling functions ---------------------------------------- - public static native void EVP_VerifyInit(int ctx, String algorithm); + public static native int EVP_VerifyInit(String algorithm); public static native void EVP_VerifyUpdate(int ctx, byte[] buffer, int offset, int length); diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java index 3118a02..ba431bd 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLMessageDigestJDK.java @@ -30,9 +30,14 @@ public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable private int ctx; /** - * The OpenSSL version of the algorithm name for later use by reset. + * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1"); */ - private final String openssl; + private final int evp_md; + + /** + * Holds the output size of the message digest. + */ + private final int size; /** * Holds a dummy buffer for writing single bytes to the digest. @@ -42,39 +47,22 @@ public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable /** * Creates a new OpenSSLMessageDigest instance for the given algorithm * name. - * - * @param algorithm The standard name of the algorithm, e.g. "SHA-1". - * @param algorithm The name of the openssl algorithm, e.g. "sha1". */ - private OpenSSLMessageDigestJDK(String algorithm, String openssl) + private OpenSSLMessageDigestJDK(String algorithm, int evp_md, int size) throws NoSuchAlgorithmException { super(algorithm); - this.openssl = openssl; - - ctx = NativeCrypto.EVP_MD_CTX_create(); - try { - NativeCrypto.EVP_DigestInit(ctx, openssl); - } catch (Exception ex) { - throw new NoSuchAlgorithmException(ex.getMessage() + " (" + algorithm + ")"); - } - } - - @Override - protected byte[] engineDigest() { - byte[] result = new byte[NativeCrypto.EVP_MD_CTX_size(ctx)]; - NativeCrypto.EVP_DigestFinal(ctx, result, 0); - NativeCrypto.EVP_DigestInit(ctx, openssl); - return result; + this.evp_md = evp_md; + this.size = size; } @Override protected void engineReset() { - NativeCrypto.EVP_DigestInit(ctx, openssl); + free(); } @Override protected int engineGetDigestLength() { - return NativeCrypto.EVP_MD_CTX_size(ctx); + return size; } @Override @@ -85,51 +73,82 @@ public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable @Override protected void engineUpdate(byte[] input, int offset, int len) { - NativeCrypto.EVP_DigestUpdate(ctx, input, offset, len); + NativeCrypto.EVP_DigestUpdate(getCtx(), input, offset, len); + } + + @Override + protected byte[] engineDigest() { + byte[] result = new byte[size]; + NativeCrypto.EVP_DigestFinal(getCtx(), result, 0); + ctx = 0; // EVP_DigestFinal frees the context as a side effect + return result; } public Object clone() throws CloneNotSupportedException { OpenSSLMessageDigestJDK d = (OpenSSLMessageDigestJDK) super.clone(); - d.ctx = NativeCrypto.EVP_MD_CTX_copy(ctx); + d.ctx = NativeCrypto.EVP_MD_CTX_copy(getCtx()); return d; } - @Override protected void finalize() throws Throwable { - try { + private int getCtx() { + if (ctx == 0) { + ctx = NativeCrypto.EVP_DigestInit(evp_md); + } + return ctx; + } + + private void free() { + if (ctx != 0) { NativeCrypto.EVP_MD_CTX_destroy(ctx); ctx = 0; + } + } + + @Override protected void finalize() throws Throwable { + try { + free(); } finally { super.finalize(); } } public static class MD5 extends OpenSSLMessageDigestJDK { + private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("md5"); + private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); public MD5() throws NoSuchAlgorithmException { - super("MD5", "md5"); + super("MD5",EVP_MD, SIZE); } } public static class SHA1 extends OpenSSLMessageDigestJDK { + private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1"); + private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); public SHA1() throws NoSuchAlgorithmException { - super("SHA-1", "sha1"); + super("SHA-1", EVP_MD, SIZE); } } public static class SHA256 extends OpenSSLMessageDigestJDK { + private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256"); + private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); public SHA256() throws NoSuchAlgorithmException { - super("SHA-256", "sha256"); + super("SHA-256", EVP_MD, SIZE); } } public static class SHA384 extends OpenSSLMessageDigestJDK { + private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384"); + private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); public SHA384() throws NoSuchAlgorithmException { - super("SHA-384", "sha384"); + super("SHA-384", EVP_MD, SIZE); } } public static class SHA512 extends OpenSSLMessageDigestJDK { + private static final int EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512"); + private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD); public SHA512() throws NoSuchAlgorithmException { - super("SHA-512", "sha512"); + super("SHA-512", EVP_MD, SIZE); } } } diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java index 8a460a4..451d395 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java @@ -80,7 +80,7 @@ public class OpenSSLSignature extends Signature { /** * Holds a pointer to the native message digest context. */ - private final int ctx; + private int ctx; /** * Holds a pointer to the native DSA key. @@ -141,7 +141,6 @@ public class OpenSSLSignature extends Signature { } this.evpAlgorithm = algorithm; - this.ctx = NativeCrypto.EVP_MD_CTX_create(); } @Override @@ -199,7 +198,7 @@ public class OpenSSLSignature extends Signature { } try { - NativeCrypto.EVP_VerifyInit(ctx, evpAlgorithm); + ctx = NativeCrypto.EVP_VerifyInit(evpAlgorithm); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/luni/src/main/native/NativeCrypto.cpp b/luni/src/main/native/NativeCrypto.cpp index 0f9ae1d..3388acc 100644 --- a/luni/src/main/native/NativeCrypto.cpp +++ b/luni/src/main/native/NativeCrypto.cpp @@ -97,6 +97,13 @@ struct EC_KEY_Delete { }; typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY; +struct EVP_MD_CTX_Delete { + void operator()(EVP_MD_CTX* p) const { + EVP_MD_CTX_destroy(p); + } +}; +typedef UniquePtr<EVP_MD_CTX, EVP_MD_CTX_Delete> Unique_EVP_MD_CTX; + struct EVP_PKEY_Delete { void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); @@ -184,18 +191,18 @@ static void freeSslErrorState(void) { * Checks this thread's OpenSSL error queue and throws a RuntimeException if * necessary. * - * @return 1 if an exception was thrown, 0 if not. + * @return true if an exception was thrown, false if not. */ -static int throwExceptionIfNecessary(JNIEnv* env, const char* location __attribute__ ((unused))) { +static bool throwExceptionIfNecessary(JNIEnv* env, const char* location __attribute__ ((unused))) { int error = ERR_get_error(); - int result = 0; + int result = false; if (error != 0) { char message[256]; ERR_error_string_n(error, message, sizeof(message)); JNI_TRACE("OpenSSL error in %s %d: %s", location, error, message); jniThrowRuntimeException(env, message); - result = 1; + result = true; } freeSslErrorState(); @@ -597,21 +604,6 @@ static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, EVP_PKEY* pkey) { } /* - * public static native int EVP_MD_CTX_create() - */ -static jint NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) { - JNI_TRACE("NativeCrypto_EVP_MD_CTX_create"); - - EVP_MD_CTX* ctx = EVP_MD_CTX_create(); - if (ctx == NULL) { - jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX"); - } - JNI_TRACE("NativeCrypto_EVP_MD_CTX_create => %p", ctx); - return (jint) ctx; - -} - -/* * public static native void EVP_MD_CTX_destroy(int) */ static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, EVP_MD_CTX* ctx) { @@ -660,86 +652,107 @@ static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx, return -1; } - int result = -1; - ScopedByteArrayRW hashBytes(env, hash); if (hashBytes.get() == NULL) { return -1; } - EVP_DigestFinal(ctx, - reinterpret_cast<unsigned char*>(hashBytes.get() + offset), - reinterpret_cast<unsigned int*>(&result)); + unsigned int bytesWritten = -1; + int ok = EVP_DigestFinal(ctx, + reinterpret_cast<unsigned char*>(hashBytes.get() + offset), + &bytesWritten); + if (ok == 0) { + throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal"); + } + EVP_MD_CTX_destroy(ctx); - throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal"); + JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, bytesWritten); + return bytesWritten; +} - JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, result); - return result; +/* + * public static native int EVP_DigestInit(int) + */ +static int NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, EVP_MD* evp_md) { + JNI_TRACE("NativeCrypto_EVP_DigestInit(%d)", evp_md); + + if (evp_md == NULL) { + jniThrowNullPointerException(env, NULL); + return NULL; + } + + Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create()); + if (ctx.get() == NULL) { + jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX"); + return NULL; + } + JNI_TRACE("NativeCrypto_EVP_DigestInit ctx=%p", ctx.get()); + + int ok = EVP_DigestInit(ctx.get(), evp_md); + if (ok == 0) { + bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit"); + if (exception) { + return NULL; + } + } + return (jint) ctx.release(); } /* - * public static native void EVP_DigestInit(int, java.lang.String) + * public static native int EVP_get_digestbyname(java.lang.String) */ -static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) { - JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %p)", ctx, algorithm); +static jint NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) { + JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm); - if (ctx == NULL || algorithm == NULL) { + if (algorithm == NULL) { jniThrowNullPointerException(env, NULL); - return; + return -1; } ScopedUtfChars algorithmChars(env, algorithm); if (algorithmChars.c_str() == NULL) { - return; + return NULL; } + JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s)", algorithmChars.c_str()); - JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %s)", ctx, algorithmChars.c_str()); - const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str())); - - if (digest == NULL) { + const EVP_MD* evp_md = EVP_get_digestbyname(algorithmChars.c_str()); + if (evp_md == NULL) { jniThrowRuntimeException(env, "Hash algorithm not found"); - return; + return NULL; } - EVP_DigestInit(ctx, digest); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit"); + JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %d", algorithmChars.c_str(), result); + return (jint) evp_md; } /* - * public static native int EVP_MD_CTX_size(int) + * public static native int EVP_MD_size(int) */ -static jint NativeCrypto_EVP_MD_CTX_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) { - JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p)", ctx); +static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, EVP_MD* evp_md) { + JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md); - if (ctx == NULL) { + if (evp_md == NULL) { jniThrowNullPointerException(env, NULL); return -1; } - int result = EVP_MD_CTX_size(ctx); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_size"); - - JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p) => %d", ctx, result); + int result = EVP_MD_size(evp_md); + JNI_TRACE("NativeCrypto_EVP_MD_size(%p) => %d", ctx, result); return result; } /* - * public static int void EVP_MD_CTX_block_size(int) + * public static int void EVP_MD_block_size(int) */ -static jint NativeCrypto_EVP_MD_CTX_block_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) { - JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p)", ctx); +static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, EVP_MD* evp_md) { + JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md); - if (ctx == NULL) { + if (evp_md == NULL) { jniThrowNullPointerException(env, NULL); return -1; } - int result = EVP_MD_CTX_block_size(ctx); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_block_size"); - - JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p) => %d", ctx, result); + int result = EVP_MD_block_size(evp_md); + JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p) => %d", evp_md, result); return result; } @@ -764,40 +777,52 @@ static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx, if (bufferBytes.get() == NULL) { return; } - EVP_DigestUpdate(ctx, - reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), - length); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate"); + int ok = EVP_DigestUpdate(ctx, + reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), + length); + if (ok == 0) { + throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate"); + } } /* - * public static native void EVP_VerifyInit(int, java.lang.String) + * public static native int EVP_VerifyInit(java.lang.String) */ -static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) { - JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %p)", ctx, algorithm); +static jint NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) { + JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p)", algorithm); - if (ctx == NULL || algorithm == NULL) { + if (algorithm == NULL) { jniThrowNullPointerException(env, NULL); - return; + return NULL; } + Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create()); + if (ctx.get() == NULL) { + jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX"); + return NULL; + } + JNI_TRACE("NativeCrypto_EVP_VerifyInit ctx=%p", ctx.get()); + ScopedUtfChars algorithmChars(env, algorithm); if (algorithmChars.c_str() == NULL) { - return; + return NULL; } + JNI_TRACE("NativeCrypto_EVP_VerifyInit algorithmChars=%s", algorithmChars.c_str()); - JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %s)", ctx, algorithmChars.c_str()); const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str())); - if (digest == NULL) { jniThrowRuntimeException(env, "Hash algorithm not found"); - return; + return NULL; } - EVP_VerifyInit(ctx, digest); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit"); + int ok = EVP_VerifyInit(ctx.get(), digest); + if (ok == 0) { + bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit"); + if (exception) { + return NULL; + } + } + return (jint) ctx.release(); } /* @@ -816,11 +841,12 @@ static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx, if (bufferBytes.get() == NULL) { return; } - EVP_VerifyUpdate(ctx, - reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), - length); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate"); + int ok = EVP_VerifyUpdate(ctx, + reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), + length); + if (ok == 0) { + throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate"); + } } /* @@ -840,17 +866,17 @@ static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jb if (bufferBytes.get() == NULL) { return -1; } - int result = EVP_VerifyFinal(ctx, - reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), - length, - pkey); - - throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal"); - + int ok = EVP_VerifyFinal(ctx, + reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset), + length, + pkey); + if (ok == 0) { + throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal"); + } JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d", - ctx, buffer, offset, length, pkey, result); + ctx, buffer, offset, length, pkey, ok); - return result; + return ok; } /** @@ -962,20 +988,20 @@ static int NativeCrypto_verifySignature(JNIEnv* env, jclass, JNI_TRACE("NativeCrypto_verifySignature algorithmChars=%s", algorithmChars.c_str()); Unique_RSA rsa(rsaCreateKey(modBytes.get(), modBytes.size(), expBytes.get(), expBytes.size())); - int result = -1; + int ok = -1; if (rsa.get() != NULL) { - result = rsaVerify(msgBytes.get(), msgBytes.size(), sigBytes.get(), sigBytes.size(), + ok = rsaVerify(msgBytes.get(), msgBytes.size(), sigBytes.get(), sigBytes.size(), algorithmChars.c_str(), rsa.get()); } - if (result == -1) { + if (ok == -1 || ok == 0) { if (!throwExceptionIfNecessary(env, "NativeCrypto_verifySignature")) { jniThrowRuntimeException(env, "Internal error during verification"); } } JNI_TRACE("NativeCrypto_verifySignature => %d", result); - return result; + return ok == 1; } static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) { @@ -3308,15 +3334,15 @@ static JNINativeMethod sNativeCryptoMethods[] = { NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"), NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B)I"), NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"), - NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()I"), NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"), NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"), NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"), - NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(ILjava/lang/String;)V"), - NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_block_size, "(I)I"), - NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_size, "(I)I"), + NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(I)I"), + NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)I"), + NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(I)I"), + NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(I)I"), NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"), - NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(ILjava/lang/String;)V"), + NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)I"), NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"), NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"), NATIVE_METHOD(NativeCrypto, verifySignature, "([B[BLjava/lang/String;[B[B)I"), diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java index 8e237a4..d594780 100644 --- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java +++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/MessageDigest2Test.java @@ -17,33 +17,26 @@ package org.apache.harmony.security.tests.java.security; -import dalvik.annotation.TestTargetClass; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; - import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Enumeration; -import java.util.Vector; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; -@TestTargetClass(MessageDigest.class) public class MessageDigest2Test extends junit.framework.TestCase { private static final String MESSAGEDIGEST_ID = "MessageDigest."; - private String[] digestAlgs = null; - - private String providerName = null; + private Map<Provider, List<String>> digestAlgs = new HashMap<Provider, List<String>>(); private static final byte[] AR1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; @@ -67,37 +60,26 @@ public class MessageDigest2Test extends junit.framework.TestCase { 8, -41, 3, 25, -66, 38, 16, -24, -91, 125, -102, 91, -107, -99, 59, }; /** - * @tests java.security.MessageDigest#MessageDigest(java.lang.String) + * java.security.MessageDigest#MessageDigest(java.lang.String) */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "MessageDigest", - args = {java.lang.String.class} - ) public void test_constructor() { - for (int i = 0; i < digestAlgs.length; i++) { - MessageDigestStub md = new MessageDigestStub(digestAlgs[i]); - assertEquals(digestAlgs[i], md.getAlgorithm()); - assertEquals(0, md.getDigestLength()); - assertNull(md.getProvider()); + for (List<String> algorithms : digestAlgs.values()) { + for (String algorithm : algorithms) { + MessageDigestStub md = new MessageDigestStub(algorithm); + assertEquals(algorithm, md.getAlgorithm()); + assertEquals(0, md.getDigestLength()); + assertNull(md.getProvider()); + } } } /** - * @tests java.security.MessageDigest#clone() + * java.security.MessageDigest#clone() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "clone", - args = {} - ) - public void test_clone() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - MessageDigest d1 = MessageDigest.getInstance(digestAlgs[i], - providerName); + public void test_clone() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest d1 = MessageDigest.getInstance(algorithm, e.getKey().getName()); for (byte b = 0; b < 84; b++) { d1.update(b); } @@ -106,15 +88,8 @@ public class MessageDigest2Test extends junit.framework.TestCase { d1.update((byte) 1); d2.update((byte) 1); - assertTrue("cloned hash differs from original for algorithm " - + digestAlgs[i], MessageDigest.isEqual(d1.digest(), d2 - .digest())); - } catch (CloneNotSupportedException e) { - // Expected - a Signature may not be cloneable - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); + assertTrue("cloned hash differs from original for algorithm " + algorithm, + MessageDigest.isEqual(d1.digest(), d2.digest())); } } } @@ -122,138 +97,112 @@ public class MessageDigest2Test extends junit.framework.TestCase { private static final byte[] SHA_DATA_2 = { 70, -54, 124, 120, -29, 57, 56, 119, -108, -54, -97, -76, -97, -50, -63, -73, 2, 85, -53, -79, }; - private void testSerializationSHA_DATA_2(MessageDigest sha) { - try { - sha.reset(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DataOutputStream output = new DataOutputStream(out); - // ----------------------------------------------------------------------- - - // Made up data - output - .writeUTF("tests.api.java.security.MessageDigestTest$InitializerFieldsTest3"); - output.writeInt(0); // class modifiers - output.writeUTF("java.io.Serializable"); // interfaces - - // Fields - output.writeUTF("sub_toBeNotSerialized"); // name - output.writeInt(9); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - output.writeUTF("sub_toBeNotSerialized2"); // name - output.writeInt(9); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - output.writeUTF("sub_toBeSerialized"); // name - output.writeInt(1); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - output.writeUTF("sub_toBeSerialized3"); // name - output.writeInt(1); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - output.writeUTF("sub_toBeSerialized4"); // name - output.writeInt(1); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - output.writeUTF("sub_toBeSerialized5"); // name - output.writeInt(1); // modifiers - output.writeUTF("Ljava/lang/String;"); // signature - - // clinit - output.writeUTF("<clinit>"); // name - output.writeInt(8); // modifiers - output.writeUTF("()V"); // signature - - // constructors - output.writeUTF("<init>"); // name - output.writeInt(0); // modifiers - output.writeUTF("()V"); // signature - - // methods - output.writeUTF("equals"); // name - output.writeInt(1); // modifiers - output.writeUTF("(Ljava.lang.Object;)Z"); // signature - - // ----------------------------------------------------------------------- - - output.flush(); - - byte[] data = out.toByteArray(); - byte[] hash = sha.digest(data); - assertTrue("SHA_DATA_2 NOT ok", Arrays.equals(hash, SHA_DATA_2)); - } catch (IOException e) { - fail("SHA_DATA_2 NOT ok"); - } + private void testSerializationSHA_DATA_2(MessageDigest sha) throws Exception { + sha.reset(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DataOutputStream output = new DataOutputStream(out); + + // Made up data + output.writeUTF("tests.api.java.security.MessageDigestTest$InitializerFieldsTest3"); + output.writeInt(0); // class modifiers + output.writeUTF("java.io.Serializable"); // interfaces + + // Fields + output.writeUTF("sub_toBeNotSerialized"); // name + output.writeInt(9); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + output.writeUTF("sub_toBeNotSerialized2"); // name + output.writeInt(9); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + output.writeUTF("sub_toBeSerialized"); // name + output.writeInt(1); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + output.writeUTF("sub_toBeSerialized3"); // name + output.writeInt(1); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + output.writeUTF("sub_toBeSerialized4"); // name + output.writeInt(1); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + output.writeUTF("sub_toBeSerialized5"); // name + output.writeInt(1); // modifiers + output.writeUTF("Ljava/lang/String;"); // signature + + // clinit + output.writeUTF("<clinit>"); // name + output.writeInt(8); // modifiers + output.writeUTF("()V"); // signature + + // constructors + output.writeUTF("<init>"); // name + output.writeInt(0); // modifiers + output.writeUTF("()V"); // signature + + // methods + output.writeUTF("equals"); // name + output.writeInt(1); // modifiers + output.writeUTF("(Ljava.lang.Object;)Z"); // signature + + output.flush(); + + byte[] data = out.toByteArray(); + byte[] hash = sha.digest(data); + assertTrue("SHA_DATA_2 NOT ok", Arrays.equals(hash, SHA_DATA_2)); } private static final byte[] SHA_DATA_1 = { 90, 36, 111, 106, -32, 38, 4, 126, 21, -51, 107, 45, -64, -68, -109, 112, -31, -46, 34, 115, }; - private void testSerializationSHA_DATA_1(MessageDigest sha) { - try { - sha.reset(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DataOutputStream output = new DataOutputStream(out); - // ----------------------------------------------------------------------- - - // Made up data - output - .writeUTF("tests.api.java.security.MessageDigestTest$OptionalDataNotRead"); - // name - output.writeInt(0); // class modifiers - output.writeUTF("java.io.Serializable"); // interfaces - - // Fields - output.writeUTF("class$0"); // name - output.writeInt(8); // modifiers - output.writeUTF("Ljava/lang/Class;"); // signature - - output.writeUTF("field1"); // name - output.writeInt(2); // modifiers - output.writeUTF("I"); // signature - - output.writeUTF("field2"); // name - output.writeInt(2); // modifiers - output.writeUTF("I"); // signature - - // clinit - output.writeUTF("<clinit>"); // name - output.writeInt(8); // modifiers - output.writeUTF("()V"); // signature - - // constructors - output.writeUTF("<init>"); // name - output.writeInt(1); // modifiers - output.writeUTF("()V"); // signature - // ----------------------------------------------------------------------- - - output.flush(); - byte[] data = out.toByteArray(); - byte[] hash = sha.digest(data); - assertTrue("SHA_DATA_1 NOT ok", Arrays.equals(hash, SHA_DATA_1)); - } catch (IOException e) { - fail("SHA_DATA_1 NOT ok"); - } + private void testSerializationSHA_DATA_1(MessageDigest sha) throws Exception { + sha.reset(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DataOutputStream output = new DataOutputStream(out); + + // Made up data + output.writeUTF("tests.api.java.security.MessageDigestTest$OptionalDataNotRead"); + // name + output.writeInt(0); // class modifiers + output.writeUTF("java.io.Serializable"); // interfaces + + // Fields + output.writeUTF("class$0"); // name + output.writeInt(8); // modifiers + output.writeUTF("Ljava/lang/Class;"); // signature + + output.writeUTF("field1"); // name + output.writeInt(2); // modifiers + output.writeUTF("I"); // signature + + output.writeUTF("field2"); // name + output.writeInt(2); // modifiers + output.writeUTF("I"); // signature + + // clinit + output.writeUTF("<clinit>"); // name + output.writeInt(8); // modifiers + output.writeUTF("()V"); // signature + + // constructors + output.writeUTF("<init>"); // name + output.writeInt(1); // modifiers + output.writeUTF("()V"); // signature + + output.flush(); + byte[] data = out.toByteArray(); + byte[] hash = sha.digest(data); + assertTrue("SHA_DATA_1 NOT ok", Arrays.equals(hash, SHA_DATA_1)); } /** - * @tests java.security.MessageDigest#digest() + * java.security.MessageDigest#digest() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "digest", - args = {} - ) - public void test_digest() { - MessageDigest sha = null; - try { - sha = MessageDigest.getInstance("SHA"); - assertNotNull(sha); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm"); - } + public void test_digest() throws Exception { + MessageDigest sha = MessageDigest.getInstance("SHA"); + assertNotNull(sha); sha.update(MESSAGE.getBytes()); byte[] digest = sha.digest(); assertTrue("bug in SHA", MessageDigest.isEqual(digest, MESSAGE_DIGEST)); @@ -264,8 +213,7 @@ public class MessageDigest2Test extends junit.framework.TestCase { sha.update((byte) 'a'); } digest = sha.digest(); - assertTrue("bug in SHA", MessageDigest.isEqual(digest, - MESSAGE_DIGEST_63_As)); + assertTrue("bug in SHA", MessageDigest.isEqual(digest, MESSAGE_DIGEST_63_As)); sha.reset(); for (int i = 0; i < 64; i++) { @@ -273,8 +221,7 @@ public class MessageDigest2Test extends junit.framework.TestCase { sha.update((byte) 'a'); } digest = sha.digest(); - assertTrue("bug in SHA", MessageDigest.isEqual(digest, - MESSAGE_DIGEST_64_As)); + assertTrue("bug in SHA", MessageDigest.isEqual(digest, MESSAGE_DIGEST_64_As)); sha.reset(); for (int i = 0; i < 65; i++) { @@ -282,368 +229,229 @@ public class MessageDigest2Test extends junit.framework.TestCase { sha.update((byte) 'a'); } digest = sha.digest(); - assertTrue("bug in SHA", MessageDigest.isEqual(digest, - MESSAGE_DIGEST_65_As)); + assertTrue("bug in SHA", MessageDigest.isEqual(digest, MESSAGE_DIGEST_65_As)); testSerializationSHA_DATA_1(sha); testSerializationSHA_DATA_2(sha); } /** - * @tests java.security.MessageDigest#digest(byte[]) + * java.security.MessageDigest#digest(byte[]) */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "digest", - args = {byte[].class} - ) - public void test_digest$B() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - MessageDigest digest = MessageDigest.getInstance(digestAlgs[i], - providerName); + public void test_digest$B() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest digest = MessageDigest.getInstance(algorithm, e.getKey().getName()); assertNotNull(digest); digest.digest(AR1); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); } } } /** - * @tests java.security.MessageDigest#digest(byte[], int, int) + * java.security.MessageDigest#digest(byte[], int, int) */ - @TestTargetNew( - level = TestLevel.PARTIAL_COMPLETE, - notes = "", - method = "digest", - args = {byte[].class, int.class, int.class} - ) - public void test_digest$BII() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - MessageDigest digest = MessageDigest.getInstance(digestAlgs[i], - providerName); + public void test_digest$BII() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest digest = MessageDigest.getInstance(algorithm, e.getKey().getName()); assertNotNull(digest); int len = digest.getDigestLength(); byte[] digestBytes = new byte[len]; digest.digest(digestBytes, 0, digestBytes.length); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); - } catch (DigestException e) { - fail("digest caused exception for algorithm " + digestAlgs[i] - + " : " + e); } - } - try { - MessageDigest.getInstance("SHA").digest(new byte[] {}, - Integer.MAX_VALUE, 755); - } catch (NoSuchAlgorithmException e) { - // allowed - } catch (DigestException e) { - // allowed - } catch (IllegalArgumentException e) { - // expected + try { + MessageDigest.getInstance("SHA").digest(new byte[] {}, Integer.MAX_VALUE, 755); + fail(); + } catch (IllegalArgumentException expected) { + } } } /** - * @tests java.security.MessageDigest#update(byte[], int, int) + * java.security.MessageDigest#update(byte[], int, int) */ - @TestTargetNew( - level = TestLevel.PARTIAL_COMPLETE, - notes = "D", - method = "update", - args = {byte[].class, int.class, int.class} - ) - public void test_update$BII() { + public void test_update$BII() throws Exception { try { MessageDigest.getInstance("SHA").update(new byte[] {}, - Integer.MAX_VALUE, Integer.MAX_VALUE); - } catch (NoSuchAlgorithmException e) { - // allowed - } catch (IllegalArgumentException e) { - // expected + Integer.MAX_VALUE, Integer.MAX_VALUE); + fail(); + } catch (IllegalArgumentException expected) { } } /** - * @tests java.security.MessageDigest#getAlgorithm() + * java.security.MessageDigest#getAlgorithm() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getAlgorithm", - args = {} - ) - public void test_getAlgorithm() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - String alg = MessageDigest.getInstance(digestAlgs[i], - providerName).getAlgorithm(); - assertTrue("getAlgorithm ok", alg.equals(digestAlgs[i])); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); + public void test_getAlgorithm() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm, e.getKey().getName()); + assertEquals(algorithm, md.getAlgorithm()); } } } /** - * @tests java.security.MessageDigest#getDigestLength() + * java.security.MessageDigest#getDigestLength() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getDigestLength", - args = {} - ) - public void test_getDigestLength() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - int len = MessageDigest - .getInstance(digestAlgs[i], providerName) - .getDigestLength(); - assertTrue("length not ok", len > 0); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); + public void test_getDigestLength() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm, e.getKey().getName()); + assertTrue("length not ok", md.getDigestLength() > 0); } - }// end for + } } /** - * @tests java.security.MessageDigest#getInstance(java.lang.String) + * java.security.MessageDigest#getInstance(java.lang.String) */ - @TestTargetNew( - level = TestLevel.PARTIAL_COMPLETE, - notes = "", - method = "getInstance", - args = {java.lang.String.class} - ) - public void test_getInstanceLjava_lang_String() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - MessageDigest.getInstance(digestAlgs[i]); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); + public void test_getInstanceLjava_lang_String() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm); + assertNotNull(md); } } try { MessageDigest.getInstance("UnknownDigest"); fail("expected NoSuchAlgorithmException"); - } catch (NoSuchAlgorithmException e) { - // ok + } catch (NoSuchAlgorithmException expected) { } } /** - * @tests java.security.MessageDigest#getInstance(java.lang.String, + * java.security.MessageDigest#getInstance(java.lang.String, * java.lang.String) */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getInstance", - args = {java.lang.String.class, java.lang.String.class} - ) - public void test_getInstanceLjava_lang_StringLjava_lang_String() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - MessageDigest.getInstance(digestAlgs[i], providerName); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); + public void test_getInstanceLjava_lang_StringLjava_lang_String() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm, e.getKey().getName()); + assertNotNull(md); } } - try { - MessageDigest.getInstance(digestAlgs[0], "UnknownProvider"); - fail("expected NoSuchProviderException"); - } catch (NoSuchProviderException e) { - // ok - } catch (NoSuchAlgorithmException e) { - fail("unexpected exception: " + e); + for (List<String> algorithms : digestAlgs.values()) { + for (String algorithm : algorithms) { + try { + MessageDigest.getInstance(algorithm, "UnknownProvider"); + fail("expected NoSuchProviderException"); + } catch (NoSuchProviderException expected) { + } + } } - try { - MessageDigest.getInstance("UnknownDigest", providerName); - fail("expected NoSuchAlgorithmException"); - } catch (NoSuchAlgorithmException e) { - // ok - } catch (NoSuchProviderException e) { - fail("unexpected exception: " + e); + for (Provider provider : digestAlgs.keySet()) { + try { + MessageDigest.getInstance("UnknownDigest", provider.getName()); + fail("expected NoSuchAlgorithmException"); + } catch (NoSuchAlgorithmException expected) { + } } - try { - MessageDigest.getInstance(null, providerName); - fail("expected NullPointerException"); - } catch (NullPointerException e) { - // ok - } catch (NoSuchAlgorithmException e) { - fail("unexpected exception: " + e); - } catch (NoSuchProviderException e) { - fail("unexpected exception: " + e); + for (Provider provider : digestAlgs.keySet()) { + try { + MessageDigest.getInstance(null, provider.getName()); + fail("expected NullPointerException"); + } catch (NullPointerException expected) { + } } try { MessageDigest.getInstance("AnyDigest", (String)null); fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // ok - } catch (NoSuchAlgorithmException e) { - fail("unexpected exception: " + e); - } catch (NoSuchProviderException e) { - fail("unexpected exception: " + e); + } catch (IllegalArgumentException expected) { } } /** - * @tests java.security.MessageDigest#getInstance(java.lang.String, + * java.security.MessageDigest#getInstance(java.lang.String, * java.security.Provider) */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getInstance", - args = {java.lang.String.class, java.security.Provider.class} - ) - public void test_getInstanceLjava_lang_StringLjava_security_Provider() { - Provider[] providers = Security.getProviders("MessageDigest.SHA"); - for (int i = 0; i < digestAlgs.length; i++) { - for (int j = 0; j < providers.length; j++) { - try { - MessageDigest.getInstance(digestAlgs[i], providers[j]); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } + public void test_getInstanceLjava_lang_StringLjava_security_Provider() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm, e.getKey().getName()); + assertNotNull(md); } } try { MessageDigest.getInstance(null, new TestProvider()); fail("expected NullPointerException"); - } catch (NullPointerException e) { - // ok - } catch (NoSuchAlgorithmException e) { - fail("unexpected exception: " + e); + } catch (NullPointerException expected) { } try { MessageDigest.getInstance("UnknownDigest", new TestProvider()); fail("expected NoSuchAlgorithmException"); - } catch (NoSuchAlgorithmException e) { - // ok + } catch (NoSuchAlgorithmException expected) { } try { MessageDigest.getInstance("AnyDigest", (Provider)null); fail("expected IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // ok - } catch (NoSuchAlgorithmException e) { - fail("unexpected exception: " + e); + } catch (IllegalArgumentException expected) { } } /** - * @tests java.security.MessageDigest#getProvider() + * java.security.MessageDigest#getProvider() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "getProvider", - args = {} - ) - public void test_getProvider() { - for (int i = 0; i < digestAlgs.length; i++) { - try { - Provider p = MessageDigest.getInstance(digestAlgs[i], - providerName).getProvider(); - assertNotNull("provider is null", p); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm " + digestAlgs[i]); - } catch (NoSuchProviderException e) { - fail("getInstance did not find provider " + providerName); + public void test_getProvider() throws Exception { + for (Entry<Provider, List<String>> e : digestAlgs.entrySet()) { + for (String algorithm : e.getValue()) { + MessageDigest md = MessageDigest.getInstance(algorithm, e.getKey().getName()); + assertNotNull("provider is null", md.getProvider()); } } } /** - * @tests java.security.MessageDigest#isEqual(byte[], byte[]) + * java.security.MessageDigest#isEqual(byte[], byte[]) */ - @TestTargetNew( - level = TestLevel.PARTIAL, - notes = "Otherwise case is not checked", - method = "isEqual", - args = {byte[].class, byte[].class} - ) public void test_isEqual$B$B() { assertTrue("isEqual is not correct", MessageDigest.isEqual(AR1, AR2)); } /** - * @tests java.security.MessageDigest#toString() + * java.security.MessageDigest#toString() */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "", - method = "toString", - args = {} - ) - public void test_toString() { - try { - String str = MessageDigest.getInstance("SHA").toString(); - assertNotNull("toString is null", str); - } catch (NoSuchAlgorithmException e) { - fail("getInstance did not find algorithm"); - } + public void test_toString() throws Exception { + String str = MessageDigest.getInstance("SHA").toString(); + assertNotNull("toString is null", str); } protected void setUp() { - if (digestAlgs == null) { - Provider[] providers = Security.getProviders("MessageDigest.SHA"); - if (providers == null) { - fail("No providers available for test"); - } - - // Arbitrarily select the first available provider - providerName = providers[0].getName(); - digestAlgs = getDigestAlgorithms(providerName); - if (digestAlgs == null || digestAlgs.length == 0) { - fail("No digest algorithms were found"); - } + Provider[] providers = Security.getProviders("MessageDigest.SHA"); + for (Provider provider : providers) { + digestAlgs.put(provider, getDigestAlgorithms(provider)); } } /* * Returns the digest algorithms that the given provider supports. */ - private String[] getDigestAlgorithms(String providerName) { - Vector<String> algs = new Vector<String>(); - - Provider provider = Security.getProvider(providerName); - if (provider == null) - return new String[0]; - Enumeration e = provider.keys(); - while (e.hasMoreElements()) { - String algorithm = (String) e.nextElement(); - if (algorithm.startsWith(MESSAGEDIGEST_ID) - && !algorithm.contains(" ")) { - algs.addElement(algorithm.substring(MESSAGEDIGEST_ID.length())); + private List<String> getDigestAlgorithms(Provider provider) { + if (provider == null) { + fail("No digest algorithms were found"); + } + + List<String> algs = new ArrayList<String>(); + for (Object key : provider.keySet()) { + String algorithm = (String) key; + if (algorithm.startsWith(MESSAGEDIGEST_ID) && !algorithm.contains(" ")) { + algs.add(algorithm.substring(MESSAGEDIGEST_ID.length())); } - }// end while + } - return (String[]) algs.toArray(new String[algs.size()]); + if (algs.size() == 0) { + fail("No digest algorithms were found"); + } + return algs; } private class MessageDigestStub extends MessageDigest { diff --git a/support/src/test/java/tests/security/MessageDigestTest.java b/support/src/test/java/tests/security/MessageDigestTest.java index 9ae4881..5457688 100644 --- a/support/src/test/java/tests/security/MessageDigestTest.java +++ b/support/src/test/java/tests/security/MessageDigestTest.java @@ -15,16 +15,12 @@ */ package tests.security; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargets; - -import junit.framework.TestCase; - import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import junit.framework.TestCase; + public abstract class MessageDigestTest extends TestCase { private String digestAlgorithmName; @@ -65,14 +61,14 @@ public abstract class MessageDigestTest extends TestCase { expected3 = null; digest = null; + sourceData.close(); sourceData = null; checkDigest = null; System.gc(); } - MessageDigest getMessageDigest() - { + MessageDigest getMessageDigest() { try { return MessageDigest.getInstance(digestAlgorithmName); } catch (NoSuchAlgorithmException e) { @@ -81,59 +77,37 @@ public abstract class MessageDigestTest extends TestCase { } } - InputStream getSourceData() - { - InputStream sourceStream = getClass().getResourceAsStream( - digestAlgorithmName + ".data"); - assertNotNull("digest source data not found: " + digestAlgorithmName, - sourceStream); + InputStream getSourceData() { + InputStream sourceStream = getClass().getResourceAsStream(digestAlgorithmName + ".data"); + assertNotNull("digest source data not found: " + digestAlgorithmName, sourceStream); return sourceStream; } - byte[] getCheckDigest() - { - InputStream checkDigestStream = getClass().getResourceAsStream( - digestAlgorithmName + ".check"); + byte[] getCheckDigest() { + InputStream checkDigestStream = + getClass().getResourceAsStream(digestAlgorithmName + ".check"); byte[] checkDigest = new byte[digest.getDigestLength()]; int read = 0; int index = 0; try { - while ((read = checkDigestStream.read()) != -1) - { + while ((read = checkDigestStream.read()) != -1) { checkDigest[index++] = (byte)read; } + checkDigestStream.close(); } catch (IOException e) { fail("failed to read digest golden data: " + digestAlgorithmName); } return checkDigest; } - @TestTargets({ - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "update", - args = {byte[].class,int.class,int.class} - ), - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "digest", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "method", - args = {} - ) - }) - public void testMessageDigest1() - { + public void testMessageDigest1() { byte[] buf = new byte[128]; int read = 0; try { - while ((read = sourceData.read(buf)) != -1) - { + while ((read = sourceData.read(buf)) != -1) { digest.update(buf, 0, read); } + sourceData.close(); } catch (IOException e) { fail("failed to read digest data"); } @@ -141,42 +115,22 @@ public abstract class MessageDigestTest extends TestCase { byte[] computedDigest = digest.digest(); assertNotNull("computed digest is is null", computedDigest); - assertEquals("digest length mismatch", checkDigest.length, - computedDigest.length); + assertEquals("digest length mismatch", checkDigest.length, computedDigest.length); - for (int i = 0; i < checkDigest.length; i++) - { + for (int i = 0; i < checkDigest.length; i++) { assertEquals("byte " + i + " of computed and check digest differ", - checkDigest[i], computedDigest[i]); + checkDigest[i], computedDigest[i]); } } - @TestTargets({ - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "update", - args = {byte.class} - ), - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "digest", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "method", - args = {} - ) - }) - public void testMessageDigest2() - { + public void testMessageDigest2() { int val; try { - while ((val = sourceData.read()) != -1) - { + while ((val = sourceData.read()) != -1) { digest.update((byte)val); } + sourceData.close(); } catch (IOException e) { fail("failed to read digest data"); } @@ -184,12 +138,10 @@ public abstract class MessageDigestTest extends TestCase { byte[] computedDigest = digest.digest(); assertNotNull("computed digest is is null", computedDigest); - assertEquals("digest length mismatch", checkDigest.length, - computedDigest.length); - for (int i = 0; i < checkDigest.length; i++) - { + assertEquals("digest length mismatch", checkDigest.length, computedDigest.length); + for (int i = 0; i < checkDigest.length; i++) { assertEquals("byte " + i + " of computed and check digest differ", - checkDigest[i], computedDigest[i]); + checkDigest[i], computedDigest[i]); } } @@ -199,8 +151,12 @@ public abstract class MessageDigestTest extends TestCase { * Official FIPS180-2 testcases */ - protected String source1, source2, source3; - protected String expected1, expected2, expected3; + protected String source1; + protected String source2; + protected String source3; + protected String expected1; + protected String expected2; + protected String expected3; String getLongMessage(int length) { StringBuilder sourceBuilder = new StringBuilder(length); @@ -210,23 +166,6 @@ public abstract class MessageDigestTest extends TestCase { return sourceBuilder.toString(); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "update", - args = {byte.class} - ), - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "digest", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "method", - args = {} - ) - }) public void testfips180_2_singleblock() { digest.update(source1.getBytes(), 0, source1.length()); @@ -236,33 +175,13 @@ public abstract class MessageDigestTest extends TestCase { assertNotNull("computed digest is null", computedDigest); StringBuilder sb = new StringBuilder(); - String res; - for (int i = 0; i < computedDigest.length; i++) - { - res = Integer.toHexString(computedDigest[i] & 0xFF); + for (int i = 0; i < computedDigest.length; i++) { + String res = Integer.toHexString(computedDigest[i] & 0xFF); sb.append((res.length() == 1 ? "0" : "") + res); } - assertEquals("computed and check digest differ", expected1, - sb.toString()); + assertEquals("computed and check digest differ", expected1, sb.toString()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "update", - args = {byte.class} - ), - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "digest", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "method", - args = {} - ) - }) public void testfips180_2_multiblock() { digest.update(source2.getBytes(), 0, source2.length()); @@ -272,33 +191,13 @@ public abstract class MessageDigestTest extends TestCase { assertNotNull("computed digest is null", computedDigest); StringBuilder sb = new StringBuilder(); - String res; - for (int i = 0; i < computedDigest.length; i++) - { - res = Integer.toHexString(computedDigest[i] & 0xFF); + for (int i = 0; i < computedDigest.length; i++) { + String res = Integer.toHexString(computedDigest[i] & 0xFF); sb.append((res.length() == 1 ? "0" : "") + res); } - assertEquals("computed and check digest differ", expected2, - sb.toString()); + assertEquals("computed and check digest differ", expected2, sb.toString()); } - @TestTargets({ - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "update", - args = {byte.class} - ), - @TestTargetNew( - level = TestLevel.ADDITIONAL, - method = "digest", - args = {} - ), - @TestTargetNew( - level = TestLevel.COMPLETE, - method = "method", - args = {} - ) - }) public void testfips180_2_longMessage() { digest.update(source3.getBytes(), 0, source3.length()); @@ -308,13 +207,10 @@ public abstract class MessageDigestTest extends TestCase { assertNotNull("computed digest is null", computedDigest); StringBuilder sb = new StringBuilder(); - String res; - for (int i = 0; i < computedDigest.length; i++) - { - res = Integer.toHexString(computedDigest[i] & 0xFF); + for (int i = 0; i < computedDigest.length; i++) { + String res = Integer.toHexString(computedDigest[i] & 0xFF); sb.append((res.length() == 1 ? "0" : "") + res); } - assertEquals("computed and check digest differ", expected3, - sb.toString()); + assertEquals("computed and check digest differ", expected3, sb.toString()); } } |