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
native_init(JNIEnv * env,jobject clazz)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
native_reset(JNIEnv * env,jobject clazz)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
native_update(JNIEnv * env,jobject clazz,jbyteArray dataArray)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
native_digest(JNIEnv * env,jobject clazz)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
register_android_message_digest_sha1(JNIEnv * env)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