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