Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions library/src/main/cpp/contacts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static JavaLocalRef<jobject> serialize_contact(JNIEnv *env, const session::confi
(jlong) (info.profile_updated.time_since_epoch().count()),
(jlong) info.priority,
util::serialize_expiry(env, info.exp_mode, info.exp_timer).get(),
(jlong) info.pro_features);
(jlong) info.profile_bitset.data);
return {env, returnObj};
}

Expand Down Expand Up @@ -92,7 +92,9 @@ session::config::contact_info deserialize_contact(JNIEnv *env, jobject info, ses
contact_info.priority = env->CallLongMethod(info, class_info.get_priority);
contact_info.exp_mode = expiry_pair.first;
contact_info.exp_timer = std::chrono::seconds(expiry_pair.second);
contact_info.pro_features = env->CallLongMethod(info, class_info.get_pro_features);
contact_info.profile_bitset = {
.data = static_cast<uint64_t>(env->CallLongMethod(info, class_info.get_pro_features))
};

return contact_info;
}
Expand Down Expand Up @@ -172,7 +174,7 @@ JavaLocalRef<jobject> serialize_blinded_contact(JNIEnv *env, const session::conf
(jlong) (info.profile_updated.time_since_epoch().count()),
util::serialize_user_pic(env, info.profile_picture).get(),
(jlong) info.priority,
(jlong) info.pro_features
(jlong) info.profile_bitset.data
)};
}

Expand All @@ -196,7 +198,7 @@ session::config::blinded_contact_info deserialize_blinded_contact(JNIEnv *env, j
, name_getter(env->GetMethodID(java_class, "getName", "()Ljava/lang/String;"))
, created_epoch_seconds_getter(env->GetMethodID(java_class, "getCreatedEpochSeconds", "()J"))
, profile_updated_epoch_seconds_getter(env->GetMethodID(java_class, "getProfileUpdatedEpochSeconds", "()J"))
, profile_pic_getter(env->GetMethodID(java_class, "getProfilePicture", "()Lnetwork/loki/messenger/libsession_util/util/UserPic;"))
, profile_pic_getter(env->GetMethodID(java_class, "getProfilePic", "()Lnetwork/loki/messenger/libsession_util/util/UserPic;"))
, priority_getter(env->GetMethodID(java_class, "getPriority", "()J"))
, pro_features_getter(env->GetMethodID(java_class, "getProFeaturesRaw", "()J")) {}
};
Expand All @@ -219,7 +221,9 @@ session::config::blinded_contact_info deserialize_blinded_contact(JNIEnv *env, j
info.name = JavaStringRef(env, JavaLocalRef(env, (jstring) env->CallObjectMethod(jInfo, class_info.name_getter)).get()).view();
info.profile_updated = std::chrono::sys_seconds{std::chrono::seconds{env->CallLongMethod(jInfo, class_info.profile_updated_epoch_seconds_getter)}};
info.priority = env->CallLongMethod(jInfo, class_info.priority_getter);
info.pro_features = env->CallLongMethod(jInfo, class_info.pro_features_getter);
info.profile_bitset = {
.data = static_cast<uint64_t>(env->CallLongMethod(jInfo, class_info.pro_features_getter))
};

return info;
}
Expand Down
46 changes: 25 additions & 21 deletions library/src/main/cpp/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,20 @@

using namespace jni_utils;

static JavaLocalRef<jobject> serializeDecodedPro(JNIEnv *env, const session::DecodedPro &pro) {
static BasicJavaClassInfo class_info(
env,
"network/loki/messenger/libsession_util/protocol/DecodedPro",
"(ILnetwork/loki/messenger/libsession_util/pro/ProProof;JJ)V"
);

return {env, env->NewObject(class_info.java_class, class_info.constructor,
static_cast<jint>(pro.status),
cpp_to_java_proof(env, pro.proof).get(),
static_cast<jlong>(pro.msg_bitset.data),
static_cast<jlong>(pro.profile_bitset.data))
};
}

