Skip to content

Commit aa46e72

Browse files
committed
feat: add optional insecure TLS setting and fallback certificate support
- Added `useInsecureTLS` config option to disable TLS certificate validation for relay connections ⚠️ Not recommended; prefer installing Zulu 8 JDK or importing the relay certificate manually - Improved TLS handling in broker HTTP connections: - Uses system-default TLS validation by default - Falls back to bundled cert `/certs/broker.e4mc.link.cert` if validation fails
1 parent d630fe4 commit aa46e72

File tree

6 files changed

+113
-1
lines changed

6 files changed

+113
-1
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 1.0.2
4+
5+
- **Added** a new configuration option: `useInsecureTLS`
6+
This allows disabling TLS certificate validation for relay connections.
7+
⚠️ **Warning:** This is insecure and not recommended. It is strongly advised to install the Azul Zulu 8 JDK or manually import the relay certificate instead.
8+
See [this comment](https://github.com/xhyrom/e4mc-retro/issues/2#issuecomment-3102506009) for detailed instructions and rationale.
9+
- **Improved TLS handling** for broker HTTP connections:
10+
* If `useInsecureTLS` is enabled, the client uses an insecure trust manager that disables certificate validation.
11+
* If disabled (default), the client first attempts to use the system-default TLS validation. If that fails, it falls back to a bundled custom trust manager using `/certs/broker.e4mc.link.cert`.
12+
313
## 1.0.1
414

515
- Fixed a bug where commands would not output and could crash due to a `NullPointerException` in the `sendCommandFeedback` mixin when `getServer()` returned null.

common/src/main/java/link/e4mc/Config.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ public class Config extends ReflectiveConfig {
3939
public final TrackedValue<String> relayHost = this.value("test.e4mc.link");
4040
public final TrackedValue<Integer> relayPort = this.value(25575);
4141

42+
@Comment("Disables TLS certificate validation for relay connections.\n"
43+
+ "Use this only as a last resort if you're experiencing SSL certificate errors.\n"
44+
+ "This is insecure and not recommended.\n"
45+
+ "Instead, it is strongly recommended to install the Azul Zulu 8 JDK, which avoids these issues.\n"
46+
+ "For a proper fix, including how to import the certificate manually, see:\n"
47+
+ "https://github.com/xhyrom/e4mc-retro/issues/2#issuecomment-3102506009")
48+
public final TrackedValue<Boolean> useInsecureTLS = this.value(false);
49+
4250
@Comment("Allows use of certain dedicated server commands such as /ban and /whitelist")
4351
public final TrackedValue<Boolean> restoreDedicatedCommands = this.value(true);
4452
@Comment("Whether to use whitelists on LAN worlds")

common/src/main/java/link/e4mc/QuiclimeSession.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,22 @@
3838
import dev.xhyrom.e4mc.shadow.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
3939
import dev.xhyrom.e4mc.shadow.io.netty.incubator.codec.quic.*;
4040
import link.e4mc.platform.Services;
41+
import link.e4mc.util.SSLUtil;
4142
import net.minecraft.ChatFormatting;
4243
import net.minecraft.client.Minecraft;
4344
import net.minecraft.network.chat.*;
4445

46+
import javax.net.ssl.HttpsURLConnection;
47+
import javax.net.ssl.SSLContext;
48+
import javax.net.ssl.SSLException;
4549
import java.io.BufferedReader;
4650
import java.io.InputStreamReader;
4751
import java.net.HttpURLConnection;
4852
import java.net.InetAddress;
4953
import java.net.InetSocketAddress;
5054
import java.net.URL;
5155
import java.nio.charset.StandardCharsets;
56+
import java.security.SecureRandom;
5257
import java.util.List;
5358
import java.util.concurrent.TimeUnit;
5459
import java.util.function.Consumer;
@@ -269,6 +274,36 @@ private static BrokerResponse getRelay() throws Exception {
269274
conn.setRequestMethod("GET");
270275
conn.setRequestProperty("Accept", "application/json");
271276

277+
if (conn instanceof HttpsURLConnection) {
278+
SSLContext sc = SSLContext.getInstance("TLS");
279+
280+
if (Config.INSTANCE.useInsecureTLS.value()) {
281+
E4mcClient.LOGGER.warn("Using insecure TLS for broker connection.\n"
282+
+ "This disables SSL certificate validation and is not secure.\n"
283+
+ "It is strongly recommended to install the Zulu 8 JDK or manually import the certificate.\n"
284+
+ "See https://github.com/xhyrom/e4mc-retro/issues/2#issuecomment-3102506009 for details.");
285+
286+
sc.init(null, InsecureTrustManagerFactory.INSTANCE.getTrustManagers(), new SecureRandom());
287+
((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
288+
} else {
289+
try {
290+
E4mcClient.LOGGER.info("Using system default TLS validation for broker connection.");
291+
292+
conn.connect();
293+
} catch (SSLException e) {
294+
E4mcClient.LOGGER.warn("System default TLS validation failed, falling back to bundled cert.");
295+
296+
sc.init(null, SSLUtil.createTrustManagersFromCert("/certs/broker.e4mc.link.cert"), new SecureRandom());
297+
298+
conn = (HttpsURLConnection) url.openConnection();
299+
conn.setRequestMethod("GET");
300+
conn.setRequestProperty("Accept", "application/json");
301+
((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
302+
conn.connect();
303+
}
304+
}
305+
}
306+
272307
E4mcClient.LOGGER.info("req: GET " + url);
273308

274309
int status = conn.getResponseCode();
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package link.e4mc.util;
2+
3+
import javax.net.ssl.TrustManager;
4+
import javax.net.ssl.TrustManagerFactory;
5+
import java.io.InputStream;
6+
import java.security.KeyStore;
7+
import java.security.cert.Certificate;
8+
import java.security.cert.CertificateFactory;
9+
10+
public class SSLUtil {
11+
public static TrustManager[] createTrustManagersFromCert(String certResourcePath) throws Exception {
12+
try (InputStream certInputStream = SSLUtil.class.getResourceAsStream(certResourcePath)) {
13+
if (certInputStream == null) {
14+
throw new IllegalArgumentException("Certificate resource not found: " + certResourcePath);
15+
}
16+
17+
CertificateFactory cf = CertificateFactory.getInstance("X.509");
18+
Certificate caCert = cf.generateCertificate(certInputStream);
19+
20+
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
21+
keyStore.load(null, null);
22+
keyStore.setCertificateEntry("caCert", caCert);
23+
24+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
25+
tmf.init(keyStore);
26+
27+
return tmf.getTrustManagers();
28+
}
29+
}
30+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIE+TCCA+GgAwIBAgISBqFtI9Z34+g6vl6W9w36r6YDMA0GCSqGSIb3DQEBCwUA
3+
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
4+
EwNSMTEwHhcNMjUwNzA1MDcxMjIwWhcNMjUxMDAzMDcxMjE5WjAbMRkwFwYDVQQD
5+
ExBicm9rZXIuZTRtYy5saW5rMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
6+
AQEAlXIPYXE1/+XFEXRx0zqY+ElMB3V/X9lKQA9VEaqkHNIJwbF732eJ8/6helEg
7+
kSumAoH2pNFRb05SnOa+rYiiCF1TETcXCwprwJ2XB0rNkM8GJ8048w3wGBGCY5cN
8+
EbqbVaMJ8F8nOzZ4KqRHGHZQHdfZS6eNMbd4cItWsMaYEW+EuA7Xm4XsZ9QHGZmz
9+
3C8VA7/R6DiLiYnZggB5KtdKPvDq9wg2ei990ZOq1zVTbTWsmcfaCCmsnvB6uRhp
10+
VveKpIES5r4jlP49pOCMZi9P/rIC5oVFEwbYQJbze8BZ/9VbOUZ9fKFi1oN8mlA/
11+
HOkfD0Hb/z9FbQY3td2KTBAg9wIDAQABo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgWg
12+
MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0G
13+
A1UdDgQWBBTU3ecHLJkIGxluI+bjklY8hlrUXTAfBgNVHSMEGDAWgBTFz0ak6vTD
14+
wHpslcQtsF6SLybjuTAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAKGF2h0dHA6
15+
Ly9yMTEuaS5sZW5jci5vcmcvMBsGA1UdEQQUMBKCEGJyb2tlci5lNG1jLmxpbmsw
16+
EwYDVR0gBAwwCjAIBgZngQwBAgEwLQYDVR0fBCYwJDAioCCgHoYcaHR0cDovL3Ix
17+
MS5jLmxlbmNyLm9yZy80LmNybDCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1AKRC
18+
xQZJYGFUjw/U6pz7ei0mRU2HqX8v30VZ9idPOoRUAAABl9mjWx8AAAQDAEYwRAIg
19+
KnbAuafDKVUyDrvtYzOY6C6wKvC+3hNCyZ3cx9+r05cCIHkHd5W+8zH9QQ125bRf
20+
IegR78U7lb7tPZiVHS6+XxUfAHUAzPsPaoVxCWX+lZtTzumyfCLphVwNl422qX5U
21+
wP5MDbAAAAGX2aNrbwAABAMARjBEAiAyr5PO1dSbl+b58L7/a1XoyNODPytYnnzB
22+
7flbiB/gvgIgcDlwyjePI/POa7/Y7NAI0uwi8XNvBhtR/eGMdnUgIhcwDQYJKoZI
23+
hvcNAQELBQADggEBACaumADPhtla2AHs4v9YI8Hoixi5FrsNiUBdTDAl20jpxXuI
24+
r83AfhgHNnZqBRkpizMU+rSA6QEEJjfkswRatjPfFJmNaecwj2LH/XLI0m2RTdt9
25+
ZlEi/r4EQCoi8u8A5bA9GKxMtDmBgCZU94QexvWNOHCrhDnh5x/JhOQhG1Vfd9/z
26+
e92fk5oxdT3lF2v/3ChQvkUJy0L5hlW312McMyD89H+njmU4NO0WR3Ctz4BJvBem
27+
+pzknvxnGt0ZNNS4ijPAYiVul05a1gCd2QgzV9YL/q0dDDitjeejk9PAFItCTQGb
28+
2FXj3U7nZG0T1Vm7hfv9pfNS51SJIYiwLnEoJUQ=
29+
-----END CERTIFICATE-----

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ forge_version=28.2.26
1212
ornithe_osl_version = 0.16.3
1313

1414
mod_id = e4mc_retro_minecraft
15-
mod_version = 1.0.1
15+
mod_version = 1.0.2
1616
archives_base_name = e4mc-retro

0 commit comments

Comments
 (0)