/* //device/libs/android_runtime/android_util_Base64.cpp ** ** Copyright 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. */ /********************************************************* * * This code was copied from * system/extra/ssh/dropbear-0.49/libtomcrypt/src/misc/base64/base64_decode.c * *********************************************************/ #define LOG_TAG "Base64" #include #include #include "JNIHelp.h" #include #include #include #include #include namespace android { static const unsigned char map[256] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; /** base64 decode a block of memory @param in The base64 data to decode @param inlen The length of the base64 data @param out [out] The destination of the binary decoded data @param outlen [in/out] The max size and resulting size of the decoded data @return 0 if successful */ int base64_decode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long t, x, y, z; unsigned char c; int g; g = 3; for (x = y = z = t = 0; x < inlen; x++) { c = map[in[x]&0xFF]; if (c == 255) continue; /* the final = symbols are read and used to trim the remaining bytes */ if (c == 254) { c = 0; /* prevent g < 0 which would potentially allow an overflow later */ if (--g < 0) { return -3; } } else if (g != 3) { /* we only allow = to be at the end */ return -4; } t = (t<<6)|c; if (++y == 4) { if (z + g > *outlen) { return -2; } out[z++] = (unsigned char)((t>>16)&255); if (g > 1) out[z++] = (unsigned char)((t>>8)&255); if (g > 2) out[z++] = (unsigned char)(t&255); y = t = 0; } } if (y != 0) { return -5; } *outlen = z; return 0; } static jbyteArray decodeBase64(JNIEnv *env, jobject jobj, jstring jdata) { const char * rawData = env->GetStringUTFChars(jdata, NULL); int stringLength = env->GetStringUTFLength(jdata); int resultLength = stringLength / 4 * 3; if (rawData[stringLength-1] == '=') { resultLength -= 1; if (rawData[stringLength-2] == '=') { resultLength -= 1; } } jbyteArray byteArray = env->NewByteArray(resultLength); jbyte* byteArrayData = env->GetByteArrayElements(byteArray, NULL); unsigned long outlen = resultLength; int result = base64_decode((const unsigned char*)rawData, stringLength, (unsigned char *)byteArrayData, &outlen); if (result != 0) memset((unsigned char *)byteArrayData, -result, resultLength); env->ReleaseStringUTFChars(jdata, rawData); env->ReleaseByteArrayElements(byteArray, byteArrayData, 0); return byteArray; } static const JNINativeMethod methods[] = { {"decodeBase64Native", "(Ljava/lang/String;)[B", (void*)decodeBase64 } }; static const char* const kBase64PathName = "android/os/Base64Utils"; int register_android_util_Base64(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBase64PathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Base64Utils"); return AndroidRuntime::registerNativeMethods( env, kBase64PathName, methods, NELEM(methods)); } }