static JavaLocalRef<jobject> serializeEnvelop(JNIEnv *env, const session::Envelope &envelope) {
static BasicJavaClassInfo class_info(
Expand All @@ -32,7 +45,7 @@ static JavaLocalRef<jobject> serializeDecodedEnvelope(JNIEnv *env, const session
static BasicJavaClassInfo class_info(
env,
"network/loki/messenger/libsession_util/protocol/DecodedEnvelope",
"(Lnetwork/loki/messenger/libsession_util/protocol/Envelope;ILnetwork/loki/messenger/libsession_util/pro/ProProof;J[B[B[BJ)V"
"(Lnetwork/loki/messenger/libsession_util/protocol/Envelope;Lnetwork/loki/messenger/libsession_util/protocol/DecodedPro;[B[B[BJ)V"
);

JavaLocalRef sender_ed25519 = util::bytes_from_span(env, envelop.sender_ed25519_pubkey);
Expand All @@ -41,10 +54,7 @@ static JavaLocalRef<jobject> serializeDecodedEnvelope(JNIEnv *env, const session

return {env, env->NewObject(class_info.java_class, class_info.constructor,
serializeEnvelop(env, envelop.envelope).get(),
envelop.pro ? static_cast<jint>(envelop.pro->status)
: static_cast<jint>(-1),
envelop.pro ? cpp_to_java_proof(env, envelop.pro->proof).get() : nullptr,
static_cast<jlong>(envelop.pro ? envelop.pro->features : 0),
envelop.pro ? nullptr : serializeDecodedPro(env, *envelop.pro).get(),
content.get(),
sender_ed25519.get(),
sender_x25519.get(),
Expand Down Expand Up @@ -144,21 +154,16 @@ Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_decodeForC
*java_to_cpp_array<32>(env, pro_backend_pub_key)
);

JavaLocalRef envelopClass(env, env->FindClass(
"network/loki/messenger/libsession_util/protocol/DecodedCommunityMessage"));
jmethodID init = env->GetMethodID(
envelopClass.get(),
"<init>",
"(ILnetwork/loki/messenger/libsession_util/pro/ProProof;J[B)V"
static BasicJavaClassInfo class_info(
env,
"network/loki/messenger/libsession_util/protocol/DecodedCommunityMessage",
"(Lnetwork/loki/messenger/libsession_util/protocol/DecodedPro;[B)V"
);

return env->NewObject(
envelopClass.get(),
init,
decoded.pro ? static_cast<jint>(decoded.pro->status)
: static_cast<jint>(-1),
decoded.pro ? cpp_to_java_proof(env, decoded.pro->proof).get() : nullptr,
static_cast<jlong>(decoded.pro ? decoded.pro->features : 0),
class_info.java_class,
class_info.constructor,
decoded.pro ? serializeDecodedPro(env, *decoded.pro).get() : nullptr,
util::bytes_from_vector(env, decoded.content_plaintext).get()
);
});
Expand Down Expand Up @@ -250,14 +255,13 @@ Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_decodeForG
extern "C"
JNIEXPORT jobject JNICALL
Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_proFeaturesForMessage(
JNIEnv *env, jobject thiz, jstring message_body, jlong proposed_features) {
JNIEnv *env, jobject thiz, jstring message_body) {
return run_catching_cxx_exception_or_throws<jobject>(env, [=] {
JavaCharsRef message_ref(env, message_body);

auto features = session::pro_features_for_utf16(
reinterpret_cast<const char16_t *>(message_ref.chars()),
message_ref.size(),
static_cast<SESSION_PROTOCOL_PRO_FEATURES>(proposed_features)
message_ref.size()
);

static BasicJavaClassInfo class_info(
Expand All @@ -271,7 +275,7 @@ Java_network_loki_messenger_libsession_1util_protocol_SessionProtocol_proFeature
class_info.constructor,
static_cast<jint>(features.status),
features.error.empty() ? nullptr : env->NewStringUTF(std::string(features.error).c_str()),
static_cast<jlong>(features.features),
static_cast<jlong>(features.bitset.data),
static_cast<jint>(features.codepoint_count)
);
});
Expand Down
2 changes: 1 addition & 1 deletion library/src/main/cpp/user_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ extern "C"
JNIEXPORT jlong JNICALL
Java_network_loki_messenger_libsession_1util_UserProfile_getProFeaturesRaw(JNIEnv *env,
jobject thiz) {
return static_cast<jlong>(ptrToProfile(env, thiz)->get_pro_features());
return static_cast<jlong>(ptrToProfile(env, thiz)->get_profile_bitset().data);
}

extern "C"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package network.loki.messenger.libsession_util

import network.loki.messenger.libsession_util.pro.ProConfig
import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProProfileFeatures
import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import network.loki.messenger.libsession_util.util.BlindedContact
import network.loki.messenger.libsession_util.util.ConfigPush
Expand All @@ -12,7 +11,6 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
import network.loki.messenger.libsession_util.util.GroupInfo
import network.loki.messenger.libsession_util.util.GroupMember
import network.loki.messenger.libsession_util.util.UserPic
import java.time.Instant

typealias ConversationPriority = Long

Expand Down Expand Up @@ -85,7 +83,7 @@ interface ReadableUserProfile: ReadableConfig {
fun getCommunityMessageRequests(): Boolean
fun isBlockCommunityMessageRequestsSet(): Boolean

fun getProFeatures(): ProFeatures
fun getProFeatures(): ProProfileFeatures
fun getProConfig(): ProConfig?
fun getProAccessExpiryMs(): Long?
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package network.loki.messenger.libsession_util

import network.loki.messenger.libsession_util.pro.ProConfig
import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProProfileFeatures
import network.loki.messenger.libsession_util.util.ExpiryMode
import network.loki.messenger.libsession_util.util.UserPic

Expand Down Expand Up @@ -48,7 +48,7 @@ class UserProfile private constructor(pointer: Long) : ConfigBase(pointer), Muta
external override fun setProAccessExpiryMs(epochMills: Long)
external override fun removeProAccessExpiry()
private external fun getProFeaturesRaw(): Long
override fun getProFeatures(): ProFeatures = ProFeatures(getProFeaturesRaw())
override fun getProFeatures(): ProProfileFeatures = ProProfileFeatures(getProFeaturesRaw())
external override fun getProConfig(): ProConfig?

private external fun getProAccessExpiryMsOrZero(): Long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.time.Instant

typealias ProProofStatus = Int

/**
* Represents a proof of Pro. This class is marked as @Serializable to represent the JSON structure
* received from the Pro Backend.
Expand Down Expand Up @@ -51,24 +53,6 @@ data class ProProof(
}
}

enum class Status(internal val nativeValue: Int) {
InvalidProBackendSignature(1),
InvalidUserSignature(2),
Valid(3),
Expired(4),

;
companion object {
internal fun fromNativeValue(value: Int): Status {
return entries.first { it.nativeValue == value }
}

internal fun fromNativeValueOrNull(value: Int): Status? {
return entries.firstOrNull { it.nativeValue == value }
}
}
}

class ProSignedMessage(
val data: ByteArray,
val signature: ByteArray,
Expand All @@ -85,17 +69,15 @@ data class ProProof(
senderED25519PubKey: ByteArray,
now: Instant,
signedMessage: ProSignedMessage? = null,
): Status {
): ProProofStatus {
val signedMessageData = signedMessage?.data
val signedMessageSignature = signedMessage?.signature
val statusValue = nativeStatus(
return nativeStatus(
nowUnixTs = now.toEpochMilli(),
verifyPubKey = senderED25519PubKey,
signedMessageData = signedMessageData,
signedMessageSignature = signedMessageSignature
)

return Status.fromNativeValue(statusValue)
}

private external fun nativeStatus(
Expand All @@ -104,4 +86,11 @@ data class ProProof(
signedMessageData: ByteArray?,
signedMessageSignature: ByteArray?
): Int

companion object {
const val STATUS_INVALID_PRO_BACKEND_SIGNATURE: ProProofStatus = 1
const val STATUS_INVALID_USER_SIGNATURE: ProProofStatus = 2
const val STATUS_VALID: ProProofStatus = 3
const val STATUS_EXPIRED: ProProofStatus = 4
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
package network.loki.messenger.libsession_util.protocol

import androidx.annotation.Keep
import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.util.Bytes
import java.util.EnumSet

data class DecodedCommunityMessage(
val proStatus: ProProof.Status?,
val proProof: ProProof?,
val proFeatures: ProFeatures,
val decodedPro: DecodedPro?,
val contentPlainText: Bytes,
) {
@Keep
constructor(
status: Int,
proProof: ProProof?,
proFeatures: Long,
decodedPro: DecodedPro?,
contentPlainText: ByteArray,
): this(
proStatus = ProProof.Status.fromNativeValueOrNull(status),
proProof = proProof,
proFeatures = ProFeatures(proFeatures),
decodedPro = decodedPro,
contentPlainText = Bytes(contentPlainText),
)

init {
check(proProof == null || proStatus in EnumSet.of(ProProof.Status.Expired, ProProof.Status.Valid)) {
"proProof must be null unless proStatus is Expired or Valid"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
package network.loki.messenger.libsession_util.protocol

import androidx.annotation.Keep
import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.util.Bytes
import java.time.Instant
import java.util.EnumSet

data class DecodedEnvelope(
val envelope: Envelope,
val proStatus: ProProof.Status?,
val proProof: ProProof?,
val proFeatures: ProFeatures,
val decodedPro: DecodedPro?,
val contentPlainText: Bytes,
val senderEd25519PubKey: Bytes,
val senderX25519PubKey: Bytes,
Expand All @@ -19,27 +15,17 @@ data class DecodedEnvelope(
@Keep
constructor(
envelope: Envelope,
proStatus: Int,
proProof: ProProof?,
proFeatures: Long,
decodedPro: DecodedPro?,
contentPlainText: ByteArray,
senderEd25519PubKey: ByteArray,
senderX25519PubKey: ByteArray,
timestampEpochMills: Long
): this(
envelope = envelope,
proStatus = ProProof.Status.fromNativeValueOrNull(proStatus),
proProof = proProof,
proFeatures = ProFeatures(proFeatures),
contentPlainText = Bytes(contentPlainText),
senderEd25519PubKey = Bytes(senderEd25519PubKey),
senderX25519PubKey = Bytes(senderX25519PubKey),
timestamp = Instant.ofEpochMilli(timestampEpochMills)
timestamp = Instant.ofEpochMilli(timestampEpochMills),
decodedPro = decodedPro
)

init {
check(proProof == null || proStatus in EnumSet.of(ProProof.Status.Expired, ProProof.Status.Valid)) {
"proProof must be null unless proStatus is Expired or Valid"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package network.loki.messenger.libsession_util.protocol

import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.pro.ProProofStatus

data class DecodedPro(
val status: ProProofStatus,
val proof: ProProof?,
val proMessageFeatures: ProMessageFeatures,
val proProfileFeatures: ProProfileFeatures,
)
Loading