Skip to content

Commit 81b2127

Browse files
Add more bindings (#10)
1 parent e192c9a commit 81b2127

File tree

18 files changed

+315
-69
lines changed

18 files changed

+315
-69
lines changed

library/src/main/cpp/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ set(SOURCES
4242
encryption.cpp
4343
jni_utils.cpp
4444
ed25519.cpp
45+
curve25519.cpp
46+
hash.cpp
4547
)
4648

4749
add_library( # Sets the name of the library.

library/src/main/cpp/blinded_key.cpp

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@
99
// Created by Thomas Ruffie on 29/7/2024.
1010
//
1111

12+
1213
extern "C"
1314
JNIEXPORT jobject JNICALL
1415
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionKeyPair(JNIEnv *env,
1516
jobject thiz,
1617
jbyteArray ed25519_secret_key) {
1718
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
1819
const auto [pk, sk] = session::blind_version_key_pair(util::vector_from_bytes(env, ed25519_secret_key));
19-
20-
jclass kp_class = env->FindClass("network/loki/messenger/libsession_util/util/KeyPair");
21-
jmethodID kp_constructor = env->GetMethodID(kp_class, "<init>", "([B[B)V");
22-
return env->NewObject(kp_class, kp_constructor, util::bytes_from_vector(env, {pk.data(), pk.data() + pk.size()}), util::bytes_from_vector(env, {sk.data(), sk.data() + sk.size()}));
20+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
2321
});
2422
}
2523
extern "C"
@@ -29,7 +27,11 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionSign(J
2927
jbyteArray ed25519_secret_key,
3028
jlong timestamp) {
3129
return jni_utils::run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
32-
auto bytes = session::blind_version_sign(util::vector_from_bytes(env, ed25519_secret_key), session::Platform::android, timestamp);
30+
auto bytes = session::blind_version_sign(
31+
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
32+
session::Platform::android,
33+
timestamp
34+
);
3335
return util::bytes_from_vector(env, bytes);
3436
});
3537
}
@@ -46,16 +48,63 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blindVersionSignRe
4648
return jni_utils::run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
4749
auto methodC = util::string_from_jstring(env, method);
4850
auto pathC = util::string_from_jstring(env, path);
49-
auto keyBytes = util::vector_from_bytes(env, ed25519_secret_key);
50-
auto bodyBytes = body ? std::optional(util::vector_from_bytes(env, body)) : std::nullopt;
5151

