From bbf9277107555db49f6124718b20787e02943ee6 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Sun, 27 Oct 2024 15:00:50 +0100 Subject: [PATCH] Fix updater and signature verification --- README.md | 15 ++++++--------- pom.xml | 4 ++-- .../java/eu/m724/giants/updater/JarVerifier.java | 8 +++++++- testkeystore.jks | Bin 3482 -> 0 bytes 4 files changed, 15 insertions(+), 12 deletions(-) delete mode 100644 testkeystore.jks diff --git a/README.md b/README.md index 2777d9f..ed153e9 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,16 @@ This plugin adds naturally spawning Giants with AI to your Minecraft server. ### Signing Public key goes into `resources/verifies_downloaded_jars.pem` -A test (and default) keystore is provided: -- keystore: `testkeystore` -- storepass: `123456` -- alias: `testkey` - -When using `mvn`, override with `-Djarsigner.` -``` -mvn clean package -Djarsigner.keystore=/home/user/mykeystore.jks -Djarsigner.alias=mykey -``` +A default keystore is not provided. To create a keystore and export public key: ``` keytool -keystore testkeystore2.jks -genkeypair -keyalg RSA -alias testkey -validity 999999 keytool -exportcert -alias testkey -keystore testkeystore2.jks -file cert.cer -rfc openssl x509 -inform pem -in cert.cer -pubkey -noout > public_key.pem +``` + +When using `mvn`, override with `-Djarsigner.` +``` +mvn clean package -Djarsigner.keystore=/home/user/mykeystore.jks -Djarsigner.alias=mykey ``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index 636cdca..91bfd75 100644 --- a/pom.xml +++ b/pom.xml @@ -6,8 +6,8 @@ 11 - ${project.basedir}/testkeystore.jks - testkey + ${project.basedir}/keystore.jks + mykey 123456 UTF-8 UTF-8 diff --git a/src/main/java/eu/m724/giants/updater/JarVerifier.java b/src/main/java/eu/m724/giants/updater/JarVerifier.java index e4a0133..21086f3 100644 --- a/src/main/java/eu/m724/giants/updater/JarVerifier.java +++ b/src/main/java/eu/m724/giants/updater/JarVerifier.java @@ -7,10 +7,13 @@ import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PublicKey; import java.security.cert.Certificate; +import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.security.spec.X509EncodedKeySpec; +import java.util.ArrayList; import java.util.Base64; import java.util.Enumeration; +import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -96,11 +99,14 @@ public class JarVerifier { // Check if any signer's public key matches our RSA key boolean keyMatch = false; + List signerPublicKeys = new ArrayList<>(); + for (CodeSigner signer : signers) { for (Certificate cert : signer.getSignerCertPath().getCertificates()) { PublicKey certPublicKey = cert.getPublicKey(); if (certPublicKey instanceof RSAPublicKey) { RSAPublicKey rsaKey = (RSAPublicKey) certPublicKey; + signerPublicKeys.add(Base64.getEncoder().encodeToString(rsaKey.getEncoded())); if (rsaKey.getModulus().equals(publicKey.getModulus()) && rsaKey.getPublicExponent().equals(publicKey.getPublicExponent())) { keyMatch = true; @@ -112,7 +118,7 @@ public class JarVerifier { } if (!keyMatch) { - throw new VerificationException("Entry not signed with matching RSA key: " + entry.getName()); + throw new VerificationException("Entry " + entry.getName() + " signed with " + String.join(", ", signerPublicKeys) + ", none of which match " + Base64.getEncoder().encodeToString(publicKey.getEncoded())); } } } diff --git a/testkeystore.jks b/testkeystore.jks deleted file mode 100644 index 6c10b16daafbf741f31291b4e54816a18e5d290a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3482 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