mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 09:33:39 +00:00
Message validation refactor
This commit is contained in:
parent
edb4f96f0a
commit
bb50182a18
@ -359,7 +359,7 @@ object OpenGroupApi {
|
|||||||
room: String,
|
room: String,
|
||||||
server: String
|
server: String
|
||||||
): Promise<OpenGroupMessage, Exception> {
|
): Promise<OpenGroupMessage, Exception> {
|
||||||
val signedMessage = message.sign() ?: return Promise.ofFail(Error.SigningFailed)
|
val signedMessage = message.sign(room, server, fallbackSigningType = IdPrefix.STANDARD) ?: return Promise.ofFail(Error.SigningFailed)
|
||||||
val jsonMessage = signedMessage.toJSON()
|
val jsonMessage = signedMessage.toJSON()
|
||||||
val request = Request(
|
val request = Request(
|
||||||
verb = POST,
|
verb = POST,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package org.session.libsession.messaging.open_groups
|
package org.session.libsession.messaging.open_groups
|
||||||
|
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
|
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||||
import org.session.libsignal.crypto.PushTransportDetails
|
import org.session.libsignal.crypto.PushTransportDetails
|
||||||
import org.session.libsignal.protos.SignalServiceProtos
|
import org.session.libsignal.protos.SignalServiceProtos
|
||||||
import org.session.libsignal.utilities.Base64
|
import org.session.libsignal.utilities.Base64
|
||||||
import org.session.libsignal.utilities.Base64.decode
|
import org.session.libsignal.utilities.Base64.decode
|
||||||
|
import org.session.libsignal.utilities.IdPrefix
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import org.session.libsignal.utilities.toHexString
|
import org.session.libsignal.utilities.toHexString
|
||||||
import org.whispersystems.curve25519.Curve25519
|
import org.whispersystems.curve25519.Curve25519
|
||||||
@ -29,30 +31,47 @@ data class OpenGroupMessage(
|
|||||||
|
|
||||||
fun fromJSON(json: Map<String, Any>): OpenGroupMessage? {
|
fun fromJSON(json: Map<String, Any>): OpenGroupMessage? {
|
||||||
val base64EncodedData = json["data"] as? String ?: return null
|
val base64EncodedData = json["data"] as? String ?: return null
|
||||||
val sentTimestamp = json["posted"] as? Long ?: return null
|
val sentTimestamp = json["posted"] as? Double ?: return null
|
||||||
val serverID = json["id"] as? Int
|
val serverID = json["id"] as? Int
|
||||||
val sender = json["session_id"] as? String
|
val sender = json["session_id"] as? String
|
||||||
val base64EncodedSignature = json["signature"] as? String
|
val base64EncodedSignature = json["signature"] as? String
|
||||||
return OpenGroupMessage(
|
return OpenGroupMessage(
|
||||||
serverID = serverID?.toLong(),
|
serverID = serverID?.toLong(),
|
||||||
sender = sender,
|
sender = sender,
|
||||||
sentTimestamp = sentTimestamp,
|
sentTimestamp = (sentTimestamp * 1000).toLong(),
|
||||||
base64EncodedData = base64EncodedData,
|
base64EncodedData = base64EncodedData,
|
||||||
base64EncodedSignature = base64EncodedSignature
|
base64EncodedSignature = base64EncodedSignature
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sign(): OpenGroupMessage? {
|
fun sign(room: String, server: String, fallbackSigningType: IdPrefix): OpenGroupMessage? {
|
||||||
if (base64EncodedData.isEmpty()) return null
|
if (base64EncodedData.isEmpty()) return null
|
||||||
val (publicKey, privateKey) = MessagingModuleConfiguration.shared.storage.getUserX25519KeyPair().let { it.publicKey to it.privateKey }
|
val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: return null
|
||||||
if (sender != publicKey.serialize().toHexString()) return null
|
val openGroup = MessagingModuleConfiguration.shared.storage.getOpenGroup(room, server) ?: return null
|
||||||
val signature = try {
|
val signature = when {
|
||||||
curve.calculateSignature(privateKey.serialize(), decode(base64EncodedData))
|
openGroup.capabilities.contains("blind") -> {
|
||||||
} catch (e: Exception) {
|
val blindedKeyPair = SodiumUtilities.blindedKeyPair(openGroup.publicKey, userEdKeyPair) ?: return null
|
||||||
Log.w("Loki", "Couldn't sign open group message.", e)
|
SodiumUtilities.sogsSignature(
|
||||||
return null
|
decode(base64EncodedData),
|
||||||
|
userEdKeyPair.secretKey.asBytes,
|
||||||
|
blindedKeyPair.secretKey.asBytes,
|
||||||
|
blindedKeyPair.publicKey.asBytes
|
||||||
|
) ?: return null
|
||||||
|
}
|
||||||
|
fallbackSigningType == IdPrefix.UN_BLINDED -> {
|
||||||
|
curve.calculateSignature(userEdKeyPair.secretKey.asBytes, decode(base64EncodedData))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val (publicKey, privateKey) = MessagingModuleConfiguration.shared.storage.getUserX25519KeyPair().let { it.publicKey to it.privateKey }
|
||||||
|
if (sender != publicKey.serialize().toHexString()) return null
|
||||||
|
try {
|
||||||
|
curve.calculateSignature(privateKey.serialize(), decode(base64EncodedData))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w("Loki", "Couldn't sign open group message.", e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return copy(base64EncodedSignature = Base64.encodeBytes(signature))
|
return copy(base64EncodedSignature = Base64.encodeBytes(signature))
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ import com.goterl.lazysodium.interfaces.Sign
|
|||||||
import org.session.libsession.messaging.utilities.SessionId
|
import org.session.libsession.messaging.utilities.SessionId
|
||||||
import org.session.libsignal.crypto.ecc.ECKeyPair
|
import org.session.libsignal.crypto.ecc.ECKeyPair
|
||||||
import org.session.libsignal.utilities.Hex
|
import org.session.libsignal.utilities.Hex
|
||||||
|
import org.session.libsignal.utilities.IdPrefix
|
||||||
import org.session.libsignal.utilities.hexEncodedPublicKey
|
import org.session.libsignal.utilities.hexEncodedPublicKey
|
||||||
import org.session.libsignal.utilities.removing05PrefixIfNeeded
|
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
|
||||||
import org.session.libsignal.utilities.toHexString
|
|
||||||
|
|
||||||
object MessageDecrypter {
|
object MessageDecrypter {
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ object MessageDecrypter {
|
|||||||
*/
|
*/
|
||||||
public fun decrypt(ciphertext: ByteArray, x25519KeyPair: ECKeyPair): Pair<ByteArray, String> {
|
public fun decrypt(ciphertext: ByteArray, x25519KeyPair: ECKeyPair): Pair<ByteArray, String> {
|
||||||
val recipientX25519PrivateKey = x25519KeyPair.privateKey.serialize()
|
val recipientX25519PrivateKey = x25519KeyPair.privateKey.serialize()
|
||||||
val recipientX25519PublicKey = Hex.fromStringCondensed(x25519KeyPair.hexEncodedPublicKey.removing05PrefixIfNeeded())
|
val recipientX25519PublicKey = Hex.fromStringCondensed(x25519KeyPair.hexEncodedPublicKey.removingIdPrefixIfNeeded())
|
||||||
val signatureSize = Sign.BYTES
|
val signatureSize = Sign.BYTES
|
||||||
val ed25519PublicKeySize = Sign.PUBLICKEYBYTES
|
val ed25519PublicKeySize = Sign.PUBLICKEYBYTES
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import org.session.libsession.messaging.MessagingModuleConfiguration
|
|||||||
import org.session.libsession.messaging.sending_receiving.MessageSender.Error
|
import org.session.libsession.messaging.sending_receiving.MessageSender.Error
|
||||||
import org.session.libsignal.utilities.Hex
|
import org.session.libsignal.utilities.Hex
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import org.session.libsignal.utilities.removing05PrefixIfNeeded
|
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
|
||||||
|
|
||||||
object MessageEncrypter {
|
object MessageEncrypter {
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ object MessageEncrypter {
|
|||||||
*/
|
*/
|
||||||
internal fun encrypt(plaintext: ByteArray, recipientHexEncodedX25519PublicKey: String): ByteArray {
|
internal fun encrypt(plaintext: ByteArray, recipientHexEncodedX25519PublicKey: String): ByteArray {
|
||||||
val userED25519KeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: throw Error.NoUserED25519KeyPair
|
val userED25519KeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: throw Error.NoUserED25519KeyPair
|
||||||
val recipientX25519PublicKey = Hex.fromStringCondensed(recipientHexEncodedX25519PublicKey.removing05PrefixIfNeeded())
|
val recipientX25519PublicKey = Hex.fromStringCondensed(recipientHexEncodedX25519PublicKey.removingIdPrefixIfNeeded())
|
||||||
|
|
||||||
val verificationData = plaintext + userED25519KeyPair.publicKey.asBytes + recipientX25519PublicKey
|
val verificationData = plaintext + userED25519KeyPair.publicKey.asBytes + recipientX25519PublicKey
|
||||||
val signature = ByteArray(Sign.BYTES)
|
val signature = ByteArray(Sign.BYTES)
|
||||||
|
@ -229,15 +229,15 @@ object MessageSender {
|
|||||||
message.profile = Profile(displayName)
|
message.profile = Profile(displayName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Validate the message
|
|
||||||
if (message !is VisibleMessage || !message.isValid()) {
|
|
||||||
throw Error.InvalidMessage
|
|
||||||
}
|
|
||||||
val messageBody = message.toProto()?.toByteArray()!!
|
|
||||||
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)
|
|
||||||
when (destination) {
|
when (destination) {
|
||||||
is Destination.LegacyOpenGroup -> {
|
is Destination.LegacyOpenGroup -> {
|
||||||
message.recipient = "${destination.server}.${destination.roomToken}"
|
message.recipient = "${destination.server}.${destination.roomToken}"
|
||||||
|
// Validate the message
|
||||||
|
if (message !is VisibleMessage || !message.isValid()) {
|
||||||
|
throw Error.InvalidMessage
|
||||||
|
}
|
||||||
|
val messageBody = message.toProto()?.toByteArray()!!
|
||||||
|
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)
|
||||||
val openGroupMessage = OpenGroupMessage(
|
val openGroupMessage = OpenGroupMessage(
|
||||||
sender = message.sender,
|
sender = message.sender,
|
||||||
sentTimestamp = message.sentTimestamp!!,
|
sentTimestamp = message.sentTimestamp!!,
|
||||||
@ -253,6 +253,12 @@ object MessageSender {
|
|||||||
}
|
}
|
||||||
is Destination.OpenGroup -> {
|
is Destination.OpenGroup -> {
|
||||||
message.recipient = "${destination.server}.${destination.roomToken}"
|
message.recipient = "${destination.server}.${destination.roomToken}"
|
||||||
|
// Validate the message
|
||||||
|
if (message !is VisibleMessage || !message.isValid()) {
|
||||||
|
throw Error.InvalidMessage
|
||||||
|
}
|
||||||
|
val messageBody = message.toProto()?.toByteArray()!!
|
||||||
|
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)
|
||||||
val openGroupMessage = OpenGroupMessage(
|
val openGroupMessage = OpenGroupMessage(
|
||||||
sender = message.sender,
|
sender = message.sender,
|
||||||
sentTimestamp = message.sentTimestamp!!,
|
sentTimestamp = message.sentTimestamp!!,
|
||||||
@ -268,6 +274,12 @@ object MessageSender {
|
|||||||
}
|
}
|
||||||
is Destination.OpenGroupInbox -> {
|
is Destination.OpenGroupInbox -> {
|
||||||
message.recipient = destination.blinkedPublicKey
|
message.recipient = destination.blinkedPublicKey
|
||||||
|
// Validate the message
|
||||||
|
if (message !is VisibleMessage || !message.isValid()) {
|
||||||
|
throw Error.InvalidMessage
|
||||||
|
}
|
||||||
|
val messageBody = message.toProto()?.toByteArray()!!
|
||||||
|
val plaintext = PushTransportDetails.getPaddedMessageBody(messageBody)
|
||||||
val base64EncodedData = Base64.encodeBytes(plaintext)
|
val base64EncodedData = Base64.encodeBytes(plaintext)
|
||||||
OpenGroupApi.sendDirectMessage(base64EncodedData, destination.blinkedPublicKey, destination.server).success {
|
OpenGroupApi.sendDirectMessage(base64EncodedData, destination.blinkedPublicKey, destination.server).success {
|
||||||
message.openGroupServerMessageID = it.id
|
message.openGroupServerMessageID = it.id
|
||||||
|
Loading…
x
Reference in New Issue
Block a user