mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 03:15:35 -04:00
wip MessageSigner3
This commit is contained in:
parent
556f564591
commit
28d10a2e81
@ -15,13 +15,14 @@ package de.bixilon.minosoft.data.chat.signature
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigner
|
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigner
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.versions.Version
|
import de.bixilon.minosoft.protocol.versions.Version
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MessageChain(version: Version) {
|
class MessageChain(version: Version, connection: PlayConnection) {
|
||||||
val signer = MessageSigner.forVersion(version)
|
val signer = MessageSigner.forVersion(version, connection)
|
||||||
|
|
||||||
fun signMessage(privateKey: PrivateKey, message: String, preview: ChatComponent?, salt: Long, sender: UUID, time: Instant, lastSeen: LastSeenMessageList): ByteArray {
|
fun signMessage(privateKey: PrivateKey, message: String, preview: ChatComponent?, salt: Long, sender: UUID, time: Instant, lastSeen: LastSeenMessageList): ByteArray {
|
||||||
return signer.signMessage(privateKey, message, preview, salt, sender, time, lastSeen)
|
return signer.signMessage(privateKey, message, preview, salt, sender, time, lastSeen)
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.data.chat.signature
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class MessageLink(
|
||||||
|
val index: Int,
|
||||||
|
val sender: UUID,
|
||||||
|
val sessionId: UUID,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun next(): MessageLink {
|
||||||
|
// TODO: check Int.MAX_VALUE
|
||||||
|
return MessageLink(index + 1, sender, sessionId)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* Minosoft
|
||||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
@ -18,4 +18,4 @@ import java.time.Instant
|
|||||||
class MessageExpiredError(
|
class MessageExpiredError(
|
||||||
val sent: Instant,
|
val sent: Instant,
|
||||||
val received: Instant,
|
val received: Instant,
|
||||||
) : Exception("Message expired: Sent at $sent, but received to late at $received")
|
) : Exception("Message expired: Sent at $sent, but received too late at $received")
|
||||||
|
@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.chat.signature.signer
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
||||||
import de.bixilon.minosoft.protocol.versions.Version
|
import de.bixilon.minosoft.protocol.versions.Version
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
@ -28,14 +29,14 @@ interface MessageSigner {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun forVersion(version: Version): MessageSigner {
|
fun forVersion(version: Version, connection: PlayConnection): MessageSigner {
|
||||||
if (version < ProtocolVersions.V_1_19_1_PRE4) {
|
if (version < ProtocolVersions.V_1_19_1_PRE4) {
|
||||||
return MessageSigner1(version)
|
return MessageSigner1(version)
|
||||||
}
|
}
|
||||||
if (version < ProtocolVersions.V_22W42A) {
|
if (version < ProtocolVersions.V_22W42A) {
|
||||||
return MessageSigner2(version)
|
return MessageSigner2(version)
|
||||||
}
|
}
|
||||||
return MessageSigner3(version)
|
return MessageSigner3(version, connection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
package de.bixilon.minosoft.data.chat.signature.signer
|
package de.bixilon.minosoft.data.chat.signature.signer
|
||||||
|
|
||||||
import com.google.common.hash.Hashing
|
import com.google.common.hash.Hashing
|
||||||
import com.google.common.primitives.Longs
|
|
||||||
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
||||||
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigningUtil.getSignatureBytes
|
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigningUtil.getSignatureBytes
|
||||||
|
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigningUtil.update
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
import de.bixilon.minosoft.protocol.protocol.OutByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.OutByteBuffer
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
||||||
@ -59,8 +59,7 @@ class MessageSigner2(
|
|||||||
val hash = Hashing.sha256().hashBytes(buffer.toArray()).asBytes()
|
val hash = Hashing.sha256().hashBytes(buffer.toArray()).asBytes()
|
||||||
|
|
||||||
previous?.let { signature.update(it) }
|
previous?.let { signature.update(it) }
|
||||||
signature.update(Longs.toByteArray(sender.mostSignificantBits))
|
signature.update(sender)
|
||||||
signature.update(Longs.toByteArray(sender.leastSignificantBits))
|
|
||||||
signature.update(hash)
|
signature.update(hash)
|
||||||
|
|
||||||
return signature.sign()
|
return signature.sign()
|
||||||
|
@ -13,8 +13,15 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.chat.signature.signer
|
package de.bixilon.minosoft.data.chat.signature.signer
|
||||||
|
|
||||||
|
import com.google.common.primitives.Ints
|
||||||
|
import com.google.common.primitives.Longs
|
||||||
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
import de.bixilon.minosoft.data.chat.signature.LastSeenMessageList
|
||||||
|
import de.bixilon.minosoft.data.chat.signature.MessageLink
|
||||||
|
import de.bixilon.minosoft.data.chat.signature.signer.MessageSigningUtil.update
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.encryption.CryptManager
|
||||||
import de.bixilon.minosoft.protocol.versions.Version
|
import de.bixilon.minosoft.protocol.versions.Version
|
||||||
import java.security.PrivateKey
|
import java.security.PrivateKey
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -22,9 +29,41 @@ import java.util.*
|
|||||||
|
|
||||||
class MessageSigner3(
|
class MessageSigner3(
|
||||||
private val version: Version,
|
private val version: Version,
|
||||||
|
private val connection: PlayConnection,
|
||||||
) : MessageSigner {
|
) : MessageSigner {
|
||||||
|
private var link: MessageLink = MessageLink(0, connection.account.uuid, connection.sessionId)
|
||||||
|
|
||||||
override fun signMessage(privateKey: PrivateKey, message: String, preview: ChatComponent?, salt: Long, sender: UUID, time: Instant, lastSeen: LastSeenMessageList): ByteArray {
|
override fun signMessage(privateKey: PrivateKey, message: String, preview: ChatComponent?, salt: Long, sender: UUID, time: Instant, lastSeen: LastSeenMessageList): ByteArray {
|
||||||
TODO("Not yet implemented!")
|
val signature = CryptManager.createSignature(version)
|
||||||
|
|
||||||
|
signature.initSign(privateKey)
|
||||||
|
|
||||||
|
signature.update(Ints.toByteArray(1))
|
||||||
|
|
||||||
|
val link = nextLink()
|
||||||
|
signature.update(link.sender)
|
||||||
|
signature.update(link.sessionId)
|
||||||
|
signature.update(Ints.toByteArray(link.index))
|
||||||
|
|
||||||
|
// message body
|
||||||
|
signature.update(Longs.toByteArray(salt))
|
||||||
|
signature.update(Longs.toByteArray(time.epochSecond))
|
||||||
|
val encoded = message.encodeNetwork()
|
||||||
|
signature.update(Ints.toByteArray(encoded.size))
|
||||||
|
signature.update(encoded)
|
||||||
|
|
||||||
|
signature.update(Ints.toByteArray(lastSeen.messages.size))
|
||||||
|
|
||||||
|
for (lastSeenMessage in lastSeen.messages) {
|
||||||
|
signature.update(lastSeenMessage.signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return signature.sign()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun nextLink(): MessageLink {
|
||||||
|
this.link = this.link.next()
|
||||||
|
return this.link
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,19 @@
|
|||||||
package de.bixilon.minosoft.data.chat.signature.signer
|
package de.bixilon.minosoft.data.chat.signature.signer
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.io.JsonStringEncoder
|
import com.fasterxml.jackson.core.io.JsonStringEncoder
|
||||||
|
import com.google.common.primitives.Longs
|
||||||
import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork
|
import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork
|
||||||
|
import java.security.Signature
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
object MessageSigningUtil {
|
object MessageSigningUtil {
|
||||||
|
|
||||||
fun String.getSignatureBytes(): ByteArray {
|
fun String.getSignatureBytes(): ByteArray {
|
||||||
return """{"text":"${String(JsonStringEncoder.getInstance().quoteAsString(this))}"}""".encodeNetwork()
|
return """{"text":"${String(JsonStringEncoder.getInstance().quoteAsString(this))}"}""".encodeNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Signature.update(uuid: UUID) {
|
||||||
|
update(Longs.toByteArray(uuid.mostSignificantBits))
|
||||||
|
update(Longs.toByteArray(uuid.leastSignificantBits))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ import java.time.Instant
|
|||||||
class ConnectionUtil(
|
class ConnectionUtil(
|
||||||
private val connection: PlayConnection,
|
private val connection: PlayConnection,
|
||||||
) {
|
) {
|
||||||
private val chain = MessageChain(connection.version)
|
private val chain = MessageChain(connection.version, connection)
|
||||||
private val random = SecureRandom()
|
private val random = SecureRandom()
|
||||||
|
|
||||||
fun sendDebugMessage(message: Any) {
|
fun sendDebugMessage(message: Any) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user