Home | History | Annotate | Download | only in jni
      1 /* //device/libs/android_runtime/android_message_digest_sha1.cpp
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 #include "jni.h"
     19 #include <JNIHelp.h>
     20 #include "android_runtime/AndroidRuntime.h"
     21 
     22 #include <openssl/sha.h>
     23 
     24 //#define _DEBUG 1
     25 
     26 // ----------------------------------------------------------------------------
     27 
     28 using namespace android;
     29 
     30 // ----------------------------------------------------------------------------
     31 
     32 struct fields_t {
     33     jfieldID	context;
     34 };
     35 static fields_t fields;
     36 
     37 static void native_init(JNIEnv *env, jobject clazz)
     38 {
     39 	SHA_CTX* context;
     40 
     41 #ifdef _DEBUG
     42 	printf("sha1.native_init\n");
     43 #endif
     44 
     45 	context = (SHA_CTX *)malloc(sizeof(SHA_CTX));
     46 	SHA1_Init(context);
     47 
     48 	env->SetIntField(clazz, fields.context, (int)context);
     49 }
     50 
     51 static void native_reset(JNIEnv *env, jobject clazz)
     52 {
     53     SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
     54 	if (context != NULL) {
     55 #ifdef _DEBUG
     56 		printf("sha1.native_reset: free context\n");
     57 #endif
     58 		free(context);
     59   		env->SetIntField(clazz, fields.context, 0 );
     60 	}
     61 }
     62 
     63 
     64 static void native_update(JNIEnv *env, jobject clazz, jbyteArray dataArray)
     65 {
     66 #ifdef _DEBUG
     67 	printf("sha1.native_update\n");
     68 #endif
     69 	jbyte * data;
     70     jsize dataSize;
     71     SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
     72 
     73     if (context == NULL) {
     74 #ifdef _DEBUG
     75 		printf("sha1.native_update: context is NULL, call init...\n");
     76 #endif
     77     	native_init(env, clazz);
     78     	context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
     79     }
     80 
     81     data = env->GetByteArrayElements(dataArray, NULL);
     82     if (data == NULL) {
     83         LOGE("Unable to get byte array elements");
     84         jniThrowException(env, "java/lang/IllegalArgumentException",
     85                           "Invalid data array when calling MessageDigest.update()");
     86         return;
     87     }
     88     dataSize = env->GetArrayLength(dataArray);
     89 
     90     SHA1_Update(context, data, dataSize);
     91 
     92     env->ReleaseByteArrayElements(dataArray, data, 0);
     93 }
     94 
     95 static jbyteArray native_digest(JNIEnv *env, jobject clazz)
     96 {
     97 #ifdef _DEBUG
     98 	printf("sha1.native_digest\n");
     99 #endif
    100 	jbyteArray array;
    101 	jbyte md[SHA_DIGEST_LENGTH];
    102 	SHA_CTX *context = (SHA_CTX *)env->GetIntField(clazz, fields.context);
    103 
    104   	SHA1_Final((uint8_t*)md, context);
    105 
    106   	array = env->NewByteArray(SHA_DIGEST_LENGTH);
    107     LOG_ASSERT(array, "Native could not create new byte[]");
    108 
    109   	env->SetByteArrayRegion(array, 0, SHA_DIGEST_LENGTH, md);
    110 
    111   	native_reset(env, clazz);
    112 
    113   	return array;
    114 }
    115 
    116 
    117 static JNINativeMethod method_table[] =
    118 {
    119      /* name, signature, funcPtr */
    120 	{"init", "()V", (void *)native_init},
    121     {"update", "([B)V", (void *)native_update},
    122     {"digest", "()[B", (void *)native_digest},
    123 	{"reset", "()V", (void *)native_reset},
    124 };
    125 
    126 int register_android_message_digest_sha1(JNIEnv *env)
    127 {
    128     jclass clazz;
    129 
    130     clazz = env->FindClass("android/security/Sha1MessageDigest");
    131     if (clazz == NULL) {
    132         LOGE("Can't find android/security/Sha1MessageDigest");
    133         return -1;
    134     }
    135 
    136 	fields.context = env->GetFieldID(clazz, "mNativeSha1Context", "I");
    137 	if (fields.context == NULL) {
    138 		LOGE("Can't find Sha1MessageDigest.mNativeSha1Context");
    139 		return -1;
    140 	}
    141 
    142     return AndroidRuntime::registerNativeMethods(
    143     					env, "android/security/Sha1MessageDigest",
    144     					method_table, NELEM(method_table));
    145 }
    146 
    147