mirror of
https://github.com/revanced/revanced-api.git
synced 2025-04-29 22:24:31 +02:00
feat: Add configuration to specify public key id
This commit is contained in:
parent
97a5d119ec
commit
ad7d4b226f
@ -51,6 +51,7 @@ internal class ConfigurationRepository(
|
|||||||
* @property assetRegex The regex matching the asset name.
|
* @property assetRegex The regex matching the asset name.
|
||||||
* @property signatureAssetRegex The regex matching the signature asset name to verify the asset.
|
* @property signatureAssetRegex The regex matching the signature asset name to verify the asset.
|
||||||
* @property publicKeyFile The public key file to verify the signature of the asset.
|
* @property publicKeyFile The public key file to verify the signature of the asset.
|
||||||
|
* @property publicKeyId The ID of the public key to verify the signature of the asset.
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
internal class AssetConfiguration(
|
internal class AssetConfiguration(
|
||||||
@ -64,6 +65,8 @@ internal class ConfigurationRepository(
|
|||||||
@Serializable(with = FileSerializer::class)
|
@Serializable(with = FileSerializer::class)
|
||||||
@SerialName("public-key-file")
|
@SerialName("public-key-file")
|
||||||
val publicKeyFile: File,
|
val publicKeyFile: File,
|
||||||
|
@SerialName("public-key-id")
|
||||||
|
val publicKeyId: Long,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ internal class PatchesService(
|
|||||||
patchesFile,
|
patchesFile,
|
||||||
signatureDownloadUrl,
|
signatureDownloadUrl,
|
||||||
configurationRepository.patches.publicKeyFile,
|
configurationRepository.patches.publicKeyFile,
|
||||||
|
configurationRepository.patches.publicKeyId,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
PatchBundleLoader.Jar(patchesFile)
|
PatchBundleLoader.Jar(patchesFile)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package app.revanced.api.configuration.services
|
package app.revanced.api.configuration.services
|
||||||
|
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
|
||||||
import org.bouncycastle.openpgp.*
|
import org.bouncycastle.openpgp.*
|
||||||
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator
|
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator
|
||||||
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider
|
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider
|
||||||
@ -9,7 +8,6 @@ import java.io.File
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.Security
|
|
||||||
|
|
||||||
internal class SignatureService {
|
internal class SignatureService {
|
||||||
private val signatureCache = Caffeine
|
private val signatureCache = Caffeine
|
||||||
@ -21,6 +19,7 @@ internal class SignatureService {
|
|||||||
file: File,
|
file: File,
|
||||||
signatureDownloadUrl: String,
|
signatureDownloadUrl: String,
|
||||||
publicKeyFile: File,
|
publicKeyFile: File,
|
||||||
|
publicKeyId: Long,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val fileBytes = file.readBytes()
|
val fileBytes = file.readBytes()
|
||||||
|
|
||||||
@ -28,7 +27,8 @@ internal class SignatureService {
|
|||||||
verify(
|
verify(
|
||||||
fileBytes = fileBytes,
|
fileBytes = fileBytes,
|
||||||
signatureInputStream = URL(signatureDownloadUrl).openStream(),
|
signatureInputStream = URL(signatureDownloadUrl).openStream(),
|
||||||
publicKeyInputStream = publicKeyFile.inputStream(),
|
publicKeyFileInputStream = publicKeyFile.inputStream(),
|
||||||
|
publicKeyId = publicKeyId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,37 +36,32 @@ internal class SignatureService {
|
|||||||
private fun verify(
|
private fun verify(
|
||||||
fileBytes: ByteArray,
|
fileBytes: ByteArray,
|
||||||
signatureInputStream: InputStream,
|
signatureInputStream: InputStream,
|
||||||
publicKeyInputStream: InputStream,
|
publicKeyFileInputStream: InputStream,
|
||||||
|
publicKeyId: Long,
|
||||||
) = getSignature(signatureInputStream).apply {
|
) = getSignature(signatureInputStream).apply {
|
||||||
init(BcPGPContentVerifierBuilderProvider(), getPublicKey(publicKeyInputStream))
|
init(BcPGPContentVerifierBuilderProvider(), getPublicKey(publicKeyFileInputStream, publicKeyId))
|
||||||
update(fileBytes)
|
update(fileBytes)
|
||||||
}.verify()
|
}.verify()
|
||||||
|
|
||||||
private fun getPublicKey(publicKeyInputStream: InputStream): PGPPublicKey {
|
private fun getPublicKey(
|
||||||
val decoderStream = PGPUtil.getDecoderStream(publicKeyInputStream)
|
publicKeyFileInputStream: InputStream,
|
||||||
|
publicKeyId: Long,
|
||||||
|
): PGPPublicKey {
|
||||||
|
val decoderStream = PGPUtil.getDecoderStream(publicKeyFileInputStream)
|
||||||
|
val pgpPublicKeyRingCollection = PGPPublicKeyRingCollection(decoderStream, BcKeyFingerprintCalculator())
|
||||||
|
val publicKeyRing = pgpPublicKeyRingCollection.getPublicKeyRing(publicKeyId)
|
||||||
|
?: throw IllegalArgumentException("Can't find public key ring with ID $publicKeyId.")
|
||||||
|
|
||||||
PGPPublicKeyRingCollection(decoderStream, BcKeyFingerprintCalculator()).forEach { keyRing ->
|
return publicKeyRing.getPublicKey(publicKeyId)
|
||||||
keyRing.publicKeys.forEach { publicKey ->
|
?: throw IllegalArgumentException("Can't find public key with ID $publicKeyId.")
|
||||||
if (publicKey.isEncryptionKey) {
|
|
||||||
return publicKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw IllegalArgumentException("Can't find encryption key in key ring.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSignature(inputStream: InputStream): PGPSignature {
|
private fun getSignature(inputStream: InputStream): PGPSignature {
|
||||||
val decoderStream = PGPUtil.getDecoderStream(inputStream)
|
val decoderStream = PGPUtil.getDecoderStream(inputStream)
|
||||||
val pgpObjectFactory = PGPObjectFactory(decoderStream, BcKeyFingerprintCalculator())
|
val pgpSignatureList = PGPObjectFactory(decoderStream, BcKeyFingerprintCalculator()).first {
|
||||||
val signatureList = pgpObjectFactory.nextObject() as PGPSignatureList
|
it is PGPSignatureList
|
||||||
|
} as PGPSignatureList
|
||||||
|
|
||||||
return signatureList.first()
|
return pgpSignatureList.first()
|
||||||
}
|
|
||||||
|
|
||||||
private companion object {
|
|
||||||
init {
|
|
||||||
Security.addProvider(BouncyCastleProvider())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user