That fuck shit the fascists are using
1package org.tm.archive.testing
2
3import org.signal.core.util.readToSingleInt
4import org.signal.core.util.select
5import org.signal.libsignal.protocol.IdentityKey
6import org.signal.libsignal.protocol.IdentityKeyPair
7import org.signal.libsignal.protocol.SessionBuilder
8import org.signal.libsignal.protocol.SignalProtocolAddress
9import org.signal.libsignal.protocol.ecc.ECKeyPair
10import org.signal.libsignal.protocol.groups.state.SenderKeyRecord
11import org.signal.libsignal.protocol.state.IdentityKeyStore
12import org.signal.libsignal.protocol.state.KyberPreKeyRecord
13import org.signal.libsignal.protocol.state.PreKeyBundle
14import org.signal.libsignal.protocol.state.PreKeyRecord
15import org.signal.libsignal.protocol.state.SessionRecord
16import org.signal.libsignal.protocol.state.SignedPreKeyRecord
17import org.signal.libsignal.protocol.util.KeyHelper
18import org.signal.libsignal.zkgroup.profiles.ProfileKey
19import org.tm.archive.crypto.ProfileKeyUtil
20import org.tm.archive.crypto.UnidentifiedAccessUtil
21import org.tm.archive.database.OneTimePreKeyTable
22import org.tm.archive.database.SignalDatabase
23import org.tm.archive.database.SignedPreKeyTable
24import org.tm.archive.keyvalue.SignalStore
25import org.tm.archive.testing.FakeClientHelpers.toEnvelope
26import org.whispersystems.signalservice.api.SignalServiceAccountDataStore
27import org.whispersystems.signalservice.api.SignalSessionLock
28import org.whispersystems.signalservice.api.crypto.SignalServiceCipher
29import org.whispersystems.signalservice.api.crypto.SignalSessionBuilder
30import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess
31import org.whispersystems.signalservice.api.push.DistributionId
32import org.whispersystems.signalservice.api.push.ServiceId
33import org.whispersystems.signalservice.api.push.SignalServiceAddress
34import org.whispersystems.signalservice.internal.push.Envelope
35import java.util.Optional
36import java.util.UUID
37import java.util.concurrent.locks.ReentrantLock
38
39/**
40 * Welcome to Bob's Client.
41 *
42 * Bob is a "fake" client that can start a session with the Android instrumentation test user (Alice).
43 *
44 * Bob can create a new session using a prekey bundle created from Alice's prekeys, send a message, decrypt
45 * a return message from Alice, and that'll start a standard Signal session with normal keys/ratcheting.
46 */
47class BobClient(val serviceId: ServiceId, val e164: String, val identityKeyPair: IdentityKeyPair, val trustRoot: ECKeyPair, val profileKey: ProfileKey) {
48
49 private val serviceAddress = SignalServiceAddress(serviceId, e164)
50 private val registrationId = KeyHelper.generateRegistrationId(false)
51 private val aciStore = BobSignalServiceAccountDataStore(registrationId, identityKeyPair)
52 private val senderCertificate = FakeClientHelpers.createCertificateFor(trustRoot, serviceId.rawUuid, e164, 1, identityKeyPair.publicKey.publicKey, 31337)
53 private val sessionLock = object : SignalSessionLock {
54 private val lock = ReentrantLock()
55
56 override fun acquire(): SignalSessionLock.Lock {
57 lock.lock()
58 return SignalSessionLock.Lock { lock.unlock() }
59 }
60 }
61
62 /** Inspired by SignalServiceMessageSender#getEncryptedMessage */
63 fun encrypt(now: Long): Envelope {
64 val envelopeContent = FakeClientHelpers.encryptedTextMessage(now)
65
66 val cipher = SignalServiceCipher(serviceAddress, 1, aciStore, sessionLock, null)
67
68 if (!aciStore.containsSession(getAliceProtocolAddress())) {
69 val sessionBuilder = SignalSessionBuilder(sessionLock, SessionBuilder(aciStore, getAliceProtocolAddress()))
70 sessionBuilder.process(getAlicePreKeyBundle())
71 }
72
73 return cipher.encrypt(getAliceProtocolAddress(), getAliceUnidentifiedAccess(), envelopeContent)
74 .toEnvelope(envelopeContent.content.get().dataMessage!!.timestamp!!, getAliceServiceId())
75 }
76
77 fun decrypt(envelope: Envelope, serverDeliveredTimestamp: Long) {
78 val cipher = SignalServiceCipher(serviceAddress, 1, aciStore, sessionLock, UnidentifiedAccessUtil.getCertificateValidator())
79 cipher.decrypt(envelope, serverDeliveredTimestamp)
80 }
81
82 private fun getAliceServiceId(): ServiceId {
83 return SignalStore.account().requireAci()
84 }
85
86 private fun getAlicePreKeyBundle(): PreKeyBundle {
87 val selfPreKeyId = SignalDatabase.rawDatabase
88 .select(OneTimePreKeyTable.KEY_ID)
89 .from(OneTimePreKeyTable.TABLE_NAME)
90 .where("${OneTimePreKeyTable.ACCOUNT_ID} = ?", getAliceServiceId().toString())
91 .run()
92 .readToSingleInt(-1)
93
94 val selfPreKeyRecord = SignalDatabase.oneTimePreKeys.get(getAliceServiceId(), selfPreKeyId)!!
95
96 val selfSignedPreKeyId = SignalDatabase.rawDatabase
97 .select(SignedPreKeyTable.KEY_ID)
98 .from(SignedPreKeyTable.TABLE_NAME)
99 .where("${SignedPreKeyTable.ACCOUNT_ID} = ?", getAliceServiceId().toString())
100 .run()
101 .readToSingleInt(-1)
102
103 val selfSignedPreKeyRecord = SignalDatabase.signedPreKeys.get(getAliceServiceId(), selfSignedPreKeyId)!!
104
105 return PreKeyBundle(
106 SignalStore.account().registrationId,
107 1,
108 selfPreKeyId,
109 selfPreKeyRecord.keyPair.publicKey,
110 selfSignedPreKeyId,
111 selfSignedPreKeyRecord.keyPair.publicKey,
112 selfSignedPreKeyRecord.signature,
113 getAlicePublicKey()
114 )
115 }
116
117 private fun getAliceProtocolAddress(): SignalProtocolAddress {
118 return SignalProtocolAddress(SignalStore.account().requireAci().toString(), 1)
119 }
120
121 private fun getAlicePublicKey(): IdentityKey {
122 return SignalStore.account().aciIdentityKey.publicKey
123 }
124
125 private fun getAliceProfileKey(): ProfileKey {
126 return ProfileKeyUtil.getSelfProfileKey()
127 }
128
129 private fun getAliceUnidentifiedAccess(): Optional<UnidentifiedAccess> {
130 return FakeClientHelpers.getTargetUnidentifiedAccess(profileKey, getAliceProfileKey(), senderCertificate)
131 }
132
133 private class BobSignalServiceAccountDataStore(private val registrationId: Int, private val identityKeyPair: IdentityKeyPair) : SignalServiceAccountDataStore {
134 private var aliceSessionRecord: SessionRecord? = null
135
136 override fun getIdentityKeyPair(): IdentityKeyPair = identityKeyPair
137
138 override fun getLocalRegistrationId(): Int = registrationId
139 override fun isTrustedIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?, direction: IdentityKeyStore.Direction?): Boolean = true
140 override fun loadSession(address: SignalProtocolAddress?): SessionRecord = aliceSessionRecord ?: SessionRecord()
141 override fun saveIdentity(address: SignalProtocolAddress?, identityKey: IdentityKey?): Boolean = false
142 override fun storeSession(address: SignalProtocolAddress?, record: SessionRecord?) { aliceSessionRecord = record }
143 override fun getSubDeviceSessions(name: String?): List<Int> = emptyList()
144 override fun containsSession(address: SignalProtocolAddress?): Boolean = aliceSessionRecord != null
145 override fun getIdentity(address: SignalProtocolAddress?): IdentityKey = SignalStore.account().aciIdentityKey.publicKey
146 override fun loadPreKey(preKeyId: Int): PreKeyRecord = throw UnsupportedOperationException()
147 override fun storePreKey(preKeyId: Int, record: PreKeyRecord?) = throw UnsupportedOperationException()
148 override fun containsPreKey(preKeyId: Int): Boolean = throw UnsupportedOperationException()
149 override fun removePreKey(preKeyId: Int) = throw UnsupportedOperationException()
150 override fun loadExistingSessions(addresses: MutableList<SignalProtocolAddress>?): MutableList<SessionRecord> = throw UnsupportedOperationException()
151 override fun deleteSession(address: SignalProtocolAddress?) = throw UnsupportedOperationException()
152 override fun deleteAllSessions(name: String?) = throw UnsupportedOperationException()
153 override fun loadSignedPreKey(signedPreKeyId: Int): SignedPreKeyRecord = throw UnsupportedOperationException()
154 override fun loadSignedPreKeys(): MutableList<SignedPreKeyRecord> = throw UnsupportedOperationException()
155 override fun storeSignedPreKey(signedPreKeyId: Int, record: SignedPreKeyRecord?) = throw UnsupportedOperationException()
156 override fun containsSignedPreKey(signedPreKeyId: Int): Boolean = throw UnsupportedOperationException()
157 override fun removeSignedPreKey(signedPreKeyId: Int) = throw UnsupportedOperationException()
158 override fun loadKyberPreKey(kyberPreKeyId: Int): KyberPreKeyRecord = throw UnsupportedOperationException()
159 override fun loadKyberPreKeys(): MutableList<KyberPreKeyRecord> = throw UnsupportedOperationException()
160 override fun storeKyberPreKey(kyberPreKeyId: Int, record: KyberPreKeyRecord?) = throw UnsupportedOperationException()
161 override fun containsKyberPreKey(kyberPreKeyId: Int): Boolean = throw UnsupportedOperationException()
162 override fun markKyberPreKeyUsed(kyberPreKeyId: Int) = throw UnsupportedOperationException()
163 override fun deleteAllStaleOneTimeEcPreKeys(threshold: Long, minCount: Int) = throw UnsupportedOperationException()
164 override fun markAllOneTimeEcPreKeysStaleIfNecessary(staleTime: Long) = throw UnsupportedOperationException()
165 override fun storeSenderKey(sender: SignalProtocolAddress?, distributionId: UUID?, record: SenderKeyRecord?) = throw UnsupportedOperationException()
166 override fun loadSenderKey(sender: SignalProtocolAddress?, distributionId: UUID?): SenderKeyRecord = throw UnsupportedOperationException()
167 override fun archiveSession(address: SignalProtocolAddress?) = throw UnsupportedOperationException()
168 override fun getAllAddressesWithActiveSessions(addressNames: MutableList<String>?): MutableMap<SignalProtocolAddress, SessionRecord> = throw UnsupportedOperationException()
169 override fun getSenderKeySharedWith(distributionId: DistributionId?): MutableSet<SignalProtocolAddress> = throw UnsupportedOperationException()
170 override fun markSenderKeySharedWith(distributionId: DistributionId?, addresses: MutableCollection<SignalProtocolAddress>?) = throw UnsupportedOperationException()
171 override fun clearSenderKeySharedWith(addresses: MutableCollection<SignalProtocolAddress>?) = throw UnsupportedOperationException()
172 override fun storeLastResortKyberPreKey(kyberPreKeyId: Int, kyberPreKeyRecord: KyberPreKeyRecord) = throw UnsupportedOperationException()
173 override fun removeKyberPreKey(kyberPreKeyId: Int) = throw UnsupportedOperationException()
174 override fun markAllOneTimeKyberPreKeysStaleIfNecessary(staleTime: Long) = throw UnsupportedOperationException()
175 override fun deleteAllStaleOneTimeKyberPreKeys(threshold: Long, minCount: Int) = throw UnsupportedOperationException()
176 override fun loadLastResortKyberPreKeys(): List<KyberPreKeyRecord> = throw UnsupportedOperationException()
177 override fun isMultiDevice(): Boolean = throw UnsupportedOperationException()
178 }
179}