diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/MockProvider.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/MockProvider.kt index 68e4f31e79..a5d186a10d 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/MockProvider.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/MockProvider.kt @@ -75,8 +75,8 @@ object MockProvider { val device = PreKeyResponseItem().apply { this.deviceId = deviceId registrationId = KeyHelper.generateRegistrationId(false) - signedPreKey = SignedPreKeyEntity(signedPreKeyRecord.id, signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature) - preKey = PreKeyEntity(oneTimePreKey.id, oneTimePreKey.keyPair.publicKey) + signedPreKey = SignedPreKeyEntity(signedPreKeyRecord.id.toLong(), signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature) + preKey = PreKeyEntity(oneTimePreKey.id.toLong(), oneTimePreKey.keyPair.publicKey) } return PreKeyResponse().apply { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt index df410cc6fa..ac60fbc89b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt @@ -335,7 +335,7 @@ class ChangeNumberRepository( } else { PreKeyUtil.generateSignedPreKey(SecureRandom().nextInt(Medium.MAX_VALUE), pniIdentity.privateKey) } - devicePniSignedPreKeys[deviceId] = SignedPreKeyEntity(signedPreKeyRecord.id, signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature) + devicePniSignedPreKeys[deviceId] = SignedPreKeyEntity(signedPreKeyRecord.id.toLong(), signedPreKeyRecord.keyPair.publicKey, signedPreKeyRecord.signature) // Last-resort kyber prekeys val lastResortKyberPreKeyRecord: KyberPreKeyRecord = if (deviceId == primaryDeviceId) { @@ -343,7 +343,7 @@ class ChangeNumberRepository( } else { PreKeyUtil.generateLastResortKyberPreKey(SecureRandom().nextInt(Medium.MAX_VALUE), pniIdentity.privateKey) } - devicePniLastResortKyberPreKeys[deviceId] = KyberPreKeyEntity(lastResortKyberPreKeyRecord.id, lastResortKyberPreKeyRecord.keyPair.publicKey, lastResortKyberPreKeyRecord.signature) + devicePniLastResortKyberPreKeys[deviceId] = KyberPreKeyEntity(lastResortKyberPreKeyRecord.id.toLong(), lastResortKyberPreKeyRecord.keyPair.publicKey, lastResortKyberPreKeyRecord.signature) // Registration Ids var pniRegistrationId = -1 @@ -383,8 +383,8 @@ class ChangeNumberRepository( previousPni = SignalStore.account.pni!!.toByteString(), pniIdentityKeyPair = pniIdentity.serialize().toByteString(), pniRegistrationId = pniRegistrationIds[primaryDeviceId]!!, - pniSignedPreKeyId = devicePniSignedPreKeys[primaryDeviceId]!!.keyId, - pniLastResortKyberPreKeyId = devicePniLastResortKyberPreKeys[primaryDeviceId]!!.keyId, + pniSignedPreKeyId = devicePniSignedPreKeys[primaryDeviceId]!!.keyId.toInt(), + pniLastResortKyberPreKeyId = devicePniLastResortKyberPreKeys[primaryDeviceId]!!.keyId.toInt(), previousE164 = SignalStore.account.requireE164(), newE164 = newE164 ) diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 0c0f6145ee..bb7f67d9a1 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -2850,6 +2850,10 @@ public class SignalServiceMessageSender { try { List preKeys = getPreKeys(recipient, sealedSenderAccess, deviceId, story); + if (preKeys.isEmpty()) { + throw new InvalidKeyException("No valid prekey bundles available for " + signalProtocolAddress); + } + for (PreKeyBundle preKey : preKeys) { Log.d(TAG, "Initializing prekey session for " + signalProtocolAddress); diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/keys/KeysApi.kt b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/keys/KeysApi.kt index efd5b3a2ce..1a22dce208 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/keys/KeysApi.kt +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/keys/KeysApi.kt @@ -94,7 +94,7 @@ class KeysApi( fun setPreKeys(preKeyUpload: PreKeyUpload): NetworkResult { val signedPreKey: SignedPreKeyEntity? = if (preKeyUpload.signedPreKey != null) { SignedPreKeyEntity( - preKeyUpload.signedPreKey.id, + preKeyUpload.signedPreKey.id.toLong(), preKeyUpload.signedPreKey.keyPair.publicKey, preKeyUpload.signedPreKey.signature ) @@ -105,14 +105,14 @@ class KeysApi( val oneTimeEcPreKeys: List? = if (preKeyUpload.oneTimeEcPreKeys != null) { preKeyUpload .oneTimeEcPreKeys - .map { oneTimeEcKey: PreKeyRecord -> PreKeyEntity(oneTimeEcKey.id, oneTimeEcKey.keyPair.publicKey) } + .map { oneTimeEcKey: PreKeyRecord -> PreKeyEntity(oneTimeEcKey.id.toLong(), oneTimeEcKey.keyPair.publicKey) } } else { null } val lastResortKyberPreKey: KyberPreKeyEntity? = if (preKeyUpload.lastResortKyberPreKey != null) { KyberPreKeyEntity( - preKeyUpload.lastResortKyberPreKey.id, + preKeyUpload.lastResortKyberPreKey.id.toLong(), preKeyUpload.lastResortKyberPreKey.keyPair.publicKey, preKeyUpload.lastResortKyberPreKey.signature ) @@ -123,7 +123,7 @@ class KeysApi( val oneTimeKyberPreKeys: List? = if (preKeyUpload.oneTimeKyberPreKeys != null) { preKeyUpload .oneTimeKyberPreKeys - .map { record -> KyberPreKeyEntity(record.id, record.keyPair.publicKey, record.signature) } + .map { record -> KyberPreKeyEntity(record.id.toLong(), record.keyPair.publicKey, record.signature) } } else { null } @@ -215,8 +215,13 @@ class KeysApi( var kyberPreKeySignature: ByteArray? = null if (device.getSignedPreKey() != null) { + val rawSignedPreKeyId = device.getSignedPreKey().keyId + if (rawSignedPreKeyId !in 0..Int.MAX_VALUE) { + Log.w(TAG, "Signed pre-key ID for device ${device.deviceId} is out of valid range! Skipping.") + continue + } signedPreKey = device.getSignedPreKey().publicKey - signedPreKeyId = device.getSignedPreKey().keyId + signedPreKeyId = rawSignedPreKeyId.toInt() signedPreKeySignature = device.getSignedPreKey().signature } else { Log.w(TAG, "No signed prekey for device ${device.deviceId}! Skipping.") @@ -224,13 +229,23 @@ class KeysApi( } if (device.getPreKey() != null) { - preKeyId = device.getPreKey().keyId + val rawPreKeyId = device.getPreKey().keyId + if (rawPreKeyId !in 0..Int.MAX_VALUE) { + Log.w(TAG, "Pre-key ID for device ${device.deviceId} is out of valid range! Skipping.") + continue + } + preKeyId = rawPreKeyId.toInt() preKey = device.getPreKey().publicKey } if (device.getKyberPreKey() != null) { + val rawKyberPreKeyId = device.getKyberPreKey().keyId + if (rawKyberPreKeyId !in 0..Int.MAX_VALUE) { + Log.w(TAG, "Kyber pre-key ID for device ${device.deviceId} is out of valid range! Skipping.") + continue + } kyberPreKey = device.getKyberPreKey().publicKey - kyberPreKeyId = device.getKyberPreKey().keyId + kyberPreKeyId = rawKyberPreKeyId.toInt() kyberPreKeySignature = device.getKyberPreKey().signature } else { Log.w(TAG, "No kyber prekey for device ${device.deviceId}! Skipping.") diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/SignedPreKeyEntity.java b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/SignedPreKeyEntity.java index 2ae05785e3..5d4edbb5ff 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/SignedPreKeyEntity.java +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/push/SignedPreKeyEntity.java @@ -31,7 +31,7 @@ public class SignedPreKeyEntity extends PreKeyEntity { public SignedPreKeyEntity() {} - public SignedPreKeyEntity(int keyId, ECPublicKey publicKey, byte[] signature) { + public SignedPreKeyEntity(long keyId, ECPublicKey publicKey, byte[] signature) { super(keyId, publicKey); this.signature = signature; } diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt index f10be4edf5..cb12da9cf8 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt @@ -154,10 +154,10 @@ class RegistrationApi( val request = RegisterAsSecondaryDeviceRequest( verificationCode = verificationCode, accountAttributes = attributes, - aciSignedPreKey = SignedPreKeyEntity(aciPreKeys.signedPreKey.id, aciPreKeys.signedPreKey.keyPair.publicKey, aciPreKeys.signedPreKey.signature), - pniSignedPreKey = SignedPreKeyEntity(pniPreKeys.signedPreKey.id, pniPreKeys.signedPreKey.keyPair.publicKey, pniPreKeys.signedPreKey.signature), - aciPqLastResortPreKey = KyberPreKeyEntity(aciPreKeys.lastResortKyberPreKey.id, aciPreKeys.lastResortKyberPreKey.keyPair.publicKey, aciPreKeys.lastResortKyberPreKey.signature), - pniPqLastResortPreKey = KyberPreKeyEntity(pniPreKeys.lastResortKyberPreKey.id, pniPreKeys.lastResortKyberPreKey.keyPair.publicKey, pniPreKeys.lastResortKyberPreKey.signature), + aciSignedPreKey = SignedPreKeyEntity(aciPreKeys.signedPreKey.id.toLong(), aciPreKeys.signedPreKey.keyPair.publicKey, aciPreKeys.signedPreKey.signature), + pniSignedPreKey = SignedPreKeyEntity(pniPreKeys.signedPreKey.id.toLong(), pniPreKeys.signedPreKey.keyPair.publicKey, pniPreKeys.signedPreKey.signature), + aciPqLastResortPreKey = KyberPreKeyEntity(aciPreKeys.lastResortKyberPreKey.id.toLong(), aciPreKeys.lastResortKyberPreKey.keyPair.publicKey, aciPreKeys.lastResortKyberPreKey.signature), + pniPqLastResortPreKey = KyberPreKeyEntity(pniPreKeys.lastResortKyberPreKey.id.toLong(), pniPreKeys.lastResortKyberPreKey.keyPair.publicKey, pniPreKeys.lastResortKyberPreKey.signature), gcmToken = fcmToken?.let { GcmRegistrationId(it, true) } ) diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/KyberPreKeyEntity.java b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/KyberPreKeyEntity.java index 90520fc3f3..0612151524 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/KyberPreKeyEntity.java +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/KyberPreKeyEntity.java @@ -25,7 +25,7 @@ import java.io.IOException; public class KyberPreKeyEntity { @JsonProperty - private int keyId; + private long keyId; @JsonProperty @JsonSerialize(using = KEMPublicKeySerializer.class) @@ -39,13 +39,13 @@ public class KyberPreKeyEntity { public KyberPreKeyEntity() {} - public KyberPreKeyEntity(int keyId, KEMPublicKey publicKey, byte[] signature) { + public KyberPreKeyEntity(long keyId, KEMPublicKey publicKey, byte[] signature) { this.keyId = keyId; this.publicKey = publicKey; this.signature = signature; } - public int getKeyId() { + public long getKeyId() { return keyId; } diff --git a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PreKeyEntity.java b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PreKeyEntity.java index 1b0255413b..b99c892c58 100644 --- a/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PreKeyEntity.java +++ b/lib/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PreKeyEntity.java @@ -25,7 +25,7 @@ import java.io.IOException; public class PreKeyEntity { @JsonProperty - private int keyId; + private long keyId; @JsonProperty @JsonSerialize(using = ECPublicKeySerializer.class) @@ -34,12 +34,12 @@ public class PreKeyEntity { public PreKeyEntity() {} - public PreKeyEntity(int keyId, ECPublicKey publicKey) { + public PreKeyEntity(long keyId, ECPublicKey publicKey) { this.keyId = keyId; this.publicKey = publicKey; } - public int getKeyId() { + public long getKeyId() { return keyId; }