Skip to content

Commit

Permalink
Fix SSL fixer
Browse files Browse the repository at this point in the history
  • Loading branch information
Wyvest committed Nov 26, 2023
1 parent 1f7c143 commit a1c0660
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 140 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package mynameisjeff.skyblockclientupdater.utils.ssl;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

/**
* SSLStore attempts to work around the limitations of legacy Minecraft versions in their
* collection of certificates. Since many legacy versions including 1.8 use legacy versions
* of Java, these distributions tend to have outdated or missing CA certificates.
*
* This class loads and injects a new CA Root certificate into the normal Java KeyStore
* without having to restart the Java runtime. This allows us to load the certificate
* from Stage 0 (Wrapper), before any HTTP requests are made. We use this ability to
* take the context that SSLStore creates and use it for all future HTTP requests
* during the lifetime of the Java runtime (including for all other stages and mods).
*
* @author pauliesnug
* @see javax.net.ssl.KeyManager
* @see javax.net.ssl.SSLContext
*/
public class SSLStore {
private final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
private final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

public SSLStore() throws Exception {
Path keyStorePath = Paths.get(System.getProperty("java.home"), "lib", "security", "cacerts");
this.keyStore.load(Files.newInputStream(keyStorePath), (char[])null);
}

/**
* Loads the specified SSL certificate.
*
* @param sslFile A .der filename
* @throws Exception Uses Exception to cover the SSL loading and generation
*/
public SSLStore load(String sslFile) throws Exception {
InputStream certificateResource = SSLStore.class.getResourceAsStream(sslFile);
Throwable sslThrowable = null;

// Try to gen and load the certificate
try {
InputStream certStream = new BufferedInputStream(certificateResource);
Certificate generatedCertificate = this.certificateFactory.generateCertificate(certStream);

this.keyStore.setCertificateEntry(sslFile, generatedCertificate);
} catch (Throwable sslException) {
sslThrowable = sslException;
throw sslException;
} finally {
if (certificateResource != null) {
try {
certificateResource.close();
} catch (Throwable closeException) {
sslThrowable.addSuppressed(closeException);
}
} else {
certificateResource.close();
}
}
return this;
}

/**
* Generates and returns the SSLContext after the new cert has been added with SSLStore.load().
*
* @return The SSLContext generated after init.
* @throws Exception Uses Exception to cover the TMF init and SSLContext init.
*/
public SSLContext finish() throws Exception {
// Initialize TrustManagerFactory with the new KeyStore once the new cert has been added
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(this.keyStore);

// Return the SSLContext after init.
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init((KeyManager[])null, trustManagerFactory.getTrustManagers(), null);

return sslContext;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import kotlinx.serialization.modules.serializersModuleOf
import mynameisjeff.skyblockclientupdater.command.Command
import mynameisjeff.skyblockclientupdater.config.Config
import mynameisjeff.skyblockclientupdater.data.FileSerializer
import mynameisjeff.skyblockclientupdater.utils.ssl.FixSSL
import mynameisjeff.skyblockclientupdater.utils.ssl.SSLStore
import net.minecraft.client.Minecraft
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.ProgressManager
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
import java.awt.Color
import javax.net.ssl.HttpsURLConnection
import javax.net.ssl.SSLContext


@Mod(
name = "@NAME@",
Expand Down Expand Up @@ -41,8 +44,18 @@ import java.awt.Color
Config.preload()

val progress = ProgressManager.push("SkyClient Updater", 6)
progress.step("Fixing Let's Encrypt SSL")
FixSSL.fixup()
progress.step("Fixing Modrinth SSL")
try {
var sslStore = SSLStore()
println("Attempting to load Modrinth certificate.")
sslStore = sslStore.load("/modrinth.com.der")
val context: SSLContext = sslStore.finish()
SSLContext.setDefault(context)
HttpsURLConnection.setDefaultSSLSocketFactory(context.socketFactory)
} catch (e: Exception) {
e.printStackTrace()
println("Failed to add Modrinth certificate to keystore.")
}
progress.step("Downloading helper utility")
UpdateChecker.INSTANCE.downloadHelperTask()
progress.step("Discovering mods")
Expand Down
Binary file removed src/main/resources/lekeystore.jks
Binary file not shown.
Binary file added src/main/resources/modrinth.com.der
Binary file not shown.

0 comments on commit a1c0660

Please sign in to comment.