Skip to content

Commit eaedba8

Browse files
authored
Merge pull request #440 from WalletConnect/develop
Develop to Master
2 parents 2021f25 + 071fea9 commit eaedba8

File tree

131 files changed

+1169
-3499
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+1169
-3499
lines changed

ReadMe.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ WalletConnect v2 protocols for Android applications.
1010
* [Core SDK](https://github.com/WalletConnect/WalletConnectKotlinV2/tree/develop/androidCore)
1111
* [Sign SDK](https://github.com/WalletConnect/WalletConnectKotlinV2/tree/develop/sign)
1212
* [Auth SDK](https://github.com/WalletConnect/WalletConnectKotlinV2/tree/develop/auth)
13+
* [Chat SDK](https://github.com/WalletConnect/WalletConnectKotlinV2/tree/develop/chat)
1314

1415
## License
15-
WalletConnect v2 is released under the Apache 2.0 license. [See LICENSE](https://github.com/WalletConnect/WalletConnectKotlinV2/blob/feature/develop/LICENSE) for details.
16+
WalletConnect v2 is released under the Apache 2.0 license. [See LICENSE](https://github.com/WalletConnect/WalletConnectKotlinV2/blob/feature/develop/LICENSE) for details.

androidCore/impl/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88

99
project.apply {
1010
extra[KEY_PUBLISH_ARTIFACT_ID] = "android-core-impl"
11-
extra[KEY_PUBLISH_VERSION] = "1.1.0"
11+
extra[KEY_PUBLISH_VERSION] = "1.2.0"
1212
extra[KEY_SDK_NAME] = "Android Core Impl"
1313
}
1414

@@ -51,7 +51,7 @@ sqldelight {
5151

5252
dependencies {
5353
debugApi(project(":androidCore:sdk"))
54-
releaseApi("com.walletconnect:android-core:1.1.0")
54+
releaseApi("com.walletconnect:android-core:1.2.0")
5555

5656
bouncyCastle()
5757
coroutines()

androidCore/impl/src/main/kotlin/com/walletconnect/android/impl/common/CryptoException.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ import com.walletconnect.android.internal.common.exception.WalletConnectExceptio
44

55
class UnknownEnvelopeTypeException(override val message: String?) : WalletConnectException(message)
66
class MissingParticipantsException(override val message: String?) : WalletConnectException(message)
7-
class MissingReceiverPublicKeyException(override val message: String?) : WalletConnectException(message)
7+
class MissingKeyException(override val message: String?) : WalletConnectException(message)

androidCore/impl/src/main/kotlin/com/walletconnect/android/impl/data/codec/ChaChaPolyCodec.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
package com.walletconnect.android.impl.data.codec
44

55
import com.walletconnect.android.impl.common.MissingParticipantsException
6-
import com.walletconnect.android.impl.common.MissingReceiverPublicKeyException
6+
import com.walletconnect.android.impl.common.MissingKeyException
77
import com.walletconnect.android.impl.common.UnknownEnvelopeTypeException
88
import com.walletconnect.android.internal.common.model.Participants
99
import com.walletconnect.android.internal.common.model.SymmetricKey
1010
import com.walletconnect.android.internal.common.model.EnvelopeType
1111
import com.walletconnect.android.impl.crypto.Codec
12+
import com.walletconnect.android.impl.utils.SELF_PARTICIPANT_CONTEXT
1213
import com.walletconnect.android.internal.common.crypto.KeyManagementRepository
1314
import com.walletconnect.foundation.common.model.PublicKey
1415
import com.walletconnect.foundation.common.model.Topic
@@ -47,14 +48,17 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
4748

4849
@Throws(
4950
UnknownEnvelopeTypeException::class,
50-
MissingReceiverPublicKeyException::class
51+
MissingKeyException::class
5152
)
5253
override fun decrypt(topic: Topic, cipherText: String): String {
5354
val encryptedPayloadBytes = Base64.decode(cipherText)
5455

5556
return when (val envelopeType = encryptedPayloadBytes.envelopeType) {
5657
EnvelopeType.ZERO.id -> decryptType0(topic, encryptedPayloadBytes)
57-
EnvelopeType.ONE.id -> decryptType1(encryptedPayloadBytes, keyManagementRepository.getSelfParticipant(topic))
58+
EnvelopeType.ONE.id -> decryptType1(
59+
encryptedPayloadBytes,
60+
keyManagementRepository.getPublicKey("$SELF_PARTICIPANT_CONTEXT${topic.value}")
61+
)
5862
else -> throw UnknownEnvelopeTypeException("Decrypt; Unknown envelope type: $envelopeType")
5963
}
6064
}
@@ -70,14 +74,14 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
7074
byteBuffer.get(nonce)
7175
byteBuffer.get(encryptedMessageBytes)
7276

73-
val symmetricKey = keyManagementRepository.getSymmetricKey(topic)
77+
val symmetricKey = keyManagementRepository.getSymmetricKey(topic.value)
7478
val decryptedTextBytes = decryptPayload(symmetricKey, nonce, encryptedMessageBytes)
7579

7680
return String(decryptedTextBytes, Charsets.UTF_8)
7781
}
7882

7983
private fun decryptType1(encryptedPayloadBytes: ByteArray, receiverPublicKey: PublicKey?): String {
80-
if (receiverPublicKey == null) throw MissingReceiverPublicKeyException("Missing receiver public key")
84+
if (receiverPublicKey == null) throw MissingKeyException("Missing receiver public key")
8185

8286
val envelopeType = ByteArray(ENVELOPE_TYPE_SIZE)
8387
val nonce = ByteArray(NONCE_SIZE)
@@ -99,7 +103,7 @@ internal class ChaChaPolyCodec(private val keyManagementRepository: KeyManagemen
99103
}
100104

101105
private fun encryptEnvelopeType0(topic: Topic, nonceBytes: ByteArray, input: ByteArray, envelopeType: EnvelopeType): String {
102-
val symmetricKey = keyManagementRepository.getSymmetricKey(topic)
106+
val symmetricKey = keyManagementRepository.getSymmetricKey(topic.value)
103107
val cipherBytes = encryptPayload(symmetricKey, nonceBytes, input)
104108
val payloadSize = cipherBytes.size + NONCE_SIZE + ENVELOPE_TYPE_SIZE
105109

androidCore/impl/src/main/kotlin/com/walletconnect/android/impl/data/repository/BouncyCastleKeyManagementRepository.kt

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,73 +2,65 @@
22

33
package com.walletconnect.android.impl.data.repository
44

5-
import com.walletconnect.android.internal.common.storage.KeyStore
6-
import com.walletconnect.android.internal.common.model.SymmetricKey
5+
import com.walletconnect.android.impl.common.MissingKeyException
76
import com.walletconnect.android.internal.common.crypto.KeyManagementRepository
7+
import com.walletconnect.android.internal.common.model.SymmetricKey
8+
import com.walletconnect.android.internal.common.storage.KeyStore
9+
import com.walletconnect.foundation.common.model.Key
810
import com.walletconnect.foundation.common.model.PrivateKey
911
import com.walletconnect.foundation.common.model.PublicKey
1012
import com.walletconnect.foundation.common.model.Topic
1113
import com.walletconnect.util.bytesToHex
1214
import com.walletconnect.util.hexToBytes
13-
import com.walletconnect.utils.Empty
1415
import org.bouncycastle.crypto.digests.SHA256Digest
1516
import org.bouncycastle.crypto.generators.HKDFBytesGenerator
1617
import org.bouncycastle.crypto.params.HKDFParameters
1718
import org.bouncycastle.math.ec.rfc7748.X25519
1819
import java.security.MessageDigest
1920
import java.security.SecureRandom
2021
import javax.crypto.KeyGenerator
21-
import com.walletconnect.foundation.common.model.Key as WCKey
2222

23-
//todo: Refactor
2423
internal class BouncyCastleKeyManagementRepository(private val keyChain: KeyStore) : KeyManagementRepository {
25-
override fun generateAndStoreSymmetricKey(topic: Topic): SymmetricKey {
26-
val symmetricKey = generateSymmetricKey()
27-
keyChain.setKey(topic.value, symmetricKey)
28-
return symmetricKey
24+
override fun setKey(key: Key, tag: String) {
25+
keyChain.setKey(tag, key)
2926
}
3027

31-
override fun generateSymmetricKey(): SymmetricKey = SymmetricKey(createSymmetricKey().bytesToHex())
28+
override fun getPublicKey(tag: String): PublicKey {
29+
val key = keyChain.getKey(tag) ?: throw MissingKeyException("No SymmetricKey for tag: $tag")
30+
return PublicKey(key)
31+
}
3232

33-
override fun setSymmetricKey(topic: Topic, symmetricKey: SymmetricKey) {
34-
keyChain.setKey(topic.value, symmetricKey)
33+
override fun getSymmetricKey(tag: String): SymmetricKey {
34+
val key = keyChain.getKey(tag) ?: throw MissingKeyException("No PublicKey for tag: $tag")
35+
return SymmetricKey(key)
3536
}
3637

37-
override fun getSymmetricKey(topic: Topic): SymmetricKey {
38-
val symmetricKey = keyChain.getKey(topic.value)
38+
override fun getKeyAgreement(topic: Topic): Pair<PublicKey, PublicKey> {
39+
val tag = "$KEY_AGREEMENT_CONTEXT${topic.value}"
40+
val (selfPublic, peerPublic) = keyChain.getKeys(tag)
41+
42+
return Pair(PublicKey(selfPublic), PublicKey(peerPublic))
43+
}
3944

40-
return SymmetricKey(symmetricKey)
45+
override fun setKeyAgreement(topic: Topic, self: PublicKey, peer: PublicKey) {
46+
val tag = "$KEY_AGREEMENT_CONTEXT${topic.value}"
47+
keyChain.setKeys(tag, self, peer)
4148
}
4249

4350
override fun generateKeyPair(): PublicKey {
4451
val publicKey = ByteArray(KEY_SIZE)
4552
val privateKey = ByteArray(KEY_SIZE)
4653
X25519.generatePrivateKey(SecureRandom(ByteArray(KEY_SIZE)), privateKey)
4754
X25519.generatePublicKey(privateKey, 0, publicKey, 0)
48-
setKeyPair(PublicKey(publicKey.bytesToHex().lowercase()), PrivateKey(privateKey.bytesToHex().lowercase()))
4955

56+
setKeyPair(PublicKey(publicKey.bytesToHex().lowercase()), PrivateKey(privateKey.bytesToHex().lowercase()))
5057
return PublicKey(publicKey.bytesToHex().lowercase())
5158
}
5259

53-
override fun generateTopicFromKeyAgreement(self: PublicKey, peer: PublicKey): Topic {
54-
val symmetricKey = generateSymmetricKeyFromKeyAgreement(self, peer)
55-
val topic = Topic(sha256(symmetricKey.keyAsHex))
56-
keyChain.setKey(topic.value.lowercase(), symmetricKey)
57-
setKeyAgreement(topic, self, peer)
58-
59-
return topic
60-
}
61-
62-
override fun getTopicFromKey(key: WCKey): Topic = Topic(sha256(key.keyAsHex))
63-
64-
override fun setSelfParticipant(key: PublicKey, topic: Topic) {
65-
val tag = "$SELF_PARTICIPANT_CONTEXT${topic.value}"
66-
keyChain.setKey(tag, key)
67-
}
68-
69-
override fun getSelfParticipant(topic: Topic): PublicKey? {
70-
val keyAsHex = keyChain.getKey("$SELF_PARTICIPANT_CONTEXT${topic.value}")
71-
return if (keyAsHex == String.Empty) null else PublicKey(keyAsHex)
60+
override fun generateAndStoreSymmetricKey(topic: Topic): SymmetricKey {
61+
val symmetricKey = SymmetricKey(createSymmetricKey().bytesToHex())
62+
keyChain.setKey(topic.value, symmetricKey)
63+
return symmetricKey
7264
}
7365

7466
override fun generateSymmetricKeyFromKeyAgreement(self: PublicKey, peer: PublicKey): SymmetricKey {
@@ -81,6 +73,16 @@ internal class BouncyCastleKeyManagementRepository(private val keyChain: KeyStor
8173
return SymmetricKey(symmetricKeyBytes.bytesToHex())
8274
}
8375

76+
override fun generateTopicFromKeyAgreement(self: PublicKey, peer: PublicKey): Topic {
77+
val symmetricKey = generateSymmetricKeyFromKeyAgreement(self, peer)
78+
val topic = Topic(sha256(symmetricKey.keyAsHex))
79+
keyChain.setKey(topic.value.lowercase(), symmetricKey)
80+
setKeyAgreement(topic, self, peer)
81+
return topic
82+
}
83+
84+
override fun getTopicFromKey(key: Key): Topic = Topic(sha256(key.keyAsHex))
85+
8486
override fun removeKeys(tag: String) {
8587
val (publicKey, _) = keyChain.getKeys(tag)
8688
with(keyChain) {
@@ -89,23 +91,11 @@ internal class BouncyCastleKeyManagementRepository(private val keyChain: KeyStor
8991
}
9092
}
9193

92-
override fun getKeyAgreement(topic: Topic): Pair<PublicKey, PublicKey> {
93-
val tag = "$KEY_AGREEMENT_CONTEXT${topic.value}"
94-
val (selfPublic, peerPublic) = keyChain.getKeys(tag)
95-
96-
return Pair(PublicKey(selfPublic), PublicKey(peerPublic))
97-
}
98-
99-
private fun setKeyAgreement(topic: Topic, self: PublicKey, peer: PublicKey) {
100-
val tag = "$KEY_AGREEMENT_CONTEXT${topic.value}"
101-
keyChain.setKeys(tag, self, peer)
102-
}
103-
10494
internal fun setKeyPair(publicKey: PublicKey, privateKey: PrivateKey) {
10595
keyChain.setKeys(publicKey.keyAsHex, publicKey, privateKey)
10696
}
10797

108-
internal fun getKeyPair(wcKey: WCKey): Pair<PublicKey, PrivateKey> {
98+
internal fun getKeyPair(wcKey: Key): Pair<PublicKey, PrivateKey> {
10999
val (publicKeyHex, privateKeyHex) = keyChain.getKeys(wcKey.keyAsHex)
110100

111101
return Pair(PublicKey(publicKeyHex), PrivateKey(privateKeyHex))
@@ -145,6 +135,5 @@ internal class BouncyCastleKeyManagementRepository(private val keyChain: KeyStor
145135
const val AES: String = "AES"
146136

147137
const val KEY_AGREEMENT_CONTEXT = "key_agreement/"
148-
const val SELF_PARTICIPANT_CONTEXT = "self_participant/"
149138
}
150139
}

androidCore/impl/src/main/kotlin/com/walletconnect/android/impl/json_rpc/domain/JsonRpcInteractor.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ internal class JsonRpcInteractor(
2828
private val chaChaPolyCodec: Codec,
2929
private val jsonRpcHistory: JsonRpcHistory,
3030
) : JsonRpcInteractorInterface {
31-
private val serializer: JsonRpcSerializer
32-
get() = wcKoinApp.koin.get()
31+
private val serializer: JsonRpcSerializer get() = wcKoinApp.koin.get()
3332

3433
private val _clientSyncJsonRpc: MutableSharedFlow<WCRequest> = MutableSharedFlow()
3534
override val clientSyncJsonRpc: SharedFlow<WCRequest> = _clientSyncJsonRpc.asSharedFlow()
@@ -57,7 +56,7 @@ internal class JsonRpcInteractor(
5756
}
5857
}
5958

60-
override fun publishJsonRpcRequests(
59+
override fun publishJsonRpcRequest(
6160
topic: Topic,
6261
params: IrnParams,
6362
payload: JsonRpcClientSync<*>,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.walletconnect.android.impl.utils
2+
3+
const val SELF_PARTICIPANT_CONTEXT = "self_participant/"
4+
const val SELF_INVITE_PUBLIC_KEY_CONTEXT = "self_inviteKey/"

androidCore/impl/src/main/kotlin/com/walletconnect/android/impl/utils/UtilFunctions.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
package com.walletconnect.utils
44

5-
import com.walletconnect.android.impl.di.AndroidCoreDITags
65
import com.walletconnect.android.impl.utils.CURRENT_TIME_IN_SECONDS
7-
import com.walletconnect.android.impl.utils.Logger
86
import com.walletconnect.android.internal.common.SerializableJsonRpc
97
import com.walletconnect.android.internal.common.model.Expiry
108
import org.koin.core.module.KoinDefinition
@@ -32,12 +30,7 @@ val String.Companion.HexPrefix
3230
get() = "0x"
3331

3432
inline fun <reified T : SerializableJsonRpc> Module.addSerializerEntry(value: KClass<T>): KoinDefinition<*> =
35-
single(qualifier = named("key_${T::class.getFullName()}")) {
36-
value
37-
}
38-
33+
single(qualifier = named("key_${T::class.getFullName()}")) { value }
3934

4035
fun Module.addDeserializerEntry(key: String, value: KClass<*>): KoinDefinition<*> =
41-
single(qualifier = named("${key::class.getFullName()}_${value::class.getFullName()}_$key")) {
42-
key to value
43-
}
36+
single(qualifier = named("${key::class.getFullName()}_${value::class.getFullName()}_$key")) { key to value }

androidCore/impl/src/test/kotlin/com/walletconnect/android/impl/BouncyCastleCryptoRepositoryTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal class BouncyCastleCryptoRepositoryTest {
4444
val symKey = sut.generateAndStoreSymmetricKey(topicVO)
4545
assert(symKey.keyAsHex.length == 64)
4646

47-
val secretKey = sut.getSymmetricKey(topicVO)
47+
val secretKey = sut.getSymmetricKey(topicVO.value)
4848
assertEquals(symKey.keyAsHex, secretKey.keyAsHex)
4949
assert(secretKey.keyAsHex.length == 64)
5050
}
@@ -99,12 +99,12 @@ internal class BouncyCastleCryptoRepositoryTest {
9999
fun `Generated SymmetricKey gets removed when using a TopicVO as the tag for removeKeys`() {
100100
val symKey = sut.generateAndStoreSymmetricKey(topicVO)
101101

102-
val secretKey = sut.getSymmetricKey(topicVO)
102+
val secretKey = sut.getSymmetricKey(topicVO.value)
103103
assertEquals(symKey.keyAsHex, secretKey.keyAsHex)
104104

105105
sut.removeKeys(topicVO.value)
106106

107-
val secretKeyAfterRemoval = sut.getSymmetricKey(topicVO)
107+
val secretKeyAfterRemoval = sut.getSymmetricKey(topicVO.value)
108108
assertEquals(String.Empty, secretKeyAfterRemoval.keyAsHex)
109109
}
110110
}

0 commit comments

Comments
 (0)