5252
auto bytes = session::blind_version_sign_request(
53-
session::to_span(keyBytes),
53+
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
5454
timestamp,
5555
methodC,
5656
pathC,
57-
body ? std::optional(session::to_span(*bodyBytes)) : std::nullopt
57+
body ? std::make_optional(jni_utils::JavaByteArrayRef(env, body).get()) : std::nullopt
5858
);
5959
return util::bytes_from_vector(env, bytes);
6060
});
61+
}
62+
63+
extern "C"
64+
JNIEXPORT jobject JNICALL
65+
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15KeyPair(JNIEnv *env,
66+
jobject thiz,
67+
jbyteArray ed25519_secret_key,
68+
jbyteArray server_pub_key) {
69+
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
70+
auto [pk, sk] = session::blind15_key_pair(
71+
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
72+
jni_utils::JavaByteArrayRef(env, server_pub_key).get()
73+
);
74+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
75+
});
76+
}
77+
78+
extern "C"
79+
JNIEXPORT jbyteArray JNICALL
80+
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15Sign(JNIEnv *env, jobject thiz,
81+
jbyteArray ed25519_secret_key,
82+
jstring server_pub_key,
83+
jbyteArray message) {
84+
return jni_utils::run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
85+
auto data = session::blind15_sign(
86+
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
87+
jni_utils::JavaStringRef(env, server_pub_key).view(),
88+
jni_utils::JavaByteArrayRef(env, message).get()
89+
);
90+
return util::bytes_from_vector(env, data);
91+
});
92+
}
93+
94+
extern "C"
95+
JNIEXPORT jboolean JNICALL
96+
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_sessionIdMatchesBlindedId(JNIEnv *env,
97+
jobject thiz,
98+
jstring session_id,
99+
jstring blinded_id,
100+
jstring server_pub_key) {
101+
return jni_utils::run_catching_cxx_exception_or<jboolean>([=]() -> jboolean {
102+
return session::session_id_matches_blinded_id(
103+
jni_utils::JavaStringRef(env, session_id).view(),
104+
jni_utils::JavaStringRef(env, blinded_id).view(),
105+
jni_utils::JavaStringRef(env, server_pub_key).view()
106+
);
107+
}, [](const char *) -> jboolean {
108+
return false;
109+
});
61110
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "jni_utils.h"
2+
3+
#include <session/curve25519.hpp>
4+
5+
extern "C"
6+
JNIEXPORT jobject JNICALL
7+
Java_network_loki_messenger_libsession_1util_Curve25519_fromED25519(JNIEnv *env, jobject thiz,
8+
jbyteArray ed25519_public_key,
9+
jbyteArray ed25519_private_key) {
10+
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
11+
auto pk = session::curve25519::to_curve25519_pubkey(jni_utils::JavaByteArrayRef(env, ed25519_public_key).get());
12+
auto sk = session::curve25519::to_curve25519_seckey(jni_utils::JavaByteArrayRef(env, ed25519_private_key).get());
13+
14+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
15+
});
16+
}
17+
18+
19+
extern "C"
20+
JNIEXPORT jbyteArray JNICALL
21+
Java_network_loki_messenger_libsession_1util_Curve25519_pubKeyFromED25519(JNIEnv *env, jobject thiz,
22+
jbyteArray ed25519_public_key) {
23+
return jni_utils::run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
24+
auto pk = session::curve25519::to_curve25519_pubkey(jni_utils::JavaByteArrayRef(env, ed25519_public_key).get());
25+
return util::bytes_from_span(env, pk);
26+
});
27+
}

library/src/main/cpp/ed25519.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,17 @@ Java_network_loki_messenger_libsession_1util_ED25519_verify(JNIEnv *env, jobject
3030
jni_utils::JavaByteArrayRef(env, message).get()
3131
);
3232
});
33+
}
34+
35+
extern "C"
36+
JNIEXPORT jobject JNICALL
37+
Java_network_loki_messenger_libsession_1util_ED25519_generate(JNIEnv *env, jobject thiz,
38+
jbyteArray seed) {
39+
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
40+
auto [pk, sk] = seed
41+
? session::ed25519::ed25519_key_pair(jni_utils::JavaByteArrayRef(env, seed).get())
42+
: session::ed25519::ed25519_key_pair();
43+
44+
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
45+
});
3346
}

library/src/main/cpp/encryption.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,38 @@ Java_network_loki_messenger_libsession_1util_SessionEncrypt_encryptForBlindedRec
9191

9292
return jni_utils::session_bytes_from_range(env, data);
9393
});
94+
}
95+
96+
extern "C"
97+
JNIEXPORT jobject JNICALL
98+
Java_network_loki_messenger_libsession_1util_SessionEncrypt_decryptPushNotification(JNIEnv *env,
99+
jobject thiz,
100+
jbyteArray message,
101+
jbyteArray secret_key) {
102+
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
103+
auto data = session::decrypt_push_notification(
104+
jni_utils::JavaByteArrayRef(env, message).get(),
105+
jni_utils::JavaByteArrayRef(env, secret_key).get()
106+
);
107+
108+
return jni_utils::session_bytes_from_range(env, data);
109+
});
110+
}
111+
112+
extern "C"
113+
JNIEXPORT jstring JNICALL
114+
Java_network_loki_messenger_libsession_1util_SessionEncrypt_decryptOnsResponse(JNIEnv *env,
115+
jobject thiz,
116+
jstring lowercase_name,
117+
jbyteArray ciphertext,
118+
jbyteArray nonce) {
119+
return jni_utils::run_catching_cxx_exception_or_throws<jstring>(env, [=] {
120+
auto data = session::decrypt_ons_response(
121+
jni_utils::JavaStringRef(env, lowercase_name).view(),
122+
jni_utils::JavaByteArrayRef(env, ciphertext).get(),
123+
nonce ? std::make_optional(jni_utils::JavaByteArrayRef(env, nonce).get()) : std::nullopt
124+
);
125+
126+
return util::jstringFromOptional(env, data);
127+
});
94128
}

