Merge "Removing android.security.MessageDigest"
This commit is contained in:
committed by
Android (Google) Code Review
commit
dd1729b9e6
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* 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 android.net.http;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import android.security.Sha1MessageDigest;
|
||||
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
* Validator cache used to speed-up certificate chain validation. The idea is
|
||||
* to keep each secure domain name associated with a cryptographically secure
|
||||
* hash of the certificate chain successfully used to validate the domain. If
|
||||
* we establish connection with the domain more than once and each time receive
|
||||
* the same list of certificates, we do not have to re-validate.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
class CertificateValidatorCache {
|
||||
|
||||
// TODO: debug only!
|
||||
public static long mSave = 0;
|
||||
public static long mCost = 0;
|
||||
// TODO: debug only!
|
||||
|
||||
/**
|
||||
* The cache-entry lifetime in milliseconds (here, 10 minutes)
|
||||
*/
|
||||
private static final long CACHE_ENTRY_LIFETIME = 10 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* The certificate factory
|
||||
*/
|
||||
private static CertificateFactory sCertificateFactory;
|
||||
|
||||
/**
|
||||
* The certificate validator cache map (domain to a cache entry)
|
||||
*/
|
||||
private HashMap<Integer, CacheEntry> mCacheMap;
|
||||
|
||||
/**
|
||||
* Random salt
|
||||
*/
|
||||
private int mBigScrew;
|
||||
|
||||
/**
|
||||
* @param certificate The array of server certificates to compute a
|
||||
* secure hash from
|
||||
* @return The secure hash computed from server certificates
|
||||
*/
|
||||
public static byte[] secureHash(Certificate[] certificates) {
|
||||
byte[] secureHash = null;
|
||||
|
||||
// TODO: debug only!
|
||||
long beg = SystemClock.uptimeMillis();
|
||||
// TODO: debug only!
|
||||
|
||||
if (certificates != null && certificates.length != 0) {
|
||||
byte[] encodedCertPath = null;
|
||||
try {
|
||||
synchronized (CertificateValidatorCache.class) {
|
||||
if (sCertificateFactory == null) {
|
||||
try {
|
||||
sCertificateFactory =
|
||||
CertificateFactory.getInstance("X.509");
|
||||
} catch(GeneralSecurityException e) {
|
||||
if (HttpLog.LOGV) {
|
||||
HttpLog.v("CertificateValidatorCache:" +
|
||||
" failed to create the certificate factory");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CertPath certPath =
|
||||
sCertificateFactory.generateCertPath(Arrays.asList(certificates));
|
||||
if (certPath != null) {
|
||||
encodedCertPath = certPath.getEncoded();
|
||||
if (encodedCertPath != null) {
|
||||
Sha1MessageDigest messageDigest =
|
||||
new Sha1MessageDigest();
|
||||
secureHash = messageDigest.digest(encodedCertPath);
|
||||
}
|
||||
}
|
||||
} catch (GeneralSecurityException e) {}
|
||||
}
|
||||
|
||||
// TODO: debug only!
|
||||
long end = SystemClock.uptimeMillis();
|
||||
mCost += (end - beg);
|
||||
// TODO: debug only!
|
||||
|
||||
return secureHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new certificate-validator cache
|
||||
*/
|
||||
public CertificateValidatorCache() {
|
||||
Random random = new Random();
|
||||
mBigScrew = random.nextInt();
|
||||
|
||||
mCacheMap = new HashMap<Integer, CacheEntry>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param domain The domain to check against
|
||||
* @param secureHash The secure hash to check against
|
||||
* @return True iff there is a valid (not expired) cache entry
|
||||
* associated with the domain and the secure hash
|
||||
*/
|
||||
public boolean has(String domain, byte[] secureHash) {
|
||||
boolean rval = false;
|
||||
|
||||
if (domain != null && domain.length() != 0) {
|
||||
if (secureHash != null && secureHash.length != 0) {
|
||||
CacheEntry cacheEntry = (CacheEntry)mCacheMap.get(
|
||||
new Integer(mBigScrew ^ domain.hashCode()));
|
||||
if (cacheEntry != null) {
|
||||
if (!cacheEntry.expired()) {
|
||||
rval = cacheEntry.has(domain, secureHash);
|
||||
// TODO: debug only!
|
||||
if (rval) {
|
||||
mSave += cacheEntry.mSave;
|
||||
}
|
||||
// TODO: debug only!
|
||||
} else {
|
||||
mCacheMap.remove(cacheEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the (domain, secureHash) tuple to the cache
|
||||
* @param domain The domain to be added to the cache
|
||||
* @param secureHash The secure hash to be added to the cache
|
||||
* @return True iff succeeds
|
||||
*/
|
||||
public boolean put(String domain, byte[] secureHash, long save) {
|
||||
if (domain != null && domain.length() != 0) {
|
||||
if (secureHash != null && secureHash.length != 0) {
|
||||
mCacheMap.put(
|
||||
new Integer(mBigScrew ^ domain.hashCode()),
|
||||
new CacheEntry(domain, secureHash, save));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Certificate-validator cache entry. We have one per domain
|
||||
*/
|
||||
private class CacheEntry {
|
||||
|
||||
/**
|
||||
* The hash associated with this cache entry
|
||||
*/
|
||||
private byte[] mHash;
|
||||
|
||||
/**
|
||||
* The time associated with this cache entry
|
||||
*/
|
||||
private long mTime;
|
||||
|
||||
// TODO: debug only!
|
||||
public long mSave;
|
||||
// TODO: debug only!
|
||||
|
||||
/**
|
||||
* The host associated with this cache entry
|
||||
*/
|
||||
private String mDomain;
|
||||
|
||||
/**
|
||||
* Creates a new certificate-validator cache entry
|
||||
* @param domain The domain to be associated with this cache entry
|
||||
* @param secureHash The secure hash to be associated with this cache
|
||||
* entry
|
||||
*/
|
||||
public CacheEntry(String domain, byte[] secureHash, long save) {
|
||||
mDomain = domain;
|
||||
mHash = secureHash;
|
||||
// TODO: debug only!
|
||||
mSave = save;
|
||||
// TODO: debug only!
|
||||
mTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True iff the cache item has expired
|
||||
*/
|
||||
public boolean expired() {
|
||||
return CACHE_ENTRY_LIFETIME < SystemClock.uptimeMillis() - mTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param domain The domain to check
|
||||
* @param secureHash The secure hash to check
|
||||
* @return True iff the given domain and hash match those associated
|
||||
* with this entry
|
||||
*/
|
||||
public boolean has(String domain, byte[] secureHash) {
|
||||
if (domain != null && 0 < domain.length()) {
|
||||
if (!mDomain.equals(domain)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (secureHash != null) {
|
||||
int hashLength = secureHash.length;
|
||||
if (0 < hashLength) {
|
||||
if (hashLength == mHash.length) {
|
||||
for (int i = 0; i < hashLength; ++i) {
|
||||
if (secureHash[i] != mHash[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -18,7 +18,6 @@ package android.net.http;
|
||||
|
||||
import android.net.ParseException;
|
||||
import android.net.WebAddress;
|
||||
import android.security.Md5MessageDigest;
|
||||
import junit.framework.Assert;
|
||||
import android.webkit.CookieManager;
|
||||
|
||||
@@ -26,6 +25,8 @@ import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.Math;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
@@ -377,11 +378,15 @@ public class RequestHandle {
|
||||
*/
|
||||
private String H(String param) {
|
||||
if (param != null) {
|
||||
Md5MessageDigest md5 = new Md5MessageDigest();
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
|
||||
byte[] d = md5.digest(param.getBytes());
|
||||
if (d != null) {
|
||||
return bufferToHex(d);
|
||||
byte[] d = md5.digest(param.getBytes());
|
||||
if (d != null) {
|
||||
return bufferToHex(d);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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 android.security;
|
||||
|
||||
/**
|
||||
* Provides the MD5 hash encryption.
|
||||
*/
|
||||
public class Md5MessageDigest extends MessageDigest
|
||||
{
|
||||
// ptr to native context
|
||||
private int mNativeMd5Context;
|
||||
|
||||
public Md5MessageDigest()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
public byte[] digest(byte[] input)
|
||||
{
|
||||
update(input);
|
||||
return digest();
|
||||
}
|
||||
|
||||
private native void init();
|
||||
public native void update(byte[] input);
|
||||
public native byte[] digest();
|
||||
native public void reset();
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* 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 android.security;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Base class for producing a message digest from different hash encryptions.
|
||||
*/
|
||||
public abstract class MessageDigest
|
||||
{
|
||||
/**
|
||||
* Returns a digest object of the specified type.
|
||||
*
|
||||
* @param algorithm The type of hash function to use. Valid values are
|
||||
* <em>SHA-1</em> and <em>MD5</em>.
|
||||
* @return The respective MessageDigest object. Either a
|
||||
* {@link android.security.Sha1MessageDigest} or
|
||||
* {@link android.security.Md5MessageDigest} object.
|
||||
* @throws NoSuchAlgorithmException If an invalid <var>algorithm</var>
|
||||
* is given.
|
||||
*/
|
||||
public static MessageDigest getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException
|
||||
{
|
||||
if (algorithm == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (algorithm.equals("SHA-1")) {
|
||||
return new Sha1MessageDigest();
|
||||
}
|
||||
else if (algorithm.equals("MD5")) {
|
||||
return new Md5MessageDigest();
|
||||
}
|
||||
|
||||
throw new NoSuchAlgorithmException();
|
||||
}
|
||||
|
||||
public abstract void update(byte[] input);
|
||||
public abstract byte[] digest();
|
||||
|
||||
/**
|
||||
* Produces a message digest for the given input.
|
||||
*
|
||||
* @param input The message to encrypt.
|
||||
* @return The digest (hash sum).
|
||||
*/
|
||||
public abstract byte[] digest(byte[] input);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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 android.security;
|
||||
|
||||
/**
|
||||
* Provides the SHA-1 hash encyption.
|
||||
*/
|
||||
public class Sha1MessageDigest extends MessageDigest
|
||||
{
|
||||
// ptr to native context
|
||||
private int mNativeSha1Context;
|
||||
|
||||
public Sha1MessageDigest()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
public byte[] digest(byte[] input)
|
||||
{
|
||||
update(input);
|
||||
return digest();
|
||||
}
|
||||
|
||||
private native void init();
|
||||
public native void update(byte[] input);
|
||||
public native byte[] digest();
|
||||
native public void reset();
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.storage.IMountService;
|
||||
import android.provider.Settings;
|
||||
import android.security.MessageDigest;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
@@ -40,6 +39,7 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -75,7 +75,6 @@ LOCAL_SRC_FILES:= \
|
||||
android_nfc_NdefRecord.cpp \
|
||||
android_pim_EventRecurrence.cpp \
|
||||
android_text_format_Time.cpp \
|
||||
android_security_Md5MessageDigest.cpp \
|
||||
android_util_AssetManager.cpp \
|
||||
android_util_Binder.cpp \
|
||||
android_util_EventLog.cpp \
|
||||
@@ -138,7 +137,6 @@ LOCAL_SRC_FILES:= \
|
||||
android_server_BluetoothEventLoop.cpp \
|
||||
android_server_BluetoothA2dpService.cpp \
|
||||
android_server_Watchdog.cpp \
|
||||
android_message_digest_sha1.cpp \
|
||||
android_ddm_DdmHandleNativeHeap.cpp \
|
||||
com_android_internal_os_ZygoteInit.cpp \
|
||||
com_android_internal_graphics_NativeUtils.cpp \
|
||||
|
||||
@@ -86,8 +86,6 @@ extern int register_android_media_AudioTrack(JNIEnv *env);
|
||||
extern int register_android_media_JetPlayer(JNIEnv *env);
|
||||
extern int register_android_media_ToneGenerator(JNIEnv *env);
|
||||
|
||||
extern int register_android_message_digest_sha1(JNIEnv *env);
|
||||
|
||||
extern int register_android_util_FloatMath(JNIEnv* env);
|
||||
|
||||
namespace android {
|
||||
@@ -149,7 +147,6 @@ extern int register_android_net_LocalSocketImpl(JNIEnv* env);
|
||||
extern int register_android_net_NetworkUtils(JNIEnv* env);
|
||||
extern int register_android_net_TrafficStats(JNIEnv* env);
|
||||
extern int register_android_net_wifi_WifiManager(JNIEnv* env);
|
||||
extern int register_android_security_Md5MessageDigest(JNIEnv *env);
|
||||
extern int register_android_text_AndroidCharacter(JNIEnv *env);
|
||||
extern int register_android_text_AndroidBidi(JNIEnv *env);
|
||||
extern int register_android_text_KeyCharacterMap(JNIEnv *env);
|
||||
@@ -1202,7 +1199,6 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_content_StringBlock),
|
||||
REG_JNI(register_android_content_XmlBlock),
|
||||
REG_JNI(register_android_emoji_EmojiFactory),
|
||||
REG_JNI(register_android_security_Md5MessageDigest),
|
||||
REG_JNI(register_android_text_AndroidCharacter),
|
||||
REG_JNI(register_android_text_AndroidBidi),
|
||||
REG_JNI(register_android_text_KeyCharacterMap),
|
||||
@@ -1293,7 +1289,6 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_server_BluetoothEventLoop),
|
||||
REG_JNI(register_android_server_BluetoothA2dpService),
|
||||
REG_JNI(register_android_server_Watchdog),
|
||||
REG_JNI(register_android_message_digest_sha1),
|
||||
REG_JNI(register_android_ddm_DdmHandleNativeHeap),
|
||||
REG_JNI(register_android_backup_BackupDataInput),
|
||||
REG_JNI(register_android_backup_BackupDataOutput),
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/* //device/libs/android_runtime/android_message_digest_sha1.cpp
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include <JNIHelp.h>
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
//#define _DEBUG 1
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace android;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct fields_t {
|
||||
jfieldID context;
|
||||
};
|
||||
static fields_t fields;
|
||||
|
||||
static void native_init(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
SHA_CTX* context;
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("sha1.native_init\n");
|
||||
#endif
|
||||
|
||||
context = (SHA_CTX *)malloc(sizeof(SHA_CTX));
|
||||
SHA1_Init(context);
|
||||
|
||||
env->SetIntField(clazz, fields.context, (int)context);
|
||||
}
|
||||
|
||||
static void native_reset(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
|
||||
if (context != NULL) {
|
||||
#ifdef _DEBUG
|
||||
printf("sha1.native_reset: free context\n");
|
||||
#endif
|
||||
free(context);
|
||||
env->SetIntField(clazz, fields.context, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void native_update(JNIEnv *env, jobject clazz, jbyteArray dataArray)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
printf("sha1.native_update\n");
|
||||
#endif
|
||||
jbyte * data;
|
||||
jsize dataSize;
|
||||
SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
|
||||
|
||||
if (context == NULL) {
|
||||
#ifdef _DEBUG
|
||||
printf("sha1.native_update: context is NULL, call init...\n");
|
||||
#endif
|
||||
native_init(env, clazz);
|
||||
context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
|
||||
}
|
||||
|
||||
data = env->GetByteArrayElements(dataArray, NULL);
|
||||
if (data == NULL) {
|
||||
LOGE("Unable to get byte array elements");
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException",
|
||||
"Invalid data array when calling MessageDigest.update()");
|
||||
return;
|
||||
}
|
||||
dataSize = env->GetArrayLength(dataArray);
|
||||
|
||||
SHA1_Update(context, data, dataSize);
|
||||
|
||||
env->ReleaseByteArrayElements(dataArray, data, 0);
|
||||
}
|
||||
|
||||
static jbyteArray native_digest(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
printf("sha1.native_digest\n");
|
||||
#endif
|
||||
jbyteArray array;
|
||||
jbyte md[SHA_DIGEST_LENGTH];
|
||||
SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
|
||||
|
||||
SHA1_Final((uint8_t*)md, context);
|
||||
|
||||
array = env->NewByteArray(SHA_DIGEST_LENGTH);
|
||||
LOG_ASSERT(array, "Native could not create new byte[]");
|
||||
|
||||
env->SetByteArrayRegion(array, 0, SHA_DIGEST_LENGTH, md);
|
||||
|
||||
native_reset(env, clazz);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
static JNINativeMethod method_table[] =
|
||||
{
|
||||
/* name, signature, funcPtr */
|
||||
{"init", "()V", (void *)native_init},
|
||||
{"update", "([B)V", (void *)native_update},
|
||||
{"digest", "()[B", (void *)native_digest},
|
||||
{"reset", "()V", (void *)native_reset},
|
||||
};
|
||||
|
||||
int register_android_message_digest_sha1(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/security/Sha1MessageDigest");
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find android/security/Sha1MessageDigest");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeSha1Context", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find Sha1MessageDigest.mNativeSha1Context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(
|
||||
env, "android/security/Sha1MessageDigest",
|
||||
method_table, NELEM(method_table));
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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.
|
||||
*/
|
||||
|
||||
#include "jni.h"
|
||||
#include <JNIHelp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
namespace android
|
||||
{
|
||||
|
||||
struct fields_t {
|
||||
jfieldID context;
|
||||
};
|
||||
static fields_t fields;
|
||||
|
||||
static void native_init(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
MD5_CTX* context = (MD5_CTX *)malloc(sizeof(MD5_CTX));
|
||||
MD5_Init(context);
|
||||
|
||||
env->SetIntField(clazz, fields.context, (int)context);
|
||||
}
|
||||
|
||||
static void native_reset(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
MD5_CTX *context = (MD5_CTX *)env->GetIntField(clazz, fields.context);
|
||||
if (context != NULL) {
|
||||
free(context);
|
||||
env->SetIntField(clazz, fields.context, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void native_update(JNIEnv *env, jobject clazz, jbyteArray dataArray)
|
||||
{
|
||||
jbyte * data;
|
||||
jsize dataSize;
|
||||
MD5_CTX *context = (MD5_CTX *)env->GetIntField(clazz, fields.context);
|
||||
|
||||
if (context == NULL) {
|
||||
native_init(env, clazz);
|
||||
context = (MD5_CTX *)env->GetIntField(clazz, fields.context);
|
||||
}
|
||||
|
||||
data = env->GetByteArrayElements(dataArray, NULL);
|
||||
if (data == NULL) {
|
||||
LOGE("Unable to get byte array elements");
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException",
|
||||
"Invalid data array when calling MessageDigest.update()");
|
||||
return;
|
||||
}
|
||||
dataSize = env->GetArrayLength(dataArray);
|
||||
|
||||
MD5_Update(context, data, dataSize);
|
||||
|
||||
env->ReleaseByteArrayElements(dataArray, data, 0);
|
||||
}
|
||||
|
||||
static jbyteArray native_digest(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
jbyteArray array;
|
||||
jbyte md[MD5_DIGEST_LENGTH];
|
||||
MD5_CTX *context = (MD5_CTX *)env->GetIntField(clazz, fields.context);
|
||||
|
||||
MD5_Final((uint8_t*)md, context);
|
||||
|
||||
array = env->NewByteArray(MD5_DIGEST_LENGTH);
|
||||
LOG_ASSERT(array, "Native could not create new byte[]");
|
||||
|
||||
env->SetByteArrayRegion(array, 0, MD5_DIGEST_LENGTH, md);
|
||||
|
||||
native_reset(env, clazz);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
|
||||
static JNINativeMethod gMethods[] =
|
||||
{
|
||||
/* name, signature, funcPtr */
|
||||
{"init", "()V", (void *)native_init},
|
||||
{"update", "([B)V", (void *)native_update},
|
||||
{"digest", "()[B", (void *)native_digest},
|
||||
{"reset", "()V", (void *)native_reset},
|
||||
};
|
||||
|
||||
int register_android_security_Md5MessageDigest(JNIEnv *env)
|
||||
{
|
||||
jclass clazz;
|
||||
|
||||
clazz = env->FindClass("android/security/Md5MessageDigest");
|
||||
if (clazz == NULL) {
|
||||
LOGE("Can't find android/security/Md5MessageDigest");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fields.context = env->GetFieldID(clazz, "mNativeMd5Context", "I");
|
||||
if (fields.context == NULL) {
|
||||
LOGE("Can't find Md5MessageDigest.mNativeMd5Context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return jniRegisterNativeMethods(env, "android/security/Md5MessageDigest",
|
||||
gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
};
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
package javax.obex;
|
||||
|
||||
import android.security.Md5MessageDigest;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
@@ -916,8 +916,12 @@ public final class ObexHelper {
|
||||
* @return the MD5 hash of the byte array
|
||||
*/
|
||||
public static byte[] computeMd5Hash(byte[] in) {
|
||||
Md5MessageDigest md5 = new Md5MessageDigest();
|
||||
return md5.digest(in);
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
return md5.digest(in);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -556,9 +556,6 @@ android.provider.Settings$NameValueTable
|
||||
android.provider.Settings$Secure
|
||||
android.provider.Settings$System
|
||||
android.renderscript.RenderScript
|
||||
android.security.Md5MessageDigest
|
||||
android.security.MessageDigest
|
||||
android.security.Sha1MessageDigest
|
||||
android.server.BluetoothA2dpService
|
||||
android.server.BluetoothEventLoop
|
||||
android.server.BluetoothService
|
||||
@@ -1907,6 +1904,7 @@ com.android.org.bouncycastle.crypto.Digest
|
||||
com.android.org.bouncycastle.crypto.ExtendedDigest
|
||||
com.android.org.bouncycastle.crypto.Mac
|
||||
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
|
||||
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$MD5
|
||||
com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
|
||||
com.android.org.bouncycastle.crypto.macs.HMac
|
||||
com.android.org.bouncycastle.jce.ProviderConfigurationPermission
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package android.core;
|
||||
|
||||
import android.security.MessageDigest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import java.security.MessageDigest;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user