client loader: add new jagex certificate

This commit is contained in:
Adam
2021-10-28 10:52:58 -04:00
parent ed2594a055
commit 6ad7ba1799
2 changed files with 111 additions and 20 deletions

View File

@@ -259,7 +259,10 @@ public class ClientLoader implements Supplier<Applet>
private void updateVanilla(RSConfig config) throws IOException, VerificationException
{
Certificate[] jagexCertificateChain = getJagexCertificateChain();
Certificate[][] jagexCertificateChains = {
loadCertificateChain("jagex.crt"),
loadCertificateChain("jagex2021.crt")
};
// Get the mtime of the first thing in the vanilla cache
// we check this against what the server gives us to let us skip downloading and patching the whole thing
@@ -276,7 +279,7 @@ public class ClientLoader implements Supplier<Applet>
JarEntry je = vanillaCacheTest.getNextJarEntry();
if (je != null)
{
verifyJarEntry(je, jagexCertificateChain);
verifyJarEntry(je, jagexCertificateChains);
vanillaCacheMTime = je.getLastModifiedTime().toMillis();
}
else
@@ -355,7 +358,7 @@ public class ClientLoader implements Supplier<Applet>
}
networkJIS.skip(Long.MAX_VALUE);
verifyJarEntry(je, jagexCertificateChain);
verifyJarEntry(je, jagexCertificateChains);
long vanillaClientMTime = je.getLastModifiedTime().toMillis();
if (!vanillaCacheIsInvalid && vanillaClientMTime != vanillaCacheMTime)
{
@@ -372,7 +375,7 @@ public class ClientLoader implements Supplier<Applet>
{
// as with the request stream, its important to not early close vanilla too
JarInputStream vanillaCacheTest = new JarInputStream(Channels.newInputStream(vanilla));
verifyWholeJar(vanillaCacheTest, jagexCertificateChain);
verifyWholeJar(vanillaCacheTest, jagexCertificateChains);
}
catch (Exception e)
{
@@ -388,7 +391,7 @@ public class ClientLoader implements Supplier<Applet>
OutputStream out = Channels.newOutputStream(vanilla);
out.write(preRead.toByteArray());
copyStream.setOut(out);
verifyWholeJar(networkJIS, jagexCertificateChain);
verifyWholeJar(networkJIS, jagexCertificateChains);
copyStream.skip(Long.MAX_VALUE); // write the trailer to the file too
out.flush();
vanilla.truncate(vanilla.position());
@@ -557,9 +560,9 @@ public class ClientLoader implements Supplier<Applet>
return rs;
}
private static Certificate[] getJagexCertificateChain()
private static Certificate[] loadCertificateChain(String name)
{
try (InputStream in = ClientLoader.class.getResourceAsStream("jagex.crt"))
try (InputStream in = ClientLoader.class.getResourceAsStream(name))
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
@@ -571,28 +574,33 @@ public class ClientLoader implements Supplier<Applet>
}
}
private void verifyJarEntry(JarEntry je, Certificate[] certs) throws VerificationException
private void verifyJarEntry(JarEntry je, Certificate[][] chains) throws VerificationException
{
switch (je.getName())
if (je.getName().equals("META-INF/JAGEXLTD.SF") || je.getName().equals("META-INF/JAGEXLTD.RSA"))
{
case "META-INF/JAGEXLTD.SF":
case "META-INF/JAGEXLTD.RSA":
// You can't sign the signing files
return;
default:
if (!Arrays.equals(je.getCertificates(), certs))
{
throw new VerificationException("Unable to verify jar entry: " + je.getName());
}
// You can't sign the signing files
return;
}
// Jar entry must match one of the trusted certificate chains
Certificate[] entryCertificates = je.getCertificates();
for (Certificate[] chain : chains)
{
if (Arrays.equals(entryCertificates, chain))
{
return;
}
}
throw new VerificationException("Unable to verify jar entry: " + je.getName());
}
private void verifyWholeJar(JarInputStream jis, Certificate[] certs) throws IOException, VerificationException
private void verifyWholeJar(JarInputStream jis, Certificate[][] chains) throws IOException, VerificationException
{
for (JarEntry je; (je = jis.getNextJarEntry()) != null; )
{
jis.skip(Long.MAX_VALUE);
verifyJarEntry(je, certs);
verifyJarEntry(je, chains);
}
}
}