Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] update login protocol #2613

Merged
merged 62 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
81e9fea
[core] update protocol
Apr 8, 2023
d1846b4
[core] fix t106 decryption key
Apr 9, 2023
cdf88c7
[core] handle t543
Apr 9, 2023
3818438
[core] revert t106
Apr 9, 2023
d0ef92d
[core] revert native test pow data
Apr 9, 2023
ac7407e
[core] split build version and apk version name
Apr 9, 2023
7987473
[core] pass time to t1 instead of time diff
Apr 10, 2023
d52ddea
[core] remove unused t106 writer & rename param ip to ipv4 of t1 and …
Apr 10, 2023
39f13bc
[core] implement qimei for t545
Apr 10, 2023
434db6e
[core] fix base64 decode for android in rsa
Apr 11, 2023
e2440f3
[core] fix unix timestamp parsing on native and add more tests
Apr 11, 2023
61b7006
[api] DeviceInfo move `androidId` to main constructor and adjust test.
Apr 11, 2023
db8bbab
[api] do not request qimei when protocol is neither ANDROID_PHONE no…
Apr 11, 2023
ef2e980
[api] implement aes crypto for native target
Apr 11, 2023
388165e
[api] rsa crypto for multi-platform
Apr 13, 2023
b5fd8ac
[api] crypto test
Apr 13, 2023
2fd3e25
[api] move freePointer util
Apr 13, 2023
db7e931
[api] openssl api compatibility
Apr 13, 2023
a6b4fee
[core] add explicit `androidId` param
Apr 13, 2023
3cd9c0e
[core] remove unused `tlvCount`
Apr 13, 2023
153082f
[core] optimize crypto
Apr 13, 2023
a1d4dd7
[core] move Qimei to network package
Apr 13, 2023
79d34d7
[core] move appId to protocol
Apr 13, 2023
184932a
[core] lazily initialize qimeiLogger
Apr 13, 2023
e8f709c
[core] write byte array to BIO mem
Apr 13, 2023
54976ed
[core] move qimei to client, add direct serializer for DeviceInfo
Apr 14, 2023
0e368b3
[core] optimize DeviceInfoDelegateSerializer
Apr 14, 2023
1088054
[core] real user-agent when requesting qimei
Apr 14, 2023
804677f
[core] use `DeviceInfo.version.release`
Apr 15, 2023
ae06319
[core] remove unused wtlogin packet
Apr 15, 2023
749b8d8
[core] do what constructor serializer should do
Apr 15, 2023
de3c6ab
[core] fix endless cache validation caused by not upgrading device in…
Apr 15, 2023
6c5d2b8
[core] request qimei before fast-login
Apr 15, 2023
d0bfbbf
[core] tlv order
Apr 15, 2023
e81873b
[core] remove wrong tests and print more detail when deserialize failed.
Apr 15, 2023
dda3e89
[core] device info upgrade for native
Apr 15, 2023
b2fe32b
[core] request qimei after validating cache
Apr 15, 2023
96c53e4
Merge remote-tracking branch 'mamoe/dev' into dev
Apr 16, 2023
d0ad083
[core] DeviceInfo compatibility
Apr 16, 2023
5a3f459
[core] DeviceInfo test name
Apr 16, 2023
909767d
[core] compatibility serializer
Apr 16, 2023
ea7040f
Merge remote-tracking branch 'mamoe/dev' into protocol
May 4, 2023
128858e
[core] disable rsa crypto test on android unit test
May 5, 2023
209dfac
[core] move rsa impl to jvmBase
May 6, 2023
632e654
action
May 6, 2023
f862578
Merge branch 'dev' into dev
StageGuard May 6, 2023
0a43f8b
import
May 6, 2023
09f3250
api dump
May 6, 2023
436ff0f
api dump
May 6, 2023
5471a28
Merge branch 'dev' into dev
StageGuard May 6, 2023
c926c4d
revert wrong api dumps
May 7, 2023
1a163aa
[core] Deprecate DeviceInfo constructor and serializer, provide `seri…
Him188 May 8, 2023
86298a0
rerun ci
Him188 May 8, 2023
f090916
optimize
May 7, 2023
9cd9ef5
use serializer directly
May 8, 2023
6fc32ea
optimize test
May 8, 2023
4ee05ff
revert
May 8, 2023
c275dd1
[core] CacheValidator use `DeviceInfo.serializeToString()` instead of…
May 10, 2023
832267f
Remove `println` in `DeviceInfoManager`
Him188 May 20, 2023
89c3d1a
Add legacy deserialize overload for ABI compatibility
Him188 May 20, 2023
60a8537
Remove uncompleted docs for DeviceInfo
Him188 May 20, 2023
271a5e0
Suppress DeviceInfo deprecation warnings for internal usages
Him188 May 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[core] optimize crypto
  • Loading branch information
StageGuard committed Apr 13, 2023
commit 153082f0a5e0e8c875a5f772889542bdd6c56c1a
16 changes: 8 additions & 8 deletions mirai-core/src/androidMain/kotlin/utils/crypto/RSAAndroid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher

internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, pubPemKey: ByteArray, seed: Long): ByteArray {
val encodedKey = pubPemKey.decodeToString()
internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, plainPubPemKey: String, seed: Long): ByteArray {
Him188 marked this conversation as resolved.
Show resolved Hide resolved
val encodedKey = plainPubPemKey
.replace("\n", "")
.removePrefix("-----BEGIN PUBLIC KEY-----")
.removeSuffix("-----END PUBLIC KEY-----")
Expand All @@ -36,8 +36,8 @@ internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, pubPemKey: ByteAr
return cipher.doFinal(input)
}

internal actual fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, privPemKey: ByteArray, seed: Long): ByteArray {
val encodedKey = privPemKey.decodeToString()
internal actual fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, plainPrivPemKey: String, seed: Long): ByteArray {
val encodedKey = plainPrivPemKey
.replace("\n", "")
.removePrefix("-----BEGIN PRIVATE KEY-----")
.removeSuffix("-----END PRIVATE KEY-----")
Expand All @@ -60,15 +60,15 @@ internal actual fun generateRSAKeyPair(keySize: Int): RSAKeyPair {

val keyPair = keyGen.generateKeyPair()
return RSAKeyPair(
pubPemKey = buildString {
plainPubPemKey = buildString {
appendLine("-----BEGIN PUBLIC KEY-----")
keyPair.public.encoded.encodeBase64().chunked(64).forEach(::appendLine)
appendLine("-----END PUBLIC KEY-----")
}.encodeToByteArray(),
privPemKey = buildString {
},
plainPrivPemKey = buildString {
appendLine("-----BEGIN PRIVATE KEY-----")
keyPair.private.encoded.encodeBase64().chunked(64).forEach(::appendLine)
appendLine("-----END PRIVATE KEY-----")
}.encodeToByteArray()
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/

package net.mamoe.mirai.internal.network.protocol.packet.login.wtlogin

import io.ktor.utils.io.core.*
import net.mamoe.mirai.internal.network.*
import net.mamoe.mirai.internal.network.protocol.packet.*
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.utils.GuidSource
import net.mamoe.mirai.internal.utils.MacOrAndroidIdChangeFlag
import net.mamoe.mirai.internal.utils.guidFlag
import net.mamoe.mirai.utils._writeTlvMap
import net.mamoe.mirai.utils.generateDeviceInfoData

internal object WtLogin24 : WtLoginExt {
StageGuard marked this conversation as resolved.
Show resolved Hide resolved
private val appId = 16L

operator fun invoke(
client: QQAndroidClient,
isSmsLogin: Boolean,
): OutgoingPacketWithRespType<WtLogin.Login.LoginPacketResponse> {
return WtLogin.Login.buildLoginOutgoingPacket(
client,
bodyType = 2,
remark = "24:get-salt-uin-list",
) { sequenceId ->
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, uin = 0, commandId = 0x0810) {
writeShort(24)
_writeTlvMap {
t8()
t18(appId, client.appClientVersion, 0, 0)
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)

t104(client.t104)

t108(client.ksid)
t109(client.device.androidId)
t116(client.miscBitMap, client.subSigMap)
tlv(0x11b) { writeByte(2) }
t124(
osType = client.device.osType,
osVersion = client.device.version.release,
networkType = client.networkType,
simInfo = client.device.simInfo,
address = byteArrayOf(),
apn = client.device.apn,
)
t128(
isGuidFromFileNull = false,
isGuidAvailable = true,
isGuidChanged = false,
guidFlag = guidFlag(GuidSource.FROM_STORAGE, MacOrAndroidIdChangeFlag(0)),
buildModel = client.device.model,
guid = client.device.guid,
buildBrand = client.device.brand,
)

t142(client.apkId)
t145(client.device.guid)
t147(appId, client.apkVersionName, client.apkSignatureMd5)

t154(sequenceId)
t16e(client.device.model)

client.rollbackSig?.let { t172(it) }

t177(client.buildTime, client.sdkVersion)
t202(client.device.wifiBSSID, client.device.wifiSSID)

t400(
g = client.G,
uin = 0,
guid = client.device.guid,
dpwd = client.dpwd,
appId = 1,
subAppId = 16,
randomSeed = client.randSeed
)

t521()
t525(client.loginExtraData)
t52d(client.device.generateDeviceInfoData())
t544() // TODO
// ignored cuz qiemiListener is null
// tlv(0x545) { }
//tlv(0x548) { writeFully(powTestData) }
}
}
}
}
}
}
28 changes: 6 additions & 22 deletions mirai-core/src/commonMain/kotlin/utils/crypto/RSA.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,13 @@

package net.mamoe.mirai.internal.utils.crypto

internal data class RSAKeyPair(
val pubPemKey: ByteArray,
val privPemKey: ByteArray
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as RSAKeyPair

if (!pubPemKey.contentEquals(other.pubPemKey)) return false
return privPemKey.contentEquals(other.privPemKey)
}

override fun hashCode(): Int {
var result = pubPemKey.contentHashCode()
result = 31 * result + privPemKey.contentHashCode()
return result
}
}
internal class RSAKeyPair(
val plainPubPemKey: String,
val plainPrivPemKey: String
)

internal expect fun generateRSAKeyPair(keySize: Int): RSAKeyPair

internal expect fun rsaEncryptWithX509PubKey(input: ByteArray, pubPemKey: ByteArray, seed: Long): ByteArray
internal expect fun rsaEncryptWithX509PubKey(input: ByteArray, plainPubPemKey: String, seed: Long): ByteArray

internal expect fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, privPemKey: ByteArray, seed: Long): ByteArray
internal expect fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, plainPrivPemKey: String, seed: Long): ByteArray
52 changes: 24 additions & 28 deletions mirai-core/src/commonTest/kotlin/utils/crypto/RSATest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,41 @@

package net.mamoe.mirai.internal.utils.crypto

import net.mamoe.mirai.utils.currentTimeMillis
import net.mamoe.mirai.utils.toUHexString
import kotlin.random.Random
import kotlin.math.pow
import kotlin.test.Test
import kotlin.test.assertEquals

class RSATest {
@Test
fun `can gen rsa key pair`() {
val rsaKeyPair = generateRSAKeyPair(2048)
println(rsaKeyPair.pubPemKey.decodeToString())
println(rsaKeyPair.privPemKey.decodeToString())
repeat(4) { exp ->
StageGuard marked this conversation as resolved.
Show resolved Hide resolved
val keySize = 2.0.pow(9 + exp).toInt()
val rsaKeyPair = generateRSAKeyPair(keySize)
println("RSA keygen test #${exp + 1}: keySize = $keySize")
println(rsaKeyPair.plainPubPemKey)
println(rsaKeyPair.plainPrivPemKey)
}
}

@Test
fun `can do crypto with generated key`() {
val keyPair = generateRSAKeyPair(2048)

val random = Random(currentTimeMillis())
repeat(5) {
val keyPair = generateRSAKeyPair(2048)
val currentTime = currentTimeMillis()

val plainText = buildString {
append("Use of this source code is governed by the GNU AGPLv3 license ")
append(currentTime)
}
val plainText = buildString {
append("Use of this source code is governed by the GNU AGPLv3 license ")
append("that can be found through the following link. ")
}

println(
"RSA crypto test #${it + 1}: pubKey = ${keyPair.pubPemKey.decodeToString()}, " +
"privKey = ${keyPair.privPemKey.decodeToString()}, currentTimeMillis = $currentTime"
)
val enc =
rsaEncryptWithX509PubKey(plainText.encodeToByteArray(), keyPair.pubPemKey, random.nextLong(currentTime))
println("rsa encrypt: data=${enc.toUHexString()}")
val decrypted = rsaDecryptWithPKCS8PrivKey(enc, keyPair.privPemKey, random.nextLong(currentTime))
println("rsa decrypt: data=${decrypted.toUHexString()}")
println(
"RSA crypto test: plainTextLength: ${plainText.length}, " +
"pubKey = ${keyPair.plainPubPemKey}, " +
"privKey = ${keyPair.plainPrivPemKey}"
)
val enc = rsaEncryptWithX509PubKey(plainText.encodeToByteArray(), keyPair.plainPubPemKey, 0)
println("rsa encrypt: data size=${enc.size}")
val decrypted = rsaDecryptWithPKCS8PrivKey(enc, keyPair.plainPrivPemKey, 0)

assertEquals(plainText, decrypted.decodeToString())
}
assertEquals(plainText, decrypted.decodeToString())
}

@Test
Expand All @@ -62,7 +58,7 @@ KP1dfqZ3PrK8QBH6su0GlB8onYFtzDUckr2wCrrJ1cR4L1Dg5f2egE75l1cliAIM
eU8vpIlLP/9W5nkdqF6CWzjE3dIx2btOH4QDDyogDSLRAvcKN5/1EIZeu2FTbw9k
3QIDAQAB
-----END PUBLIC KEY-----
""".trimIndent().encodeToByteArray()
""".trimIndent()

val privKey = """
-----BEGIN PRIVATE KEY-----
Expand Down Expand Up @@ -93,7 +89,7 @@ rz6d6RB+i1Q7ExBK7lbZxN17HmKiOewwI772zEo28IY9sIHugV7rW1vQVs3bnzgk
ExDGjYWZSKHfs+3mvrLNRIx/IsVqqwlXt5oO9TspSh68ASvmXN51dmduxRrSuScq
8a49uOr675SyFCJTIdF/Ag==
-----END PRIVATE KEY-----
""".trimIndent().encodeToByteArray()
""".trimIndent()

val plainText = buildString {
append("Use of this source code is governed by the GNU AGPLv3 license ")
Expand Down
17 changes: 8 additions & 9 deletions mirai-core/src/jvmMain/kotlin/utils/crypto/RSAJvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipher


internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, pubPemKey: ByteArray, seed: Long): ByteArray {
val encodedKey = pubPemKey.decodeToString()
internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, plainPubPemKey: String, seed: Long): ByteArray {
val encodedKey = plainPubPemKey
.replace("\n", "")
.removePrefix("-----BEGIN PUBLIC KEY-----")
.removeSuffix("-----END PUBLIC KEY-----")
Expand All @@ -37,8 +36,8 @@ internal actual fun rsaEncryptWithX509PubKey(input: ByteArray, pubPemKey: ByteAr
return cipher.doFinal(input)
}

internal actual fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, privPemKey: ByteArray, seed: Long): ByteArray {
val encodedKey = privPemKey.decodeToString()
internal actual fun rsaDecryptWithPKCS8PrivKey(input: ByteArray, plainPrivPemKey: String, seed: Long): ByteArray {
val encodedKey = plainPrivPemKey
.replace("\n", "")
.removePrefix("-----BEGIN PRIVATE KEY-----")
.removeSuffix("-----END PRIVATE KEY-----")
Expand All @@ -61,15 +60,15 @@ internal actual fun generateRSAKeyPair(keySize: Int): RSAKeyPair {

val keyPair = keyGen.generateKeyPair()
return RSAKeyPair(
pubPemKey = buildString {
plainPubPemKey = buildString {
appendLine("-----BEGIN PUBLIC KEY-----")
keyPair.public.encoded.encodeBase64().chunked(64).forEach(::appendLine)
appendLine("-----END PUBLIC KEY-----")
}.encodeToByteArray(),
privPemKey = buildString {
},
plainPrivPemKey = buildString {
appendLine("-----BEGIN PRIVATE KEY-----")
keyPair.private.encoded.encodeBase64().chunked(64).forEach(::appendLine)
appendLine("-----END PRIVATE KEY-----")
}.encodeToByteArray()
}
)
}
Loading