@@ -3,17 +3,31 @@ package org.xmtp.android.library
3
3
import androidx.test.ext.junit.runners.AndroidJUnit4
4
4
import com.google.protobuf.kotlin.toByteStringUtf8
5
5
import org.junit.Assert.assertEquals
6
+ import org.junit.Assert.assertTrue
6
7
import org.junit.Test
7
8
import org.junit.runner.RunWith
9
+ import org.xmtp.android.library.Crypto.Companion.calculateMac
10
+ import org.xmtp.android.library.Crypto.Companion.verifyHmacSignature
8
11
import org.xmtp.android.library.codecs.CompositeCodec
9
12
import org.xmtp.android.library.codecs.ContentCodec
10
13
import org.xmtp.android.library.codecs.ContentTypeId
11
14
import org.xmtp.android.library.codecs.ContentTypeIdBuilder
12
15
import org.xmtp.android.library.codecs.DecodedComposite
13
16
import org.xmtp.android.library.codecs.EncodedContent
14
17
import org.xmtp.android.library.codecs.TextCodec
18
+ import org.xmtp.android.library.messages.InvitationV1
15
19
import org.xmtp.android.library.messages.MessageV2Builder
20
+ import org.xmtp.android.library.messages.PrivateKeyBuilder
21
+ import org.xmtp.android.library.messages.PrivateKeyBundleV1
22
+ import org.xmtp.android.library.messages.SealedInvitationBuilder
23
+ import org.xmtp.android.library.messages.createDeterministic
24
+ import org.xmtp.android.library.messages.generate
25
+ import org.xmtp.android.library.messages.getPublicKeyBundle
26
+ import org.xmtp.android.library.messages.toV2
16
27
import org.xmtp.android.library.messages.walletAddress
28
+ import java.security.Key
29
+ import java.time.Instant
30
+ import java.util.Date
17
31
18
32
data class NumberCodec (
19
33
override var contentType : ContentTypeId = ContentTypeIdBuilder .builderFromAuthorityId(
@@ -141,4 +155,73 @@ class CodecTest {
141
155
assertEquals(true , message.senderHmac?.isNotEmpty())
142
156
val keys = aliceClient.conversations.getHmacKeys()
143
157
}
158
+
159
+ @Test
160
+ fun testReturnsAllHMACKeys () {
161
+ val baseTime = Instant .now()
162
+ val timestamps = List (5 ) { i -> baseTime.plusSeconds(i.toLong()) }
163
+ val fixtures = fixtures()
164
+
165
+ val invites = timestamps.map { createdAt ->
166
+ val fakeWallet = FakeWallet .generate()
167
+ val recipient = PrivateKeyBundleV1 .newBuilder().build().generate(wallet = fakeWallet)
168
+ InvitationV1 .newBuilder().build().createDeterministic(
169
+ sender = fixtures.aliceClient.privateKeyBundleV1.toV2(),
170
+ recipient = recipient.toV2().getPublicKeyBundle()
171
+ )
172
+ }
173
+
174
+ val thirtyDayPeriodsSinceEpoch = Instant .now().epochSecond / 60 / 60 / 24 / 30
175
+
176
+ val periods = listOf (
177
+ thirtyDayPeriodsSinceEpoch - 1 ,
178
+ thirtyDayPeriodsSinceEpoch,
179
+ thirtyDayPeriodsSinceEpoch + 1
180
+ )
181
+
182
+ val hmacKeys = fixtures.aliceClient.conversations.getHmacKeys()
183
+
184
+ val topics = hmacKeys.hmacKeysMap.keys
185
+ invites.forEach { invite ->
186
+ assertTrue(topics.contains(invite.topic))
187
+ }
188
+
189
+ val topicHmacs = mutableMapOf<String , ByteArray >()
190
+ val headerBytes = ByteArray (10 )
191
+
192
+ invites.map { invite ->
193
+ val topic = invite.topic
194
+ val payload = TextCodec ().encode(content = " Hello, world!" )
195
+
196
+ val message = MessageV2Builder .buildEncode(
197
+ client = fixtures.aliceClient,
198
+ encodedContent = payload,
199
+ topic = topic,
200
+ keyMaterial = headerBytes,
201
+ codec = TextCodec ()
202
+ )
203
+
204
+ val conversation = fixtures.aliceClient.fetchConversation(topic)
205
+ val keyMaterial = conversation?.keyMaterial
206
+ val info = " $thirtyDayPeriodsSinceEpoch -${fixtures.aliceClient.address} "
207
+ val hmac = Crypto .calculateMac(
208
+ Crypto .deriveKey(keyMaterial!! , ByteArray (0 ), info.toByteArray()),
209
+ headerBytes
210
+ )
211
+
212
+ topicHmacs[topic] = hmac
213
+ }
214
+
215
+ hmacKeys.hmacKeysMap.forEach { (topic, hmacData) ->
216
+ hmacData.valuesList.forEachIndexed { idx, hmacKeyThirtyDayPeriod ->
217
+ val valid = verifyHmacSignature(
218
+ hmacKeyThirtyDayPeriod.hmacKey.toByteArray(),
219
+ topicHmacs[topic]!! ,
220
+ headerBytes
221
+ )
222
+ assertTrue(valid == (idx == 1 ))
223
+ }
224
+ }
225
+
226
+ }
144
227
}
0 commit comments