mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 17:27:42 +00:00
WIP: clean up signal protocol
This commit is contained in:
@@ -6,6 +6,7 @@ import org.session.libsignal.libsignal.ecc.DjbECPublicKey
|
||||
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage
|
||||
import org.session.libsignal.service.loki.utilities.toHexString
|
||||
import org.session.libsignal.utilities.Hex
|
||||
|
||||
@@ -55,10 +56,10 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
||||
const val TAG = "ClosedGroupControlMessage"
|
||||
|
||||
fun fromProto(proto: SignalServiceProtos.Content): ClosedGroupControlMessage? {
|
||||
val closedGroupControlMessageProto = proto.dataMessage?.closedGroupUpdateV2 ?: return null
|
||||
val closedGroupControlMessageProto = proto.dataMessage?.closedGroupControlMessage ?: return null
|
||||
val kind: Kind
|
||||
when(closedGroupControlMessageProto.type) {
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.NEW -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.NEW -> {
|
||||
val publicKey = closedGroupControlMessageProto.publicKey ?: return null
|
||||
val name = closedGroupControlMessageProto.name ?: return null
|
||||
val encryptionKeyPairAsProto = closedGroupControlMessageProto.encryptionKeyPair ?: return null
|
||||
@@ -71,29 +72,31 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.UPDATE -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.UPDATE -> {
|
||||
val name = closedGroupControlMessageProto.name ?: return null
|
||||
kind = Kind.Update(name, closedGroupControlMessageProto.membersList)
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.ENCRYPTION_KEY_PAIR -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR -> {
|
||||
val publicKey = closedGroupControlMessageProto.publicKey
|
||||
val wrappers = closedGroupControlMessageProto.wrappersList.mapNotNull { KeyPairWrapper.fromProto(it) }
|
||||
kind = Kind.EncryptionKeyPair(publicKey, wrappers)
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.NAME_CHANGE -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.NAME_CHANGE -> {
|
||||
val name = closedGroupControlMessageProto.name ?: return null
|
||||
kind = Kind.NameChange(name)
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBERS_ADDED -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.MEMBERS_ADDED -> {
|
||||
kind = Kind.MembersAdded(closedGroupControlMessageProto.membersList)
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBERS_REMOVED -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.MEMBERS_REMOVED -> {
|
||||
kind = Kind.MembersRemoved(closedGroupControlMessageProto.membersList)
|
||||
}
|
||||
SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBER_LEFT -> {
|
||||
DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT -> {
|
||||
kind = Kind.MemberLeft
|
||||
}
|
||||
//TODO: SignalServiceProtos.ClosedGroupUpdateV2.Type.ENCRYPTION_KEY_PAIR_REQUEST
|
||||
DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR_REQUEST -> {
|
||||
kind = Kind.EncryptionKeyPairRequest
|
||||
}
|
||||
}
|
||||
return ClosedGroupControlMessage(kind)
|
||||
}
|
||||
@@ -130,10 +133,10 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
val closedGroupControlMessage: SignalServiceProtos.ClosedGroupUpdateV2.Builder = SignalServiceProtos.ClosedGroupUpdateV2.newBuilder()
|
||||
val closedGroupControlMessage: DataMessage.ClosedGroupControlMessage.Builder = DataMessage.ClosedGroupControlMessage.newBuilder()
|
||||
when (kind) {
|
||||
is Kind.New -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.NEW
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.NEW
|
||||
closedGroupControlMessage.publicKey = kind.publicKey
|
||||
closedGroupControlMessage.name = kind.name
|
||||
val encryptionKeyPairAsProto = SignalServiceProtos.KeyPair.newBuilder()
|
||||
@@ -150,37 +153,37 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
||||
closedGroupControlMessage.addAllAdmins(kind.admins)
|
||||
}
|
||||
is Kind.Update -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.UPDATE
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.UPDATE
|
||||
closedGroupControlMessage.name = kind.name
|
||||
closedGroupControlMessage.addAllMembers(kind.members)
|
||||
}
|
||||
is Kind.EncryptionKeyPair -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.ENCRYPTION_KEY_PAIR
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR
|
||||
closedGroupControlMessage.publicKey = kind.publicKey
|
||||
closedGroupControlMessage.addAllWrappers(kind.wrappers.map { it.toProto() })
|
||||
}
|
||||
is Kind.NameChange -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.NAME_CHANGE
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.NAME_CHANGE
|
||||
closedGroupControlMessage.name = kind.name
|
||||
}
|
||||
is Kind.MembersAdded -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBERS_ADDED
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.MEMBERS_ADDED
|
||||
closedGroupControlMessage.addAllMembers(kind.members)
|
||||
}
|
||||
is Kind.MembersRemoved -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBERS_REMOVED
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.MEMBERS_REMOVED
|
||||
closedGroupControlMessage.addAllMembers(kind.members)
|
||||
}
|
||||
is Kind.MemberLeft -> {
|
||||
closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.MEMBER_LEFT
|
||||
closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT
|
||||
}
|
||||
is Kind.EncryptionKeyPairRequest -> {
|
||||
// TODO: closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.ENCRYPTION_KEY_PAIR_REQUEST
|
||||
}
|
||||
}
|
||||
val contentProto = SignalServiceProtos.Content.newBuilder()
|
||||
val dataMessageProto = SignalServiceProtos.DataMessage.newBuilder()
|
||||
dataMessageProto.closedGroupUpdateV2 = closedGroupControlMessage.build()
|
||||
val dataMessageProto = DataMessage.newBuilder()
|
||||
dataMessageProto.closedGroupControlMessage = closedGroupControlMessage.build()
|
||||
// Group context
|
||||
contentProto.dataMessage = dataMessageProto.build()
|
||||
return contentProto.build()
|
||||
@@ -197,15 +200,15 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromProto(proto: SignalServiceProtos.ClosedGroupUpdateV2.KeyPairWrapper): KeyPairWrapper {
|
||||
fun fromProto(proto: DataMessage.ClosedGroupControlMessage.KeyPairWrapper): KeyPairWrapper {
|
||||
return KeyPairWrapper(proto.publicKey.toByteArray().toHexString(), proto.encryptedKeyPair)
|
||||
}
|
||||
}
|
||||
|
||||
fun toProto(): SignalServiceProtos.ClosedGroupUpdateV2.KeyPairWrapper? {
|
||||
fun toProto(): DataMessage.ClosedGroupControlMessage.KeyPairWrapper? {
|
||||
val publicKey = publicKey ?: return null
|
||||
val encryptedKeyPair = encryptedKeyPair ?: return null
|
||||
val result = SignalServiceProtos.ClosedGroupUpdateV2.KeyPairWrapper.newBuilder()
|
||||
val result = DataMessage.ClosedGroupControlMessage.KeyPairWrapper.newBuilder()
|
||||
result.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(publicKey))
|
||||
result.encryptedKeyPair = encryptedKeyPair
|
||||
|
||||
|
@@ -1,35 +0,0 @@
|
||||
package org.session.libsession.messaging.messages.control.unused
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.messaging.messages.control.ControlMessage
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import java.security.SecureRandom
|
||||
|
||||
class NullMessage() : ControlMessage() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "NullMessage"
|
||||
|
||||
fun fromProto(proto: SignalServiceProtos.Content): NullMessage? {
|
||||
if (proto.nullMessage == null) return null
|
||||
return NullMessage()
|
||||
}
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.Content? {
|
||||
val nullMessageProto = SignalServiceProtos.NullMessage.newBuilder()
|
||||
val sr = SecureRandom()
|
||||
val paddingSize = sr.nextInt(512)
|
||||
val padding = ByteArray(paddingSize)
|
||||
nullMessageProto.padding = ByteString.copyFrom(padding)
|
||||
val contentProto = SignalServiceProtos.Content.newBuilder()
|
||||
try {
|
||||
contentProto.nullMessage = nullMessageProto.build()
|
||||
return contentProto.build()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Couldn't construct null message proto from: $this")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,83 +0,0 @@
|
||||
package org.session.libsession.messaging.messages.control.unused
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.messaging.MessagingConfiguration
|
||||
import org.session.libsession.messaging.messages.control.ControlMessage
|
||||
import org.session.libsignal.libsignal.IdentityKey
|
||||
import org.session.libsignal.libsignal.ecc.DjbECPublicKey
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.session.libsignal.libsignal.state.PreKeyBundle
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import java.security.SecureRandom
|
||||
|
||||
class SessionRequest() : ControlMessage() {
|
||||
|
||||
var preKeyBundle: PreKeyBundle? = null
|
||||
|
||||
companion object {
|
||||
const val TAG = "SessionRequest"
|
||||
|
||||
fun fromProto(proto: SignalServiceProtos.Content): SessionRequest? {
|
||||
if (proto.nullMessage == null) return null
|
||||
val preKeyBundleProto = proto.preKeyBundleMessage ?: return null
|
||||
var registrationID: Int = 0
|
||||
registrationID = MessagingConfiguration.shared.storage.getOrGenerateRegistrationID() //TODO no implementation for getOrGenerateRegistrationID yet
|
||||
//TODO just confirm if the above code does the equivalent to swift below:
|
||||
/*iOS code: Configuration.shared.storage.with { transaction in
|
||||
registrationID = Configuration.shared.storage.getOrGenerateRegistrationID(using: transaction)
|
||||
}*/
|
||||
val preKeyBundle = PreKeyBundle(
|
||||
registrationID,
|
||||
1,
|
||||
preKeyBundleProto.preKeyId,
|
||||
DjbECPublicKey(preKeyBundleProto.preKey.toByteArray()),
|
||||
preKeyBundleProto.signedKeyId,
|
||||
DjbECPublicKey(preKeyBundleProto.signedKey.toByteArray()),
|
||||
preKeyBundleProto.signature.toByteArray(),
|
||||
IdentityKey(DjbECPublicKey(preKeyBundleProto.identityKey.toByteArray()))
|
||||
)
|
||||
return SessionRequest(preKeyBundle)
|
||||
}
|
||||
}
|
||||
|
||||
//constructor
|
||||
internal constructor(preKeyBundle: PreKeyBundle) : this() {
|
||||
this.preKeyBundle = preKeyBundle
|
||||
}
|
||||
|
||||
// validation
|
||||
override fun isValid(): Boolean {
|
||||
if (!super.isValid()) return false
|
||||
return preKeyBundle != null
|
||||
}
|
||||
|
||||
override fun toProto(): SignalServiceProtos.Content? {
|
||||
val preKeyBundle = preKeyBundle
|
||||
if (preKeyBundle == null) {
|
||||
Log.w(TAG, "Couldn't construct session request proto from: $this")
|
||||
return null
|
||||
}
|
||||
val nullMessageProto = SignalServiceProtos.NullMessage.newBuilder()
|
||||
val sr = SecureRandom()
|
||||
val paddingSize = sr.nextInt(512)
|
||||
val padding = ByteArray(paddingSize)
|
||||
nullMessageProto.padding = ByteString.copyFrom(padding)
|
||||
val preKeyBundleProto = SignalServiceProtos.PreKeyBundleMessage.newBuilder()
|
||||
preKeyBundleProto.identityKey = ByteString.copyFrom(preKeyBundle.identityKey.publicKey.serialize())
|
||||
preKeyBundleProto.deviceId = preKeyBundle.deviceId
|
||||
preKeyBundleProto.preKeyId = preKeyBundle.preKeyId
|
||||
preKeyBundleProto.preKey = ByteString.copyFrom(preKeyBundle.preKey.serialize())
|
||||
preKeyBundleProto.signedKeyId = preKeyBundle.signedPreKeyId
|
||||
preKeyBundleProto.signedKey = ByteString.copyFrom(preKeyBundle.signedPreKey.serialize())
|
||||
preKeyBundleProto.signature = ByteString.copyFrom(preKeyBundle.signedPreKeySignature)
|
||||
val contentProto = SignalServiceProtos.Content.newBuilder()
|
||||
try {
|
||||
contentProto.nullMessage = nullMessageProto.build()
|
||||
contentProto.preKeyBundleMessage = preKeyBundleProto.build()
|
||||
return contentProto.build()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Couldn't construct session request proto from: $this")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@ class Profile() {
|
||||
val profileProto = proto.profile ?: return null
|
||||
val displayName = profileProto.displayName ?: return null
|
||||
val profileKey = proto.profileKey
|
||||
val profilePictureURL = profileProto.profilePictureURL
|
||||
val profilePictureURL = profileProto.profilePicture
|
||||
profileKey?.let {
|
||||
profilePictureURL?.let {
|
||||
return Profile(displayName = displayName, profileKey = profileKey.toByteArray(), profilePictureURL = profilePictureURL)
|
||||
@@ -41,12 +41,12 @@ class Profile() {
|
||||
return null
|
||||
}
|
||||
val dataMessageProto = SignalServiceProtos.DataMessage.newBuilder()
|
||||
val profileProto = SignalServiceProtos.LokiUserProfile.newBuilder()
|
||||
val profileProto = SignalServiceProtos.DataMessage.LokiProfile.newBuilder()
|
||||
profileProto.displayName = displayName
|
||||
val profileKey = profileKey
|
||||
profileKey?.let { dataMessageProto.profileKey = ByteString.copyFrom(profileKey) }
|
||||
val profilePictureURL = profilePictureURL
|
||||
profilePictureURL?.let { profileProto.profilePictureURL = profilePictureURL }
|
||||
profilePictureURL?.let { profileProto.profilePicture = profilePictureURL }
|
||||
// Build
|
||||
try {
|
||||
dataMessageProto.profile = profileProto.build()
|
||||
|
@@ -162,11 +162,11 @@ class OpenGroupPoller(private val openGroup: OpenGroup) {
|
||||
}
|
||||
val messageServerID = message.serverID
|
||||
// Profile
|
||||
val profileProto = LokiUserProfile.newBuilder()
|
||||
val profileProto = DataMessage.LokiProfile.newBuilder()
|
||||
profileProto.setDisplayName(message.displayName)
|
||||
val profilePicture = message.profilePicture
|
||||
if (profilePicture != null) {
|
||||
profileProto.setProfilePictureURL(profilePicture.url)
|
||||
profileProto.setProfilePicture(profilePicture.url)
|
||||
dataMessageProto.setProfileKey(ByteString.copyFrom(profilePicture.profileKey))
|
||||
}
|
||||
dataMessageProto.setProfile(profileProto.build())
|
||||
|
Reference in New Issue
Block a user