diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java index 5a025e68..5bb78a57 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/LiteModHDSkins.java @@ -17,6 +17,7 @@ import com.voxelmodpack.hdskins.gui.HDSkinsConfigPanel; import com.voxelmodpack.hdskins.gui.RenderPlayerModel; import com.voxelmodpack.hdskins.server.*; import com.voxelmodpack.hdskins.upload.GLWindow; +import com.voxelmodpack.hdskins.util.SslHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; @@ -46,6 +47,9 @@ public class LiteModHDSkins implements InitCompleteListener, ViewportListener, C @Expose public String lastChosenFile = ""; + @Expose + public boolean skipLetsEncrypt = false; + public LiteModHDSkins() { instance = this; } @@ -72,6 +76,10 @@ public class LiteModHDSkins implements InitCompleteListener, ViewportListener, C IReloadableResourceManager irrm = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); irrm.registerReloadListener(HDSkinManager.INSTANCE); + + if (!skipLetsEncrypt) { + SslHelper.doStuff(HDSkinManager.logger); + } } @Override diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java b/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java index f5b8c319..b2ef5b6f 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/server/ValhallaSkinServer.java @@ -36,6 +36,9 @@ public class ValhallaSkinServer implements SkinServer { private transient String accessToken; public ValhallaSkinServer(String address) { + if (address.startsWith("http:")) { + address = address.replace("http:", "https:"); + } this.address = address; } diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/util/SslHelper.java b/src/hdskins/java/com/voxelmodpack/hdskins/util/SslHelper.java new file mode 100644 index 00000000..2c090799 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/util/SslHelper.java @@ -0,0 +1,101 @@ +package com.voxelmodpack.hdskins.util; + +import java.io.*; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.logging.log4j.Logger; + +/** + * Credit to https://github.com/Cloudhunter/LetsEncryptCraft + */ +public class SslHelper { + + public static void addLetsEncryptCertificate() throws Exception { + InputStream cert = SslHelper.class.getResourceAsStream("lets-encrypt-x3-cross-signed.der"); + + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + Path ksPath = Paths.get(System.getProperty("java.home"),"lib", "security", "cacerts"); + keyStore.load(Files.newInputStream(ksPath), "changeit".toCharArray()); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + InputStream caInput = new BufferedInputStream(cert); + Certificate crt = cf.generateCertificate(caInput); + + keyStore.setCertificateEntry("lets-encrypt-x3-cross-signed", crt); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, tmf.getTrustManagers(), null); + SSLContext.setDefault(sslContext); + } + + public static void doStuff(Logger mod) { + String version = System.getProperty("java.version"); + Pattern p = Pattern.compile("^(\\d+\\.\\d+).*?_(\\d+).*"); + Matcher matcher = p.matcher(version); + String majorVersion; + int minorVersion; + if (matcher.matches()) + { + majorVersion = matcher.group(1); + minorVersion = Integer.valueOf(matcher.group(2)); + } else { + majorVersion = "1.7"; + minorVersion = 110; + mod.info("Regex to parse Java version failed - applying LetsEncrypt anyway."); + } + + switch (majorVersion) + { + case "1.7": + if (minorVersion >= 111) + { + mod.info("LetsEncrypt is not needed as Java version is at least Java 7u111."); + return; + } + break; + case "1.8": + if (minorVersion >= 101) + { + mod.info("LetsEncrypt is not needed as Java version is at least Java 8u101."); + return; + } + break; + } + + String body = ""; + try { + mod.info("Adding Let's Encrypt certificate..."); + addLetsEncryptCertificate(); + mod.info("Done, attempting to connect to https://helloworld.letsencrypt.org..."); + URL url = new URL("https://helloworld.letsencrypt.org"); + URLConnection conn = url.openConnection(); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { + body = reader.readLine(); + } + } catch (Exception e) { + mod.error("An error occurred whilst adding the Let's Encrypt root certificate. I'm afraid you wont be able to access resources with a Let's Encrypt certificate D:", e); + } + + if (body.isEmpty()) { + mod.error("An unknown error occurred whilst adding the Let's Encrypt root certificate. I'm afraid you may not be able to access resources with a Let's Encrypt certificate D:"); + } else { + mod.info("Done - you are now able to access resources with a Let's Encrypt certificate :D"); + } + } +} diff --git a/src/hdskins/resources/lets-encrypt-x3-cross-signed.der b/src/hdskins/resources/lets-encrypt-x3-cross-signed.der new file mode 100644 index 00000000..e08466c5 Binary files /dev/null and b/src/hdskins/resources/lets-encrypt-x3-cross-signed.der differ