From bd59a06e4953493fcf7013d752b245bc65578ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Sun, 24 Sep 2023 21:04:23 +0200 Subject: [PATCH] Simplify nonce verify --- .../schools/integrity/GenerateRandom.kt | 7 ---- .../schools/integrity/TokenDecrypt.kt | 4 -- .../schools/integrity/ValidateCommand.kt | 38 ++----------------- 3 files changed, 4 insertions(+), 45 deletions(-) delete mode 100644 src/main/kotlin/io/github/wulkanowy/schools/integrity/GenerateRandom.kt diff --git a/src/main/kotlin/io/github/wulkanowy/schools/integrity/GenerateRandom.kt b/src/main/kotlin/io/github/wulkanowy/schools/integrity/GenerateRandom.kt deleted file mode 100644 index 0d8248f..0000000 --- a/src/main/kotlin/io/github/wulkanowy/schools/integrity/GenerateRandom.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.github.wulkanowy.schools.integrity - -const val RANDOM_BYTE_COUNT = 16 - -fun ByteArray.toHexString(): String = joinToString(separator = "") { - currentByte -> "%02x".format(currentByte) } - diff --git a/src/main/kotlin/io/github/wulkanowy/schools/integrity/TokenDecrypt.kt b/src/main/kotlin/io/github/wulkanowy/schools/integrity/TokenDecrypt.kt index 2639d39..9b07f86 100644 --- a/src/main/kotlin/io/github/wulkanowy/schools/integrity/TokenDecrypt.kt +++ b/src/main/kotlin/io/github/wulkanowy/schools/integrity/TokenDecrypt.kt @@ -8,7 +8,6 @@ import com.google.auth.http.HttpCredentialsAdapter import com.google.auth.oauth2.GoogleCredentials import com.google.common.collect.Lists import kotlinx.serialization.json.Json -import java.util.logging.Logger fun decryptToken(tokenString: String, playIntegrity: PlayIntegrity = getPlayIntegrity()): IntegrityVerdictPayload { val decodeTokenRequest = DecodeIntegrityTokenRequest().setIntegrityToken(tokenString) @@ -17,9 +16,6 @@ fun decryptToken(tokenString: String, playIntegrity: PlayIntegrity = getPlayInte .execute() .toPrettyString() - val log = Logger.getLogger("decryptToken") - log.info("Decrypted token: $returnString") - return Json.decodeFromString(returnString) } diff --git a/src/main/kotlin/io/github/wulkanowy/schools/integrity/ValidateCommand.kt b/src/main/kotlin/io/github/wulkanowy/schools/integrity/ValidateCommand.kt index 4bb9e23..1b353ad 100644 --- a/src/main/kotlin/io/github/wulkanowy/schools/integrity/ValidateCommand.kt +++ b/src/main/kotlin/io/github/wulkanowy/schools/integrity/ValidateCommand.kt @@ -1,7 +1,5 @@ package io.github.wulkanowy.schools.integrity -import java.security.MessageDigest -import java.util.* import java.util.logging.Logger // Package name of the client application @@ -15,28 +13,15 @@ const val VERDICT_VAL_MEETS_VIRTUAL_INTEGRITY = "MEETS_VIRTUAL_INTEGRITY" const val VERDICT_VAL_VERSION_UNRECOGNIZED = "UNRECOGNIZED_VERSION" const val VERDICT_VAL_VERSION_RECOGNIZED = "PLAY_RECOGNIZED" const val VERDICT_VAL_LICENSED = "LICENSED" -const val VERDICT_VAL_UNLICENSED = "UNLICENSED" fun validateCommand(originalNonce: String, integrityVerdict: IntegrityVerdict): ValidateResult { if (integrityVerdict.requestDetails.nonce != null) { - var nonceString: String = integrityVerdict.requestDetails.nonce - // Server might re-pad base64 with unicode '=', trim any that exist to - // match our web-safe original - val utfEqualRegex = "\\u003d$".toRegex() - nonceString = utfEqualRegex.replace(nonceString, "") - // The nonce string contains two parts, the random number previously generated, - // and the SHA256 hash of the command string, we need to separate them - // The values were written out as hex values, so they are base64 compatible, but - // we don't actually base64 decode them. - val randomString = nonceString.slice(IntRange(0, (RANDOM_BYTE_COUNT * 2) - 1)) - val hashString = nonceString.slice(IntRange(RANDOM_BYTE_COUNT * 2, nonceString.lastIndex)) - + val decryptedNonce = integrityVerdict.requestDetails.nonce val log = Logger.getLogger("validateCommand") - log.info("Raw nonce: $nonceString") - log.info("Random nonce segment: $randomString") - log.info("Hash nonce segment: $hashString") + log.info("Original nonce: $originalNonce") + log.info("Decrypted nonce: $decryptedNonce") - return if (validateHash(originalNonce, hashString)) { + return if (originalNonce == decryptedNonce) { if (validateVerdict(integrityVerdict)) { ValidateResult.VALIDATE_SUCCESS } else { @@ -49,21 +34,6 @@ fun validateCommand(originalNonce: String, integrityVerdict: IntegrityVerdict): return ValidateResult.VALIDATE_NONCE_NOT_FOUND } -fun validateHash(commandString: String, hashString: String): Boolean { - val messageDigest = MessageDigest.getInstance("SHA-256") - val commandHashBytes = messageDigest.digest(commandString.toByteArray(Charsets.UTF_8)) - val commandHashString = commandHashBytes.toHexString() - val hashMatch = hashString.contentEquals(commandHashString) - - val log = Logger.getLogger("validateHash") - log.info("Command string: $commandString") - log.info("token hash string: $hashString") - log.info("command hash string: $commandHashString") - log.info("hashMatch: $hashMatch") - - return hashMatch -} - fun validateVerdict(integrityVerdict: IntegrityVerdict): Boolean { // Process the integrity verdict and 'validate' the command if the following positive // signals exist: