diff options
Diffstat (limited to 'mozglue/android/NSSBridge.cpp')
-rw-r--r-- | mozglue/android/NSSBridge.cpp | 285 |
1 files changed, 0 insertions, 285 deletions
diff --git a/mozglue/android/NSSBridge.cpp b/mozglue/android/NSSBridge.cpp deleted file mode 100644 index 3343ad1b2..000000000 --- a/mozglue/android/NSSBridge.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdlib.h> -#include "dlfcn.h" -#include "NSSBridge.h" -#include "APKOpen.h" -#ifdef ANDROID -#include <jni.h> -#include <android/log.h> -#endif - -#include "ElfLoader.h" - -#ifdef DEBUG -#define LOG(x...) __android_log_print(ANDROID_LOG_INFO, "GeckoJNI", x) -#else -#define LOG(x...) -#endif - -static bool initialized = false; - -#define NSS_WRAPPER_INT(name) name ## _t f_ ## name; -NSS_WRAPPER_INT(NSS_Initialize) -NSS_WRAPPER_INT(NSS_Shutdown) -NSS_WRAPPER_INT(SECITEM_ZfreeItem) -NSS_WRAPPER_INT(PK11SDR_Encrypt) -NSS_WRAPPER_INT(PK11SDR_Decrypt) -NSS_WRAPPER_INT(PK11_GetInternalKeySlot) -NSS_WRAPPER_INT(PK11_NeedUserInit) -NSS_WRAPPER_INT(PK11_InitPin) -NSS_WRAPPER_INT(PR_ErrorToString) -NSS_WRAPPER_INT(PR_GetError) -NSS_WRAPPER_INT(PR_Free) -NSS_WRAPPER_INT(PL_Base64Encode) -NSS_WRAPPER_INT(PL_Base64Decode) -NSS_WRAPPER_INT(PL_strfree) - -SECStatus doCrypto(JNIEnv* jenv, const char *path, const char *value, char** result, bool doEncrypt); -SECStatus encode(const uint8_t* data, uint32_t srclen, char** result); -SECStatus decode(const char* data, uint8_t** result, uint32_t* length); - -int -setup_nss_functions(void *nss_handle, - void *nspr_handle, - void *plc_handle) -{ - if (nss_handle == nullptr || nspr_handle == nullptr || plc_handle == nullptr) { - LOG("Missing handle\n"); - return FAILURE; - } -#define GETFUNC(name) f_ ## name = (name ## _t) (uintptr_t) __wrap_dlsym(nss_handle, #name); \ - if (!f_ ##name) { __android_log_print(ANDROID_LOG_ERROR, "GeckoJNI", "missing %s", #name); return FAILURE; } - GETFUNC(NSS_Initialize); - GETFUNC(NSS_Shutdown); - GETFUNC(PK11SDR_Encrypt); - GETFUNC(PK11SDR_Decrypt); - GETFUNC(PK11_GetInternalKeySlot); - GETFUNC(PK11_NeedUserInit); - GETFUNC(PK11_InitPin); - GETFUNC(SECITEM_ZfreeItem); -#undef GETFUNC -#define NSPRFUNC(name) f_ ## name = (name ## _t) (uintptr_t) __wrap_dlsym(nspr_handle, #name); \ - if (!f_ ##name) { __android_log_print(ANDROID_LOG_ERROR, "GeckoJNI", "missing %s", #name); return FAILURE; } - NSPRFUNC(PR_ErrorToString); - NSPRFUNC(PR_GetError); - NSPRFUNC(PR_Free); -#undef NSPRFUNC -#define PLCFUNC(name) f_ ## name = (name ## _t) (uintptr_t) __wrap_dlsym(plc_handle, #name); \ - if (!f_ ##name) { __android_log_print(ANDROID_LOG_ERROR, "GeckoJNI", "missing %s", #name); return FAILURE; } - PLCFUNC(PL_Base64Encode); - PLCFUNC(PL_Base64Decode); - PLCFUNC(PL_strfree); -#undef PLCFUNC - - return SUCCESS; -} - -/* Throws the current NSS error. */ -static void -throwError(JNIEnv* jenv, const char * funcString) { - char *msg; - - PRErrorCode perr = f_PR_GetError(); - char * errString = f_PR_ErrorToString(perr, 0); - asprintf(&msg, "%s returned error %d: %s\n", funcString, perr, errString); - LOG("Throwing error: %s\n", msg); - - JNI_Throw(jenv, "java/lang/Exception", msg); - free(msg); - LOG("Error thrown\n"); -} - -extern "C" NS_EXPORT jstring MOZ_JNICALL -Java_org_mozilla_gecko_NSSBridge_nativeEncrypt(JNIEnv* jenv, jclass, - jstring jPath, - jstring jValue) -{ - jstring ret = jenv->NewStringUTF(""); - - const char* path; - path = jenv->GetStringUTFChars(jPath, nullptr); - - const char* value; - value = jenv->GetStringUTFChars(jValue, nullptr); - - char* result; - SECStatus rv = doCrypto(jenv, path, value, &result, true); - if (rv == SECSuccess) { - ret = jenv->NewStringUTF(result); - free(result); - } - - jenv->ReleaseStringUTFChars(jValue, value); - jenv->ReleaseStringUTFChars(jPath, path); - - return ret; -} - -extern "C" NS_EXPORT jstring MOZ_JNICALL -Java_org_mozilla_gecko_NSSBridge_nativeDecrypt(JNIEnv* jenv, jclass, - jstring jPath, - jstring jValue) -{ - jstring ret = jenv->NewStringUTF(""); - - const char* path; - path = jenv->GetStringUTFChars(jPath, nullptr); - - const char* value; - value = jenv->GetStringUTFChars(jValue, nullptr); - - char* result; - SECStatus rv = doCrypto(jenv, path, value, &result, false); - if (rv == SECSuccess) { - ret = jenv->NewStringUTF(result); - free(result); - } - - jenv->ReleaseStringUTFChars(jValue, value); - jenv->ReleaseStringUTFChars(jPath, path); - - return ret; -} - - -/* Encrypts or decrypts a string. result should be freed with free() when done */ -SECStatus -doCrypto(JNIEnv* jenv, const char *path, const char *value, char** result, bool encrypt) -{ - SECStatus rv; - PK11SlotInfo *slot; - if (!initialized) { - LOG("Initialize crypto in %s\n", path); - rv = f_NSS_Initialize(path, "", "", "secmod.db", NSS_INIT_NOROOTINIT); - if (rv != SECSuccess) { - throwError(jenv, "NSS_Initialize"); - return rv; - } - initialized = true; - } - - slot = f_PK11_GetInternalKeySlot(); - if (!slot) { - throwError(jenv, "PK11_GetInternalKeySlot"); - return SECFailure; - } - - if (f_PK11_NeedUserInit(slot)) { - LOG("Initializing key3.db with default blank password.\n"); - rv = f_PK11_InitPin(slot, nullptr, nullptr); - if (rv != SECSuccess) { - throwError(jenv, "PK11_InitPin"); - return rv; - } - } - - SECItem request; - SECItem reply; - - reply.data = 0; - reply.len = 0; - - if (encrypt) { - // This can print sensitive data. Uncomment if you need it. - // LOG("Encrypting: %s\n", value); - request.data = (unsigned char*)value; - request.len = strlen(value); - - SECItem keyid; - keyid.data = 0; - keyid.len = 0; - rv = f_PK11SDR_Encrypt(&keyid, &request, &reply, nullptr); - - if (rv == SECSuccess) { - rv = encode(reply.data, reply.len, result); - if (rv == SECSuccess) { - LOG("Encrypted: %s\n", *result); - } else { - throwError(jenv, "encode"); - } - } else { - throwError(jenv, "PK11SDR_Encrypt"); - } - - } else { - LOG("Decoding: %s\n", value); - rv = decode(value, &request.data, &request.len); - if (rv != SECSuccess) { - throwError(jenv, "decode"); - return rv; - } - - rv = f_PK11SDR_Decrypt(&request, &reply, nullptr); - - if (rv == SECSuccess) { - *result = static_cast<char*>(malloc(reply.len + 1)); - strncpy(*result, reinterpret_cast<char*>(reply.data), reply.len); - (*result)[reply.len] = '\0'; - - // This can print sensitive data. Uncomment if you need it. - // LOG("Decoded %i letters: %s\n", reply.len, *result); - } else { - throwError(jenv, "PK11SDR_Decrypt"); - } - free(request.data); - } - - f_SECITEM_ZfreeItem(&reply, false); - return rv; -} - -/* - * Base64 encodes the data passed in. The caller must deallocate _retval using free(); - */ -SECStatus -encode(const uint8_t* data, uint32_t srclen, char** result) -{ - if (srclen > (PR_UINT32_MAX / 4) * 3) { - return SECFailure; - } - - const uint32_t dstlen = ((srclen + 2) / 3) * 4; - char* const buffer = static_cast<char*>(malloc(dstlen + 1)); - - if (!buffer || !f_PL_Base64Encode(reinterpret_cast<const char*>(data), srclen, buffer)) { - free(buffer); - *result = nullptr; - return SECFailure; - } - - buffer[dstlen] = '\0'; - *result = buffer; - return SECSuccess; -} - -/* - * Base64 decodes the data passed in. The caller must deallocate result using free(); - */ -SECStatus -decode(const char* data, uint8_t** result, uint32_t* length) -{ - uint32_t srclen = strlen(data); - while (srclen && data[srclen - 1] == '=') { - srclen--; - } - - // Avoid overflow when calculating result length. - const uint32_t dstlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4; - // At most 2 extra bytes due to padding in input. - uint8_t* const buffer = static_cast<uint8_t*>(malloc(dstlen + 2)); - - if (!buffer || !f_PL_Base64Decode(data, srclen, reinterpret_cast<char*>(buffer))) { - free(buffer); - *result = nullptr; - *length = 0; - return SECFailure; - } - - buffer[dstlen] = '\0'; - *result = buffer; - *length = dstlen; - return SECSuccess; -} |