library/src/main/cpp/hash.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "jni_utils.h"
2+
3+
#include <session/hash.hpp>
4+
5+
extern "C"
6+
JNIEXPORT void JNICALL
7+
Java_network_loki_messenger_libsession_1util_Hash_hash(JNIEnv *env, jobject thiz,
8+
jbyteArray message,
9+
jbyteArray hashOut,
10+
jbyteArray key) {
11+
jni_utils::run_catching_cxx_exception_or_throws<void>(env, [=] {
12+
session::hash::hash(
13+
jni_utils::JavaByteArrayRef(env, hashOut).get(),
14+
jni_utils::JavaByteArrayRef(env, message).get(),
15+
key ? std::make_optional(jni_utils::JavaByteArrayRef(env, key).get()) : std::nullopt);
16+
});
17+
}

library/src/main/cpp/jni_utils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@ namespace jni_utils {
66
jmethodID constructor = env->GetMethodID(pair_class.get(), "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
77
return env->NewObject(pair_class.get(), constructor, first, second);
88
}
9+
10+
jobject new_key_pair(JNIEnv *env, jbyteArray pubKey, jbyteArray secKey) {
11+
auto kp_class = JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/KeyPair"));
12+
jmethodID kp_constructor = env->GetMethodID(kp_class.get(), "<init>", "([B[B)V");
13+
return env->NewObject(kp_class.get(), kp_constructor, pubKey, secKey);
14+
}
915
}

library/src/main/cpp/jni_utils.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ namespace jni_utils {
146146
*/
147147
jobject new_kotlin_pair(JNIEnv *env, jobject first, jobject second);
148148

149+
/**
150+
* Create a new KeyPair object
151+
*/
152+
jobject new_key_pair(JNIEnv *env, jbyteArray pubKey, jbyteArray secKey);
153+
154+
class JavaStringRef {
155+
JNIEnv *env;
156+
jstring s;
157+
std::span<char> data;
158+
159+
public:
160+
JavaStringRef(JNIEnv *env, jstring s) : env(env), s(s) {
161+
const char *c_str = env->GetStringUTFChars(s, nullptr);
162+
data = std::span<char>(const_cast<char *>(c_str), env->GetStringUTFLength(s));
163+
}
164+
165+
~JavaStringRef() {
166+
env->ReleaseStringUTFChars(s, data.data());
167+
}
168+
169+
// Get the data as a string view. Only valid during the lifetime of this object.
170+
std::string_view view() const {
171+
return std::string_view(data.data(), data.size());
172+
}
173+
174+
// Get the data as a span. Only valid during the lifetime of this object.
175+
std::span<char> get() const {
176+
return data;
177+
}
178+
};
179+
149180
/**
150181
* A RAII wrapper for a Java byte array. This will automatically release the byte array when it goes out of scope.
151182
*/
@@ -164,6 +195,7 @@ namespace jni_utils {
164195
env->ReleaseByteArrayElements(byte_array, reinterpret_cast<jbyte *>(data.data()), 0);
165196
}
166197

198+
// Get the data as a span. Only valid during the lifetime of this object.
167199
std::span<unsigned char> get() const {
168200
return data;
169201
}

library/src/main/cpp/util.cpp

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -173,43 +173,10 @@ namespace util {
173173
}
174174
}
175175

