blob: 35335599659c4b75ea038dd1e91650c9a52063e1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
24namespace android
25{
26
27struct fields_t {
28 jfieldID context;
29};
30static fields_t fields;
31
32static 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
40static 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
49static 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
74static 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
97static 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
106int 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};