Sign loaders

bzip2
Graham 5 years ago
parent 33955e76c7
commit 11ef4b0227
  1. 14
      asm/src/main/java/dev/openrs2/asm/classpath/Library.kt
  2. 13
      bundler/src/main/java/dev/openrs2/bundler/Bundler.kt
  3. 64
      common/src/main/java/dev/openrs2/common/crypto/Pkcs12KeyStore.kt
  4. 1
      conf/.gitignore

@ -3,6 +3,7 @@ package dev.openrs2.asm.classpath
import com.github.michaelbull.logging.InlineLogger import com.github.michaelbull.logging.InlineLogger
import dev.openrs2.asm.hasCode import dev.openrs2.asm.hasCode
import dev.openrs2.asm.remap.ClassForNameRemapper import dev.openrs2.asm.remap.ClassForNameRemapper
import dev.openrs2.common.crypto.Pkcs12KeyStore
import dev.openrs2.common.io.DeterministicJarOutputStream import dev.openrs2.common.io.DeterministicJarOutputStream
import dev.openrs2.common.io.SkipOutputStream import dev.openrs2.common.io.SkipOutputStream
import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassReader
@ -101,6 +102,19 @@ class Library constructor() : Iterable<ClassNode> {
} }
} }
public fun writeSignedJar(path: Path, keyStore: Pkcs12KeyStore, manifest: Manifest? = null) {
logger.info { "Writing signed jar $path" }
val unsignedPath = Files.createTempFile("tmp", ".jar")
try {
writeJar(unsignedPath, manifest)
keyStore.signJar(unsignedPath)
DeterministicJarOutputStream.repack(unsignedPath, path)
} finally {
Files.deleteIfExists(unsignedPath)
}
}
fun writePack(out: OutputStream) { fun writePack(out: OutputStream) {
val temp = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX) val temp = Files.createTempFile(TEMP_PREFIX, JAR_SUFFIX)
try { try {

@ -13,6 +13,7 @@ import dev.openrs2.bundler.transform.PlatformDetectionTransformer
import dev.openrs2.bundler.transform.PublicKeyTransformer import dev.openrs2.bundler.transform.PublicKeyTransformer
import dev.openrs2.bundler.transform.ResourceTransformer import dev.openrs2.bundler.transform.ResourceTransformer
import dev.openrs2.bundler.transform.RightClickTransformer import dev.openrs2.bundler.transform.RightClickTransformer
import dev.openrs2.common.crypto.Pkcs12KeyStore
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.util.jar.Attributes import java.util.jar.Attributes
@ -24,14 +25,14 @@ import javax.inject.Singleton
fun main() { fun main() {
val injector = Guice.createInjector(BundlerModule()) val injector = Guice.createInjector(BundlerModule())
val bundler = injector.getInstance(Bundler::class.java) val bundler = injector.getInstance(Bundler::class.java)
bundler.run(Paths.get("nonfree/code"), Paths.get("nonfree/code/bundle")) bundler.run(Paths.get("nonfree/code"), Paths.get("nonfree/code/bundle"), Paths.get("conf/loader.p12"))
} }
@Singleton @Singleton
class Bundler @Inject constructor(publicKeyTransformer: PublicKeyTransformer) { class Bundler @Inject constructor(publicKeyTransformer: PublicKeyTransformer) {
private val transformers = listOf(*TRANSFORMERS.toTypedArray(), publicKeyTransformer) private val transformers = listOf(*TRANSFORMERS.toTypedArray(), publicKeyTransformer)
fun run(input: Path, output: Path) { fun run(input: Path, output: Path, keyStorePath: Path) {
// read input jars/packs // read input jars/packs
logger.info { "Reading input jars" } logger.info { "Reading input jars" }
val unpacker = Library.readJar(input.resolve("game_unpacker.dat")) val unpacker = Library.readJar(input.resolve("game_unpacker.dat"))
@ -116,12 +117,10 @@ class Bundler @Inject constructor(publicKeyTransformer: PublicKeyTransformer) {
// write unsigned client and loaders // write unsigned client and loaders
client.writeJar(output.resolve("runescape.jar"), unsignedManifest) client.writeJar(output.resolve("runescape.jar"), unsignedManifest)
loader.writeJar(output.resolve("loader.jar"), signedManifest)
glLoader.writeJar(output.resolve("loader_gl.jar"), signedManifest)
// sign loaders val keyStore = Pkcs12KeyStore.open(keyStorePath)
logger.info { "Signing loaders" } loader.writeSignedJar(output.resolve("loader.jar"), keyStore, signedManifest)
// TODO(gpe): implement glLoader.writeSignedJar(output.resolve("loader_gl.jar"), keyStore, signedManifest)
} }
companion object { companion object {

@ -0,0 +1,64 @@
package dev.openrs2.common.crypto
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
class Pkcs12KeyStore private constructor(private val path: Path) {
fun signJar(jar: Path) {
exec(
"jarsigner",
"-keystore", path.toString(),
"-storetype", "pkcs12",
"-storepass", STORE_PASSWORD,
"-keypass", KEY_PASSWORD,
jar.toString(),
ALIAS
)
}
companion object {
private const val ALIAS = "openrs2"
private const val STORE_PASSWORD = ALIAS
private const val KEY_PASSWORD = ALIAS
private const val DNAME = "CN=OpenRS2"
private const val VALIDITY_PERIOD = "3650"
private const val KEY_ALGORITHM = "RSA"
private const val KEY_SIZE = "2048"
private const val SIGNATURE_ALGORITHM = "SHA256with$KEY_ALGORITHM"
fun open(path: Path): Pkcs12KeyStore {
if (!Files.exists(path)) {
create(path)
}
return Pkcs12KeyStore(path)
}
private fun create(path: Path) {
exec(
"keytool",
"-genkeypair",
"-keystore", path.toString(),
"-storetype", "pkcs12",
"-storepass", STORE_PASSWORD,
"-keypass", KEY_PASSWORD,
"-alias", ALIAS,
"-dname", DNAME,
"-validity", VALIDITY_PERIOD,
"-keyalg", KEY_ALGORITHM,
"-keysize", KEY_SIZE,
"-sigalg", SIGNATURE_ALGORITHM
)
}
private fun exec(command: String, vararg args: String) {
val commandWithArgs = listOf(command, *args)
val status = ProcessBuilder(commandWithArgs)
.start()
.waitFor()
if (status != 0) {
throw IOException("$command returned non-zero status code $status")
}
}
}
}

1
conf/.gitignore vendored

@ -1,2 +1,3 @@
/loader.p12
/private.key /private.key
/public.key /public.key

Loading…
Cancel
Save