176-
extern "C"
177-
JNIEXPORT jobject JNICALL
178-
Java_network_loki_messenger_libsession_1util_util_Sodium_ed25519KeyPair(JNIEnv *env, jobject thiz, jbyteArray seed) {
179-
std::array<unsigned char, 32> ed_pk; // NOLINT(cppcoreguidelines-pro-type-member-init)
180-
std::array<unsigned char, 64> ed_sk; // NOLINT(cppcoreguidelines-pro-type-member-init)
181-
auto seed_bytes = util::vector_from_bytes(env, seed);
182-
crypto_sign_ed25519_seed_keypair(ed_pk.data(), ed_sk.data(), seed_bytes.data());
183-
184-
auto kp_class = jni_utils::JavaLocalRef(env, env->FindClass("network/loki/messenger/libsession_util/util/KeyPair"));
185-
jmethodID kp_constructor = env->GetMethodID(kp_class.get(), "<init>", "(Lnetwork/loki/messenger/libsession_util/util/Bytes;Lnetwork/loki/messenger/libsession_util/util/Bytes;)V");
186-
187-
return env->NewObject(kp_class.get(), kp_constructor,
188-
jni_utils::JavaLocalRef(env, jni_utils::session_bytes_from_range(env, ed_pk)).get(),
189-
jni_utils::JavaLocalRef(env, jni_utils::session_bytes_from_range(env, ed_sk)).get()
190-
);
191-
}
192-
193-
extern "C"
194-
JNIEXPORT jbyteArray JNICALL
195-
Java_network_loki_messenger_libsession_1util_util_Sodium_ed25519PkToCurve25519(JNIEnv *env,
196-
jobject thiz,
197-
jbyteArray pk) {
198-
auto ed_pk = util::vector_from_bytes(env, pk);
199-
std::array<unsigned char, 32> curve_pk; // NOLINT(cppcoreguidelines-pro-type-member-init)
200-
int success = crypto_sign_ed25519_pk_to_curve25519(curve_pk.data(), ed_pk.data());
201-
if (success != 0) {
202-
jclass exception = env->FindClass("java/lang/Exception");
203-
env->ThrowNew(exception, "Invalid crypto_sign_ed25519_pk_to_curve25519 operation");
204-
return nullptr;
205-
}
206-
jbyteArray curve_pk_jarray = util::bytes_from_span(env, std::span<const unsigned char> {curve_pk.data(), curve_pk.size()});
207-
return curve_pk_jarray;
208-
}
209176

210177
extern "C"
211178
JNIEXPORT jbyteArray JNICALL
212-
Java_network_loki_messenger_libsession_1util_util_Sodium_encryptForMultipleSimple(
179+
Java_network_loki_messenger_libsession_1util_util_MultiEncrypt_encryptForMultipleSimple(
213180
JNIEnv *env, jobject thiz, jobjectArray messages, jobjectArray recipients,
214181
jbyteArray ed25519_secret_key, jstring domain) {
215182
// messages and recipients have to be the same size
@@ -258,12 +225,12 @@ Java_network_loki_messenger_libsession_1util_util_Sodium_encryptForMultipleSimpl
258225

259226
extern "C"
260227
JNIEXPORT jbyteArray JNICALL
261-
Java_network_loki_messenger_libsession_1util_util_Sodium_decryptForMultipleSimple(JNIEnv *env,
262-
jobject thiz,
263-
jbyteArray encoded,
264-
jbyteArray secret_key,
265-
jbyteArray sender_pub_key,
266-
jstring domain) {
228+
Java_network_loki_messenger_libsession_1util_util_MultiEncrypt_decryptForMultipleSimple(JNIEnv *env,
229+
jobject thiz,
230+
jbyteArray encoded,
231+
jbyteArray secret_key,
232+
jbyteArray sender_pub_key,
233+
jstring domain) {
267234
auto sk_vector = util::vector_from_bytes(env, secret_key);
268235
auto encoded_vector = util::vector_from_bytes(env, encoded);
269236
auto pub_vector = util::vector_from_bytes(env, sender_pub_key);

library/src/main/java/network/loki/messenger/libsession_util/Config.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import network.loki.messenger.libsession_util.util.GroupMember
1010
import network.loki.messenger.libsession_util.util.UserPic
1111
import java.io.Closeable
1212

13-
sealed class Config(initialPointer: Long): Closeable {
13+
sealed class Config(initialPointer: Long): Closeable, LibSessionUtilCApi() {
1414
var pointer = initialPointer
1515
private set
1616

0 commit comments

Comments
 (0)