diff --git a/doc/Updater.md b/doc/Updater.md index 05678d2c1..e23c65d4e 100644 --- a/doc/Updater.md +++ b/doc/Updater.md @@ -29,7 +29,7 @@ Otherwise it responds with `200 OK` and returns a json object (with the signatur "url": "https:// where to download it", "size": , "sha512": "SHA512 hash of the binary", - "signature": "Release signature" + "signature": "SHA512withRSA signature of the binary" }, "release_notes": "" } @@ -45,10 +45,6 @@ Once it is downloaded, minosoft asks the user to restart. It will then quit and The client will refuse to update, if the release date of the next version is lower than the version currently running (i.e. no downgrades) -## Signature - -The first line of the file is the base64 encoded signature of the whole json object. - ## Future - Maybe split the fat jar and download all dependencies individual (reduces size of the binary; lowers traffic) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/updater/MinosoftUpdaterTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/updater/MinosoftUpdaterTest.kt index bdbab723d..1af0f39ca 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/updater/MinosoftUpdaterTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/updater/MinosoftUpdaterTest.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -13,26 +13,27 @@ package de.bixilon.minosoft.updater -import org.testng.Assert.assertThrows import org.testng.annotations.Test @Test(groups = ["updater"]) class MinosoftUpdaterTest { - private fun verify(signature: String, data: String) { - MinosoftUpdater.parse(signature + "\n" + data) + /* + private fun verify(data: String) { + MinosoftUpdater.parse(data) } fun `verify broken signature`() { - assertThrows { verify("NOT_VALID", """{"id":"dummy","name":"Dummy version","date":-1,"stable":true,"page":null,"download":{"url":"https://bixilon.de/secret-update.jar","size":123,"sha512":"b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee"},"release_notes":":)"}""") } + assertThrows { verify("""{"id":"dummy","name":"Dummy version","date":-1,"stable":true,"page":null,"download":{"url":"https://bixilon.de/secret-update.jar","size":123,"sha512":"b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee"},"release_notes":":)"}""", "NOT_VALID") } } fun `verify correct signature`() { assertThrows { verify( - "Mv7979ky1AlMCcOLmX+Zdmo2Y7YOGiMthTBeNP2jKUPRkMtX1GCBYMrsKV+si9rR9Kg+1Ns82Hw1iYAI+ZOkTzVmoIeaWkqL4PN4sCCVllm2ZmZhTap7wdNAVEjW197Cf+V2YJW0TsG+j2s6OK86gdtVmyJ96X/ENhXTJRp8pW50lcCyy95ipQ1Qe8v4mAFykpU9XC/yU2Mhil/KznxvxKgd7N4+/VNpubOHetWfdiz9jqAB6uaYVi0H9E+EoZodkG3Iy5uagr1OrWNiwjk3LQUEk+J+5cYRPqBHrqLM9VNQFa5BqysSJoW7cIo/QUQA47EBxO8Rmg/juFA1l9bXtSUA+1j12n9ImhE/L3cYseYiIN8GFRpbhSaROgfZW9u3lVHM4g45q67zvvdf+Eo7lqfipYio89rQ984U58o5AvLhV+WqhDVRBTTtO+oI/FjdiHIruoiY/adEz7gJEAlrMlgoAAQkVnKma9uufObIemL+QGpDjLvdluIgts/cT34r4I5Xaij1vGAjzZ+Fe+Tn5tuW48pjtjWCzAwVTEu/zf/VKSJPoCVGx5YCvFE3CKXkVWuJ86gj+rO/SXWkjv672EetaVwv2Uc/RkCfru84m6bQWAHzb3P46Hfkw3kIyaIudxgizy1xlxLEEU3LwUU/vFxTd2Q6lAhGGMn6Imy9Z6I=", - """{"id":"dummy","name":"Dummy version","date":-1,"stable":true,"page":null,"download":{"url":"https://bixilon.de/secret-update.jar","size":123,"sha512":"b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee"},"release_notes":":)"}""") + """{"id":"dummy","name":"Dummy version","date":-1,"stable":true,"page":null,"download":{"url":"https://bixilon.de/secret-update.jar","size":123,"sha512":"b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee"},"release_notes":":)"}""", + "Mv7979ky1AlMCcOLmX+Zdmo2Y7YOGiMthTBeNP2jKUPRkMtX1GCBYMrsKV+si9rR9Kg+1Ns82Hw1iYAI+ZOkTzVmoIeaWkqL4PN4sCCVllm2ZmZhTap7wdNAVEjW197Cf+V2YJW0TsG+j2s6OK86gdtVmyJ96X/ENhXTJRp8pW50lcCyy95ipQ1Qe8v4mAFykpU9XC/yU2Mhil/KznxvxKgd7N4+/VNpubOHetWfdiz9jqAB6uaYVi0H9E+EoZodkG3Iy5uagr1OrWNiwjk3LQUEk+J+5cYRPqBHrqLM9VNQFa5BqysSJoW7cIo/QUQA47EBxO8Rmg/juFA1l9bXtSUA+1j12n9ImhE/L3cYseYiIN8GFRpbhSaROgfZW9u3lVHM4g45q67zvvdf+Eo7lqfipYio89rQ984U58o5AvLhV+WqhDVRBTTtO+oI/FjdiHIruoiY/adEz7gJEAlrMlgoAAQkVnKma9uufObIemL+QGpDjLvdluIgts/cT34r4I5Xaij1vGAjzZ+Fe+Tn5tuW48pjtjWCzAwVTEu/zf/VKSJPoCVGx5YCvFE3CKXkVWuJ86gj+rO/SXWkjv672EetaVwv2Uc/RkCfru84m6bQWAHzb3P46Hfkw3kIyaIudxgizy1xlxLEEU3LwUU/vFxTd2Q6lAhGGMn6Imy9Z6I=") } } + */ } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/other/updater/UpdaterC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/other/updater/UpdaterC.kt index a631b62c4..dbed24923 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/other/updater/UpdaterC.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/other/updater/UpdaterC.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -45,7 +45,7 @@ class UpdaterC(profile: OtherProfile) { * - OS: Operating system (windows, linux, mac, ...) * - ARCH: architecture of the current build (x86, x64, arm64) */ - var url by StringDelegate(profile, "https://minosoft.bixilon.de/v1/updates?version=\${VERSION}&channel=\${CHANNEL}&commit=\${COMMIT}&os=\${OS}&arch=\${ARCH}") + var url by StringDelegate(profile, "https://minosoft.bixilon.de/api/v1/updates?version=\${VERSION}&channel=\${CHANNEL}&commit=\${COMMIT}&os=\${OS}&arch=\${ARCH}") /** * If the newest version matches this field, it won't be shown diff --git a/src/main/java/de/bixilon/minosoft/updater/DownloadLink.kt b/src/main/java/de/bixilon/minosoft/updater/DownloadLink.kt index 6d0da47d5..c62506841 100644 --- a/src/main/java/de/bixilon/minosoft/updater/DownloadLink.kt +++ b/src/main/java/de/bixilon/minosoft/updater/DownloadLink.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -19,4 +19,5 @@ data class DownloadLink( val url: URL, val size: Int, val sha512: String, + val signature: String, ) diff --git a/src/main/java/de/bixilon/minosoft/updater/MinosoftUpdater.kt b/src/main/java/de/bixilon/minosoft/updater/MinosoftUpdater.kt index c2f2a64b9..a5f48aa96 100644 --- a/src/main/java/de/bixilon/minosoft/updater/MinosoftUpdater.kt +++ b/src/main/java/de/bixilon/minosoft/updater/MinosoftUpdater.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -101,9 +101,7 @@ object MinosoftUpdater { } fun parse(data: String): MinosoftUpdate { - val (signature, json) = data.split('\n', limit = 2) - UpdateKey.require(signature, json) - return Jackson.MAPPER.readValue(json, MinosoftUpdate::class.java) + return Jackson.MAPPER.readValue(data, MinosoftUpdate::class.java) } fun download(update: MinosoftUpdate, progress: UpdateProgress) { @@ -116,5 +114,6 @@ object MinosoftUpdater { progress.log?.print("TODO :)") progress.stage = UpdateProgress.UpdateStage.FAILED + // UpdateKey.require(data, signature) } } diff --git a/src/main/java/de/bixilon/minosoft/util/http/HTTPResponse.kt b/src/main/java/de/bixilon/minosoft/util/http/HTTPResponse.kt index 476450df2..5c1d842b5 100644 --- a/src/main/java/de/bixilon/minosoft/util/http/HTTPResponse.kt +++ b/src/main/java/de/bixilon/minosoft/util/http/HTTPResponse.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2021 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -15,5 +15,6 @@ package de.bixilon.minosoft.util.http class HTTPResponse( val statusCode: Int, + val headers: Map, val body: T, ) diff --git a/src/main/java/de/bixilon/minosoft/util/signature/SignatureSigner.kt b/src/main/java/de/bixilon/minosoft/util/signature/SignatureSigner.kt index 7cbf9fca3..a99f3eac0 100644 --- a/src/main/java/de/bixilon/minosoft/util/signature/SignatureSigner.kt +++ b/src/main/java/de/bixilon/minosoft/util/signature/SignatureSigner.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2023 Moritz Zwerger + * Copyright (C) 2020-2024 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. * @@ -42,22 +42,23 @@ abstract class SignatureSigner( return instance } - open fun verify(data: ByteArray, signature: ByteArray): Boolean { + open fun verify(data: ByteArray, signature: ByteArray?): Boolean { + if (signature == null) return false val instance = createInstance() instance.update(data) return instance.verify(signature) } - fun require(data: ByteArray, signature: ByteArray) { + fun require(data: ByteArray, signature: ByteArray?) { if (verify(data, signature)) return throw SignatureException() } - fun verify(data: String, signature: String): Boolean { + fun verify(data: String, signature: String?): Boolean { return verify(data.toByteArray(), Base64.getDecoder().decode(signature)) } - fun require(data: String, signature: String) { + fun require(data: String, signature: String?) { if (verify(data, signature)) return throw SignatureException() }