/* * SPDX-License-Identifier: MPL-2.0 * Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) */ package emu.skyline import android.content.Context import android.net.Uri import android.util.Log import androidx.documentfile.provider.DocumentFile import java.io.File object KeyReader { private val Tag = KeyReader::class.java.simpleName enum class KeyType(val keyName : String, val fileName : String) { Title("title_keys", "title.keys"), Prod("prod_keys", "prod.keys"); companion object { fun parse(keyName : String) = values().first { it.keyName == keyName } } } /** * Reads keys file, trims and writes to internal app data storage, it makes sure file is properly formatted */ fun import(context : Context, uri : Uri, keyType : KeyType) : Boolean { Log.i(Tag, "Parsing ${keyType.name}") if (!DocumentFile.isDocumentUri(context, uri)) return false val fileName = DocumentFile.fromSingleUri(context, uri)!!.name if (fileName?.substringAfterLast('.')?.startsWith("keys")?.not() == true) return false val tmpOutputFile = File("${context.filesDir.canonicalFile}/${keyType.fileName}.tmp") val inputStream = context.contentResolver.openInputStream(uri) tmpOutputFile.bufferedWriter().use { writer -> val valid = inputStream!!.bufferedReader().useLines { for (line in it) { val pair = line.split("=") if (pair.size != 2) return@useLines false val key = pair[0].trim() val value = pair[1].trim() when (keyType) { KeyType.Title -> { if (key.length != 32 && !isHexString(key)) return@useLines false if (value.length != 32 && !isHexString(value)) return@useLines false } KeyType.Prod -> { if (!key.contains("_")) return@useLines false if (!isHexString(value)) return@useLines false } } writer.append("$key=$value\n") } true } if (valid) tmpOutputFile.renameTo(File("${tmpOutputFile.parent}/${keyType.fileName}")) return valid } } private fun isHexString(str : String) : Boolean { for (c in str) if (!(c in '0'..'9' || c in 'a'..'f' || c in 'A'..'F')) return false return true } }