Use both envelope.type and ciphertextMessageType in the validator.

This commit is contained in:
Greyson Parrelli
2026-01-28 12:43:59 -05:00
parent 0a572153f0
commit d9dba89781
7 changed files with 179 additions and 33 deletions

View File

@@ -8,6 +8,8 @@ package org.whispersystems.signalservice.api.messages
import okio.ByteString.Companion.toByteString
import org.junit.Test
import org.signal.core.models.ServiceId
import org.signal.libsignal.protocol.message.CiphertextMessage
import org.signal.libsignal.protocol.message.DecryptionErrorMessage
import org.whispersystems.signalservice.internal.push.Content
import org.whispersystems.signalservice.internal.push.DataMessage
import org.whispersystems.signalservice.internal.push.Envelope
@@ -30,7 +32,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -45,7 +47,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -61,7 +63,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -77,7 +79,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -93,7 +95,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -108,7 +110,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -120,7 +122,7 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@@ -134,7 +136,132 @@ class EnvelopeContentValidatorTest {
)
)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI)
val result = EnvelopeContentValidator.validate(Envelope(), content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - plaintext content via envelope type with valid decryption error message is valid`() {
val envelope = Envelope(
type = Envelope.Type.PLAINTEXT_CONTENT
)
val content = Content(
decryptionErrorMessage = createValidDecryptionErrorMessage()
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Valid)
}
@Test
fun `validate - plaintext content via ciphertext message type (sealed sender) with valid decryption error message is valid`() {
val envelope = Envelope(
type = Envelope.Type.UNIDENTIFIED_SENDER
)
val content = Content(
decryptionErrorMessage = createValidDecryptionErrorMessage()
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Valid)
}
@Test
fun `validate - plaintext content via envelope type with unexpected DataMessage is invalid`() {
val envelope = Envelope(
type = Envelope.Type.PLAINTEXT_CONTENT,
timestamp = 1234
)
val content = Content(
decryptionErrorMessage = createValidDecryptionErrorMessage(),
dataMessage = DataMessage(timestamp = 1234)
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - plaintext content via ciphertext message type (sealed sender) with unexpected DataMessage is invalid`() {
val envelope = Envelope(
type = Envelope.Type.UNIDENTIFIED_SENDER,
timestamp = 1234
)
val content = Content(
decryptionErrorMessage = createValidDecryptionErrorMessage(),
dataMessage = DataMessage(timestamp = 1234)
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - plaintext content via envelope type without DecryptionErrorMessage is invalid`() {
val envelope = Envelope(
type = Envelope.Type.PLAINTEXT_CONTENT
)
val content = Content()
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - plaintext content via ciphertext message type (sealed sender) without DecryptionErrorMessage is invalid`() {
val envelope = Envelope(
type = Envelope.Type.UNIDENTIFIED_SENDER
)
val content = Content()
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - plaintext content with SyncMessage is invalid`() {
val envelope = Envelope(
type = Envelope.Type.PLAINTEXT_CONTENT
)
val content = Content(
decryptionErrorMessage = createValidDecryptionErrorMessage(),
syncMessage = org.whispersystems.signalservice.internal.push.SyncMessage()
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.PLAINTEXT_CONTENT_TYPE)
assert(result is EnvelopeContentValidator.Result.Invalid)
}
@Test
fun `validate - regular encrypted message is not subject to plaintext validation`() {
val envelope = Envelope(
type = Envelope.Type.CIPHERTEXT,
timestamp = 1234
)
val content = Content(
dataMessage = DataMessage(timestamp = 1234)
)
val result = EnvelopeContentValidator.validate(envelope, content, SELF_ACI, CiphertextMessage.WHISPER_TYPE)
assert(result is EnvelopeContentValidator.Result.Valid)
}
private fun createValidDecryptionErrorMessage(): okio.ByteString {
val minimalSenderKeyContent = ByteArray(64)
val decryptionErrorMessage = DecryptionErrorMessage.forOriginalMessage(
minimalSenderKeyContent,
CiphertextMessage.SENDERKEY_TYPE,
System.currentTimeMillis(),
1
)
return decryptionErrorMessage.serialize().toByteString()
}
}