summaryrefslogtreecommitdiffstats
path: root/mozglue/android/NSSBridge.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mozglue/android/NSSBridge.cpp')
-rw-r--r--mozglue/android/NSSBridge.cpp285
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;
-}