Replace jarsigner with the jdk.security.jarsigner API

Signed-off-by: Graham <gpe@openrs2.dev>
feat/deob-ir
Graham 5 years ago
parent 164e02cbce
commit 8e0b480cfb
  1. 10
      asm/src/main/java/dev/openrs2/asm/classpath/Library.kt
  2. 51
      common/src/main/java/dev/openrs2/common/crypto/Pkcs12KeyStore.kt

@ -101,8 +101,14 @@ class Library constructor() : Iterable<ClassNode> {
val unsignedPath = Files.createTempFile("tmp", ".jar") val unsignedPath = Files.createTempFile("tmp", ".jar")
try { try {
writeJar(classPath, unsignedPath, manifest) writeJar(classPath, unsignedPath, manifest)
keyStore.signJar(unsignedPath)
DeterministicJarOutputStream.repack(unsignedPath, path) val signedPath = Files.createTempFile("tmp", ".jar")
try {
keyStore.signJar(unsignedPath, signedPath)
DeterministicJarOutputStream.repack(signedPath, path)
} finally {
Files.deleteIfExists(signedPath)
}
} finally { } finally {
Files.deleteIfExists(unsignedPath) Files.deleteIfExists(unsignedPath)
} }

@ -1,5 +1,6 @@
package dev.openrs2.common.crypto package dev.openrs2.common.crypto
import jdk.security.jarsigner.JarSigner
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers import org.bouncycastle.asn1.nist.NISTObjectIdentifiers
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
import org.bouncycastle.asn1.x500.X500NameBuilder import org.bouncycastle.asn1.x500.X500NameBuilder
@ -10,7 +11,6 @@ import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory
import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder
import org.bouncycastle.util.BigIntegers import org.bouncycastle.util.BigIntegers
import java.io.IOException
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.security.KeyFactory import java.security.KeyFactory
@ -19,18 +19,21 @@ import java.time.OffsetDateTime
import java.time.Period import java.time.Period
import java.time.ZoneOffset import java.time.ZoneOffset
import java.util.Date import java.util.Date
import java.util.jar.JarFile
class Pkcs12KeyStore private constructor(private val path: Path) { class Pkcs12KeyStore private constructor(privateKeyEntry: KeyStore.PrivateKeyEntry) {
fun signJar(jar: Path) { private val signer = JarSigner.Builder(privateKeyEntry)
exec( .signatureAlgorithm("SHA256withRSA")
"jarsigner", .digestAlgorithm("SHA-256")
"-keystore", path.toString(), .signerName(SIGNER_NAME)
"-storetype", "pkcs12", .build()
"-storepass", PASSWORD,
"-keypass", PASSWORD, fun signJar(input: Path, output: Path) {
jar.toString(), JarFile(input.toFile()).use { file ->
ALIAS Files.newOutputStream(output).use { os ->
) signer.sign(file, os)
}
}
} }
companion object { companion object {
@ -43,8 +46,9 @@ class Pkcs12KeyStore private constructor(private val path: Path) {
private const val SERIAL_LENGTH = 128 private const val SERIAL_LENGTH = 128
// TODO(gpe): add support for overriding this // TODO(gpe): add support for overriding this
private const val SIGNER_NAME = "OpenRS2"
private val DNAME = X500NameBuilder() private val DNAME = X500NameBuilder()
.addRDN(BCStyle.CN, "OpenRS2") .addRDN(BCStyle.CN, SIGNER_NAME)
.build() .build()
private val MAX_CLOCK_SKEW = Period.ofDays(1) private val MAX_CLOCK_SKEW = Period.ofDays(1)
@ -63,15 +67,20 @@ class Pkcs12KeyStore private constructor(private val path: Path) {
keyStore.load(null) keyStore.load(null)
} }
if (!keyStore.containsAlias(ALIAS)) { val privateKeyEntry = if (keyStore.containsAlias(ALIAS)) {
keyStore.setEntry(ALIAS, createPrivateKeyEntry(), PASSWORD_PARAMETER) keyStore.getEntry(ALIAS, PASSWORD_PARAMETER) as KeyStore.PrivateKeyEntry
} else {
val entry = createPrivateKeyEntry()
keyStore.setEntry(ALIAS, entry, PASSWORD_PARAMETER)
Files.newOutputStream(path).use { output -> Files.newOutputStream(path).use { output ->
keyStore.store(output, PASSWORD_CHARS) keyStore.store(output, PASSWORD_CHARS)
} }
entry
} }
return Pkcs12KeyStore(path) return Pkcs12KeyStore(privateKeyEntry)
} }
private fun createPrivateKeyEntry(): KeyStore.PrivateKeyEntry { private fun createPrivateKeyEntry(): KeyStore.PrivateKeyEntry {
@ -98,15 +107,5 @@ class Pkcs12KeyStore private constructor(private val path: Path) {
val jcaCertificate = JcaX509CertificateConverter().getCertificate(certificate) val jcaCertificate = JcaX509CertificateConverter().getCertificate(certificate)
return KeyStore.PrivateKeyEntry(jcaPrivate, arrayOf(jcaCertificate)) return KeyStore.PrivateKeyEntry(jcaPrivate, arrayOf(jcaCertificate))
} }
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")
}
}
} }
} }

Loading…
Cancel
Save