Skip to content

Commit d4898ab

Browse files
SessionHero01SessionHero01
authored andcommitted
Update libsession's protocol encryption API
1 parent 1819ad2 commit d4898ab

File tree

5 files changed

+120
-324
lines changed

5 files changed

+120
-324
lines changed

library/src/main/cpp/jni_utils.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ namespace jni_utils {
8080
}
8181
};
8282

83+
8384
/**
8485
* Create a Java List from an iterator.
8586
*
@@ -225,6 +226,24 @@ namespace jni_utils {
225226
return std::vector(data.begin(), data.end());
226227
}
227228
};
229+
230+
template <size_t N>
231+
static std::optional<std::array<unsigned char, N>> java_to_cpp_array(JNIEnv *env, jbyteArray array) {
232+
if (!array) {
233+
return std::nullopt;
234+
}
235+
236+
JavaByteArrayRef bytes(env, array);
237+
auto span = bytes.get();
238+
if (span.size() != N) {
239+
throw std::runtime_error("Invalid byte array length from java, expecting " + std::to_string(N) + " got " + std::to_string(span.size()));
240+
}
241+
242+
std::array<unsigned char, N> out;
243+
std::copy(span.begin(), span.end(), out.begin());
244+
return out;
245+
}
246+
228247
}
229248

230249
#endif //SESSION_ANDROID_JNI_UTILS_H

library/src/main/cpp/protocol.cpp

Lines changed: 76 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -1,242 +1,35 @@
11
#include <jni.h>
22
#include <session/session_protocol.hpp>
3+
#include <session/sodium_array.hpp>
34

45
#include "jni_utils.h"
56

67
using namespace jni_utils;
78

8-
template <size_t N>
9-
static std::optional<std::array<unsigned char, N>> java_to_cpp_array(JNIEnv *env, jbyteArray array) {
10-
if (!array) {
11-
return std::nullopt;
12-
}
13-
14-
JavaByteArrayRef bytes(env, array);
15-
auto span = bytes.get();
16-
if (span.size() != N) {
17-
throw std::runtime_error("Invalid byte array length from java, expecting " + std::to_string(N) + " got " + std::to_string(span.size()));
18-
}
19-
20-
std::array<unsigned char, N> out;
21-
std::copy(span.begin(), span.end(), out.begin());
22-
return out;
23-
}
24-
25-
extern "C"
26-
JNIEXPORT void JNICALL
27-
Java_network_loki_messenger_libsession_1util_protocol_Destination_00024Contact_toNativeDestination(
28-
JNIEnv *env, jobject thiz, jlong native_ptr) {
29-
auto &dest = *reinterpret_cast<session::Destination *>(native_ptr);
30-
31-
JavaLocalRef clazz(env, env->GetObjectClass(thiz));
32-
33-
JavaLocalRef pub_key(
34-
env,
35-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
36-
thiz,
37-
env->GetMethodID(clazz.get(), "getRecipientPubKey", "()[B"))));
38-
39-
JavaLocalRef sig(
40-
env,
41-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
42-
thiz,
43-
env->GetMethodID(clazz.get(), "getProSignature", "()[B"))));
44-
jlong timestamp = env->CallLongMethod(thiz, env->GetMethodID(clazz.get(), "getSentTimestampMs",
45-
"()J"));
469

47-
run_catching_cxx_exception_or_throws<void>(env, [&] {
48-
dest.type = session::DestinationType::Contact;
49-
dest.pro_sig = java_to_cpp_array<64>(env, sig.get());
50-
dest.recipient_pubkey = java_to_cpp_array<33>(env, pub_key.get()).value();
51-
dest.sent_timestamp_ms = std::chrono::milliseconds{timestamp};
52-
});
53-
}
54-
55-
extern "C"
56-
JNIEXPORT void JNICALL
57-
Java_network_loki_messenger_libsession_1util_protocol_Destination_00024Sync_toNativeDestination(
58-
JNIEnv *env, jobject thiz, jlong native_ptr) {
59-
auto &dest = *reinterpret_cast<session::Destination *>(native_ptr);
60-
61-
JavaLocalRef clazz(env, env->GetObjectClass(thiz));
62-
63-
JavaLocalRef pub_key(
64-
env,
65-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
66-
thiz,
67-
env->GetMethodID(clazz.get(), "getMyPubKey", "()[B"))));
68-
69-
JavaLocalRef sig(
70-
env,
71-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
72-
thiz,
73-
env->GetMethodID(clazz.get(), "getProSignature", "()[B"))));
74-
jlong timestamp = env->CallLongMethod(thiz, env->GetMethodID(clazz.get(), "getSentTimestampMs",
75-
"()J"));
76-
77-
run_catching_cxx_exception_or_throws<void>(env, [&] {
78-
dest.type = session::DestinationType::SyncMessage;
79-
dest.pro_sig = java_to_cpp_array<64>(env, sig.get());
80-
dest.recipient_pubkey = java_to_cpp_array<33>(env, pub_key.get()).value();
81-
dest.sent_timestamp_ms = std::chrono::milliseconds{timestamp};
82-
});
83-
}
84-
85-
extern "C"
86-
JNIEXPORT void JNICALL
87-
Java_network_loki_messenger_libsession_1util_protocol_Destination_00024Group_toNativeDestination(
88-
JNIEnv *env, jobject thiz, jlong native_ptr) {
89-
auto &dest = *reinterpret_cast<session::Destination *>(native_ptr);
90-
91-
JavaLocalRef clazz(env, env->GetObjectClass(thiz));
92-
93-
JavaLocalRef pub_key(
94-
env,
95-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
96-
thiz,
97-
env->GetMethodID(clazz.get(), "getEd25519PubKey", "()[B"))));
98-
99-
JavaLocalRef priv_key(
100-
env,
101-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
102-
thiz,
103-
env->GetMethodID(clazz.get(), "getEd25519PrivKey", "()[B"))));
104-
105-
JavaLocalRef sig(
106-
env,
107-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
108-
thiz,
109-
env->GetMethodID(clazz.get(), "getProSignature", "()[B"))));
110-
111-
jlong timestamp = env->CallLongMethod(thiz, env->GetMethodID(clazz.get(), "getSentTimestampMs",
112-
"()J"));
113-
114-
run_catching_cxx_exception_or_throws<void>(env, [&] {
115-
dest.type = session::DestinationType::Group;
116-
dest.pro_sig = java_to_cpp_array<64>(env, sig.get());
117-
dest.group_ed25519_privkey = java_to_cpp_array<32>(env, priv_key.get()).value();
118-
dest.group_ed25519_pubkey = java_to_cpp_array<33>(env, pub_key.get()).value();
119-
dest.sent_timestamp_ms = std::chrono::milliseconds{timestamp};
120-
});
121-
}
122-
123-
extern "C"
124-
JNIEXPORT void JNICALL
125-
Java_network_loki_messenger_libsession_1util_protocol_Destination_00024Community_toNativeDestination(
126-
JNIEnv *env, jobject thiz, jlong native_ptr) {
127-
auto &dest = *reinterpret_cast<session::Destination *>(native_ptr);
128-
129-
JavaLocalRef clazz(env, env->GetObjectClass(thiz));
130-
JavaLocalRef sig(
131-
env,
132-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
133-
thiz,
134-
env->GetMethodID(clazz.get(), "getProSignature", "()[B"))));
135-
136-
jlong timestamp = env->CallLongMethod(thiz, env->GetMethodID(clazz.get(), "getSentTimestampMs",
137-
"()J"));
138-
139-
run_catching_cxx_exception_or_throws<void>(env, [&] {
140-
dest.type = session::DestinationType::Community;
141-
dest.pro_sig = java_to_cpp_array<64>(env, sig.get());
142-
dest.sent_timestamp_ms = std::chrono::milliseconds{timestamp};
143-
});
144-
}
145-
146-
extern "C"
147-
JNIEXPORT void JNICALL
148-
Java_network_loki_messenger_libsession_1util_protocol_Destination_00024CommunityInbox_toNativeDestination(
149-
JNIEnv *env, jobject thiz, jlong native_ptr) {
150-
auto &dest = *reinterpret_cast<session::Destination *>(native_ptr);
151-
152-
JavaLocalRef clazz(env, env->GetObjectClass(thiz));
153-
154-
JavaLocalRef recipient_pub_key(
155-
env,
156-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
157-
thiz,
158-
env->GetMethodID(clazz.get(), "getRecipientPubKey", "()[B"))));
159-
160-
161-
JavaLocalRef pub_key(
162-
env,
163-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
164-
thiz,
165-
env->GetMethodID(clazz.get(), "getCommunityPubKey", "()[B"))));
166-
167-
JavaLocalRef sig(
168-
env,
169-
reinterpret_cast<jbyteArray>(env->CallObjectMethod(
170-
thiz,
171-
env->GetMethodID(clazz.get(), "getProSignature", "()[B"))));
172-
173-
jlong timestamp = env->CallLongMethod(thiz, env->GetMethodID(clazz.get(), "getSentTimestampMs",
174-
"()J"));
175-
176-
run_catching_cxx_exception_or_throws<void>(env, [&] {
177-
dest.type = session::DestinationType::CommunityInbox;
178-
dest.pro_sig = java_to_cpp_array<64>(env, sig.get());
179-
dest.community_inbox_server_pubkey = java_to_cpp_array<32>(env, pub_key.get()).value();
180-
dest.recipient_pubkey = java_to_cpp_array<33>(env, recipient_pub_key.get()).value();
181-
dest.sent_timestamp_ms = std::chrono::milliseconds{timestamp};
182-
});
183-
}
184-
185-
186-
extern "C"
187-
JNIEXPORT jbyteArray JNICALL
188-
Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_encryptForDestination(
189-
JNIEnv *env,
190-
jobject thiz,
191-
jbyteArray java_message,
192-
jbyteArray java_my_ed25519_privkey,
193-
jobject java_destination,
194-
jint java_namespace) {
195-
session::Destination dest;
196-
auto to_native_method = env->GetMethodID(env->GetObjectClass(java_destination), "toNativeDestination", "(J)V");
197-
env->CallVoidMethod(java_destination, to_native_method, reinterpret_cast<jlong>(&dest));
198-
199-
// Make sure nothing went wrong in toNativeDestination
200-
if (env->ExceptionCheck()) {
201-
return nullptr;
202-
}
203-
204-
return run_catching_cxx_exception_or_throws<jbyteArray>(env, [&] {
205-
auto result = session::encrypt_for_destination(
206-
JavaByteArrayRef(env, java_message).get(),
207-
JavaByteArrayRef(env, java_my_ed25519_privkey).get(),
208-
dest,
209-
static_cast<session::config::Namespace>(java_namespace));
210-
if (result.encrypted) {
211-
return util::bytes_from_vector(env, result.ciphertext);
212-
} else {
213-
return (jbyteArray) nullptr;
214-
}
215-
});
216-
}
21710

21811
static JavaLocalRef<jobject> serializeProStatus(JNIEnv *env, const session::DecryptedEnvelope & envelope) {
21912
if (!envelope.pro.has_value()) {
22013
JavaLocalRef noneClass(env, env->FindClass("network/loki/messenger/libsession_util/protocol/ProStatus$None"));
22114
auto fieldId = env->GetStaticFieldID(
22215
noneClass.get(),
22316
"INSTANCE", "Lnetwork/loki/messenger/libsession_util/protocol/ProStatus$None;");
224-
return JavaLocalRef(env, env->GetStaticObjectField(noneClass.get(), fieldId));
17+
return {env, env->GetStaticObjectField(noneClass.get(), fieldId)};
22518
}
22619

22720
if (envelope.pro->status == session::config::ProStatus::Valid) {
22821
JavaLocalRef validClass(env, env->FindClass("network/loki/messenger/libsession_util/protocol/ProStatus$Valid"));
22922
auto init = env->GetMethodID(validClass.get(), "<init>", "(JJ)V");
230-
return JavaLocalRef(env, env->NewObject(validClass.get(), init,
23+
return {env, env->NewObject(validClass.get(), init,
23124
static_cast<jlong>(envelope.pro->proof.expiry_unix_ts.time_since_epoch().count()),
232-
static_cast<jlong>(envelope.pro->features)));
25+
static_cast<jlong>(envelope.pro->features))};
23326
}
23427

23528
JavaLocalRef invalidClass(env, env->FindClass("network/loki/messenger/libsession_util/protocol/ProStatus$Invalid"));
23629
auto fieldId = env->GetStaticFieldID(
23730
invalidClass.get(),
23831
"INSTANCE", "Lnetwork/loki/messenger/libsession_util/protocol/ProStatus$Invalid;");
239-
return JavaLocalRef(env, env->GetStaticObjectField(invalidClass.get(), fieldId));
32+
return {env, env->GetStaticObjectField(invalidClass.get(), fieldId)};
24033
}
24134

24235
extern "C"
@@ -323,3 +116,74 @@ Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_decryptEnv
323116
});
324117
}
325118

119+
120+
extern "C"
121+
JNIEXPORT jbyteArray JNICALL
122+
Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_encryptFor1o1(JNIEnv *env,
123+
jobject thiz,
124+
jbyteArray plaintext,
125+
jbyteArray my_ed25519_priv_key,
126+
jlong timestamp_ms,
127+
jbyteArray recipient_pub_key,
128+
jbyteArray pro_signature) {
129+
return run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
130+
return util::bytes_from_vector(
131+
env,
132+
session::encrypt_for_1o1(
133+
JavaByteArrayRef(env, plaintext).get(),
134+
JavaByteArrayRef(env, my_ed25519_priv_key).get(),
135+
std::chrono::milliseconds { timestamp_ms },
136+
*java_to_cpp_array<33>(env, recipient_pub_key),
137+
java_to_cpp_array<64>(env, pro_signature)
138+
));
139+
});
140+
}
141+
142+
extern "C"
143+
JNIEXPORT jbyteArray JNICALL
144+
Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_encryptForCommunityInbox(
145+
JNIEnv *env, jobject thiz, jbyteArray plaintext, jbyteArray my_ed25519_priv_key,
146+
jlong timestamp_ms, jbyteArray recipient_pub_key, jbyteArray community_server_pub_key,
147+
jbyteArray pro_signature) {
148+
return run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
149+
return util::bytes_from_vector(
150+
env,
151+
session::encrypt_for_community_inbox(
152+
JavaByteArrayRef(env, plaintext).get(),
153+
JavaByteArrayRef(env, my_ed25519_priv_key).get(),
154+
std::chrono::milliseconds { timestamp_ms },
155+
*java_to_cpp_array<33>(env, recipient_pub_key),
156+
*java_to_cpp_array<32>(env, community_server_pub_key),
157+
java_to_cpp_array<64>(env, pro_signature)
158+
));
159+
});
160+
}
161+
162+
extern "C"
163+
JNIEXPORT jbyteArray JNICALL
164+
Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_encryptForGroup(JNIEnv *env,
165+
jobject thiz,
166+
jbyteArray plaintext,
167+
jbyteArray my_ed25519_priv_key,
168+
jlong timestamp_ms,
169+
jbyteArray group_ed25519_public_key,
170+
jbyteArray group_ed25519_private_key,
171+
jbyteArray pro_signature) {
172+
return run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
173+
session::cleared_uc32 group_private_key;
174+
175+
auto array = *java_to_cpp_array<32>(env, group_ed25519_private_key);
176+
std::copy(array.begin(), array.end(), group_private_key.begin());
177+
178+
return util::bytes_from_vector(
179+
env,
180+
session::encrypt_for_group(
181+
JavaByteArrayRef(env, plaintext).get(),
182+
JavaByteArrayRef(env, my_ed25519_priv_key).get(),
183+
std::chrono::milliseconds { timestamp_ms },
184+
*java_to_cpp_array<33>(env, group_ed25519_public_key),
185+
group_private_key,
186+
java_to_cpp_array<64>(env, pro_signature)
187+
));
188+
});
189+
}

0 commit comments

Comments
 (0)