refactor: match the new branch refactor

This commit is contained in:
0x330a 2022-12-06 16:23:45 +11:00
parent 2daf231e59
commit b2a3e3e7d5
6 changed files with 111 additions and 49 deletions

@ -1 +1 @@
Subproject commit b80d9d9afa725da528d23000062bc34551e4326c Subproject commit fa7e0d0acf9c343f0d7f0a23e5852077c2cf288f

View File

@ -3,6 +3,8 @@ package network.loki.messenger.libsession_util
import android.util.Log import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import network.loki.messenger.libsession_util.util.Sodium
import network.loki.messenger.libsession_util.util.UserPic
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -15,6 +17,10 @@ import org.session.libsignal.utilities.Hex
*/ */
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class InstrumentedTests { class InstrumentedTests {
val seed = Hex.fromStringCondensed("0123456789abcdef0123456789abcdef00000000000000000000000000000000")
val keyPair = Sodium.ed25519KeyPair(seed)
@Test @Test
fun useAppContext() { fun useAppContext() {
// Context of the app under test. // Context of the app under test.
@ -24,15 +30,14 @@ class InstrumentedTests {
@Test @Test
fun jni_accessible() { fun jni_accessible() {
val userProfile = UserProfile.newInstance() val userProfile = UserProfile.newInstance(keyPair.secretKey)
assertNotNull(userProfile) assertNotNull(userProfile)
userProfile.free() userProfile.free()
} }
@Test @Test
fun jni_user_profile_c_api() { fun jni_user_profile_c_api() {
Log.d("JNITEST","Creating profile") val userProfile = UserProfile.newInstance(keyPair.secretKey)
val userProfile = UserProfile.newInstance()
// these should be false as empty config // these should be false as empty config
assertFalse(userProfile.needsPush()) assertFalse(userProfile.needsPush())
@ -53,9 +58,7 @@ class InstrumentedTests {
// not sending keylen like c api so cutting off the NOTSECRET in key for testing purposes // not sending keylen like c api so cutting off the NOTSECRET in key for testing purposes
userProfile.setName("Kallie") userProfile.setName("Kallie")
val newUserPic = UserPic("http://example.org/omg-pic-123.bmp", "secret".encodeToByteArray()) val newUserPic = UserPic("http://example.org/omg-pic-123.bmp", "secret".encodeToByteArray())
Log.d("JNITEST","setting pic")
userProfile.setPic(newUserPic) userProfile.setPic(newUserPic)
Log.d("JNITEST","set pic")
// Retrieve them just to make sure they set properly: // Retrieve them just to make sure they set properly:
assertEquals("Kallie", userProfile.getName()) assertEquals("Kallie", userProfile.getName())
@ -110,7 +113,7 @@ class InstrumentedTests {
@Test @Test
fun jni_setting_getting() { fun jni_setting_getting() {
val userProfile = UserProfile.newInstance() val userProfile = UserProfile.newInstance(keyPair.secretKey)
val newName = "test" val newName = "test"
println("Name being set via JNI call: $newName") println("Name being set via JNI call: $newName")
userProfile.setName(newName) userProfile.setName(newName)

View File

@ -1,5 +1,6 @@
#include <jni.h> #include <jni.h>
#include <string> #include <string>
#include <sodium/crypto_sign_ed25519.h>
#include "session/config/user_profile.hpp" #include "session/config/user_profile.hpp"
session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) { session::config::ConfigBase* ptrToConfigBase(JNIEnv *env, jobject obj) {
@ -14,7 +15,7 @@ session::config::UserProfile* ptrToProfile(JNIEnv* env, jobject obj) {
return (session::config::UserProfile*) env->GetLongField(obj, pointerField); return (session::config::UserProfile*) env->GetLongField(obj, pointerField);
} }
jbyteArray bytes_from_string(JNIEnv* env, std::string_view from_str) { jbyteArray bytes_from_ustring(JNIEnv* env, session::ustring_view from_str) {
size_t length = from_str.length(); size_t length = from_str.length();
jsize jlength = (jsize)length; jsize jlength = (jsize)length;
jbyteArray new_array = env->NewByteArray(jlength); jbyteArray new_array = env->NewByteArray(jlength);
@ -22,20 +23,36 @@ jbyteArray bytes_from_string(JNIEnv* env, std::string_view from_str) {
return new_array; return new_array;
} }
std::string string_from_bytes(JNIEnv* env, jbyteArray byteArray) { session::ustring ustring_from_bytes(JNIEnv* env, jbyteArray byteArray) {
size_t len = env->GetArrayLength(byteArray); size_t len = env->GetArrayLength(byteArray);
jbyte* bytes = env->GetByteArrayElements(byteArray, nullptr); jbyte* bytes = env->GetByteArrayElements(byteArray, nullptr);
std::string newSt((char*)bytes, len); session::ustring newSt((u_char*)bytes, len);
env->ReleaseByteArrayElements(byteArray, bytes, 0); env->ReleaseByteArrayElements(byteArray, bytes, 0);
return newSt; return newSt;
} }
extern "C" JNIEXPORT jobject JNICALL extern "C"
Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance( JNIEXPORT jobject JNICALL
JNIEnv* env, Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B_3B(
jobject) { JNIEnv *env, jobject thiz, jbyteArray ed25519_secret_key, jbyteArray initial_dump) {
auto secret_key = ustring_from_bytes(env, ed25519_secret_key);
auto initial = ustring_from_bytes(env, initial_dump);
auto* profile = new session::config::UserProfile(secret_key, std::optional(initial));
auto* profile = new session::config::UserProfile(); jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile");
jmethodID constructor = env->GetMethodID(userClass, "<init>", "(J)V");
jobject newConfig = env->NewObject(userClass, constructor, reinterpret_cast<jlong>(profile));
return newConfig;
}
extern "C" JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_UserProfile_00024Companion_newInstance___3B(
JNIEnv* env,
jobject,
jbyteArray secretKey) {
auto* profile = new session::config::UserProfile(ustring_from_bytes(env, secretKey), std::nullopt);
jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile"); jclass userClass = env->FindClass("network/loki/messenger/libsession_util/UserProfile");
jmethodID constructor = env->GetMethodID(userClass, "<init>", "(J)V"); jmethodID constructor = env->GetMethodID(userClass, "<init>", "(J)V");
@ -58,8 +75,8 @@ JNIEXPORT jstring JNICALL
Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jobject thiz) { Java_network_loki_messenger_libsession_1util_UserProfile_getName(JNIEnv *env, jobject thiz) {
auto profile = ptrToProfile(env, thiz); auto profile = ptrToProfile(env, thiz);
auto name = profile->get_name(); auto name = profile->get_name();
if (name == nullptr) return nullptr; if (name == std::nullopt) return nullptr;
jstring returnString = env->NewStringUTF(name->c_str()); jstring returnString = env->NewStringUTF(name->data());
return returnString; return returnString;
} }
@ -96,8 +113,8 @@ JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) { Java_network_loki_messenger_libsession_1util_ConfigBase_push(JNIEnv *env, jobject thiz) {
auto config = ptrToConfigBase(env, thiz); auto config = ptrToConfigBase(env, thiz);
auto pair = config->push(); auto pair = config->push();
std::string to_push_str = pair.first; session::ustring to_push_str = pair.first;
jbyteArray returnByteArray = bytes_from_string(env, to_push_str); jbyteArray returnByteArray = bytes_from_ustring(env, to_push_str);
jlong seqNo = pair.second; jlong seqNo = pair.second;
jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo"); jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/util/ConfigWithSeqNo");
jmethodID methodId = env->GetMethodID(returnObjectClass, "<init>", "([BJ)V"); jmethodID methodId = env->GetMethodID(returnObjectClass, "<init>", "([BJ)V");
@ -109,15 +126,13 @@ extern "C"
JNIEXPORT jobject JNICALL JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, jobject thiz) { Java_network_loki_messenger_libsession_1util_UserProfile_getPic(JNIEnv *env, jobject thiz) {
auto profile = ptrToProfile(env, thiz); auto profile = ptrToProfile(env, thiz);
auto pair = profile->get_profile_pic(); auto pic = profile->get_profile_pic();
if (pic == std::nullopt) return nullptr;
// return nullptr if either parameter is null as per profile class // return nullptr if either parameter is null as per profile class
if (pair.first == nullptr || pair.second == nullptr) return nullptr;
const std::string* pic_url = pair.first;
const std::string* pic_key = pair.second;
jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/UserPic"); jclass returnObjectClass = env->FindClass("network/loki/messenger/libsession_util/UserPic");
jmethodID constructor = env->GetMethodID(returnObjectClass, "<init>", "(Ljava/lang/String;[B)V"); jmethodID constructor = env->GetMethodID(returnObjectClass, "<init>", "(Ljava/lang/String;[B)V");
jstring url = env->NewStringUTF(pic_url->c_str()); jstring url = env->NewStringUTF(pic->url.data());
jbyteArray byteArray = bytes_from_string(env, *pic_key); jbyteArray byteArray = bytes_from_ustring(env, pic->key);
jobject returnObject = env->NewObject(returnObjectClass, constructor, url, byteArray); jobject returnObject = env->NewObject(returnObjectClass, constructor, url, byteArray);
return returnObject; return returnObject;
} }
@ -133,7 +148,7 @@ Java_network_loki_messenger_libsession_1util_UserProfile_setPic(JNIEnv *env, job
auto key = (jbyteArray)env->GetObjectField(user_pic, keyField); auto key = (jbyteArray)env->GetObjectField(user_pic, keyField);
const char* pic_chars = env->GetStringUTFChars(pic, nullptr); const char* pic_chars = env->GetStringUTFChars(pic, nullptr);
const std::string key_str = string_from_bytes(env, key); auto key_str = ustring_from_bytes(env, key);
auto* pic_string = new std::string(pic_chars); auto* pic_string = new std::string(pic_chars);
profile->set_profile_pic(*pic_string, key_str); profile->set_profile_pic(*pic_string, key_str);
@ -142,7 +157,24 @@ extern "C"
JNIEXPORT jbyteArray JNICALL JNIEXPORT jbyteArray JNICALL
Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) { Java_network_loki_messenger_libsession_1util_ConfigBase_dump(JNIEnv *env, jobject thiz) {
auto config = ptrToConfigBase(env, thiz); auto config = ptrToConfigBase(env, thiz);
std::string dumped = config->dump(); auto dumped = config->dump();
jbyteArray bytes = bytes_from_string(env, dumped); jbyteArray bytes = bytes_from_ustring(env, dumped);
return bytes; return bytes;
}
extern "C"
JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_util_Sodium_ed25519KeyPair(JNIEnv *env, jobject thiz, jbyteArray seed) {
std::array<unsigned char, 32> ed_pk;
std::array<unsigned char, 64> ed_sk;
auto seed_bytes = ustring_from_bytes(env, seed);
crypto_sign_ed25519_seed_keypair(ed_pk.data(), ed_sk.data(), seed_bytes.c_str());
jclass kp_class = env->FindClass("network/loki/messenger/libsession_util/util/KeyPair");
jmethodID kp_constructor = env->GetMethodID(kp_class, "<init>", "([B[B)V");
jbyteArray pk_jarray = bytes_from_ustring(env, ed_pk.data());
jbyteArray sk_jarray = bytes_from_ustring(env, ed_sk.data());
jobject return_obj = env->NewObject(kp_class, kp_constructor, pk_jarray, sk_jarray);
return return_obj;
} }

View File

@ -1,6 +1,7 @@
package network.loki.messenger.libsession_util package network.loki.messenger.libsession_util
import network.loki.messenger.libsession_util.util.ConfigWithSeqNo import network.loki.messenger.libsession_util.util.ConfigWithSeqNo
import network.loki.messenger.libsession_util.util.UserPic
sealed class ConfigBase(protected val /* yucky */ pointer: Long) { sealed class ConfigBase(protected val /* yucky */ pointer: Long) {
@ -21,31 +22,12 @@ class UserProfile(pointer: Long): ConfigBase(pointer) {
init { init {
System.loadLibrary("session_util") System.loadLibrary("session_util")
} }
external fun newInstance(): UserProfile external fun newInstance(ed25519SecretKey: ByteArray): UserProfile
external fun newInstance(ed25519SecretKey: ByteArray, initialDump: ByteArray): UserProfile
} }
external fun setName(newName: String) external fun setName(newName: String)
external fun getName(): String? external fun getName(): String?
external fun free() external fun free()
external fun getPic(): UserPic? external fun getPic(): UserPic?
external fun setPic(userPic: UserPic) external fun setPic(userPic: UserPic)
}
data class UserPic(val url: String, val key: ByteArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as UserPic
if (url != other.url) return false
if (!key.contentEquals(other.key)) return false
return true
}
override fun hashCode(): Int {
var result = url.hashCode()
result = 31 * result + key.contentHashCode()
return result
}
} }

View File

@ -0,0 +1,5 @@
package network.loki.messenger.libsession_util.util
object Sodium {
external fun ed25519KeyPair(seed: ByteArray): KeyPair
}

View File

@ -19,4 +19,44 @@ data class ConfigWithSeqNo(val config: ByteArray, val seqNo: Long) {
return result return result
} }
}
data class UserPic(val url: String, val key: ByteArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as UserPic
if (url != other.url) return false
if (!key.contentEquals(other.key)) return false
return true
}
override fun hashCode(): Int {
var result = url.hashCode()
result = 31 * result + key.contentHashCode()
return result
}
}
data class KeyPair(val pubKey: ByteArray, val secretKey: ByteArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as KeyPair
if (!pubKey.contentEquals(other.pubKey)) return false
if (!secretKey.contentEquals(other.secretKey)) return false
return true
}
override fun hashCode(): Int {
var result = pubKey.contentHashCode()
result = 31 * result + secretKey.contentHashCode()
return result
}
} }