Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDK updates and log_list.json #108

Open
gnair03 opened this issue Mar 18, 2024 · 7 comments
Open

SDK updates and log_list.json #108

gnair03 opened this issue Mar 18, 2024 · 7 comments

Comments

@gnair03
Copy link

gnair03 commented Mar 18, 2024

Is there anyway to supply my own log_list.json file?
Thing is, I am using 2.4.0 of this lib in my app. If logserver fetch fails, the fallback log_list.json embedded in the SDK is outdated (older than 70 days). Due to the logic added in the SDK, CT Checks get disabled in this particular scenario. The only solution would be to upgrade the SDK. This can be a constant overhead, considering that the SDK is updated with loglist.json every week or two. To overcome this issue, is there anyway to supply my own log_list.json file? Or anyway to override the 70 days logic within the SDK?

@mattmook pls let me know, since my app is on production and this needs to be solved for asap.

@gnair03
Copy link
Author

gnair03 commented Mar 19, 2024

@mattmook -
I was thinking about using the below method:

LogListDataSourceFactory.createDataSource(
                logListService = LogListDataSourceFactory.createLogListService(LOG_SERVER_BASE_URL),
                diskCache = AndroidDiskCache(appContext)
)

but provide my own implementation of the AndroidDiskCache class. But I dont understand how to create the log-list.sig file at my end. Could you pls help here? Is this even do-able?

@dsatija
Copy link

dsatija commented Apr 17, 2024

Hi @gnair03 , were you able to resolve this?

@sergeich
Copy link

Temporary workaround. It's mainly a copy of AndroidDiskCache from the library but with some changes for the case of not existent cache. I've put log_list.json and log_list.sig to raw resource folder and renamed them. Files could be downloaded from the last commit: 8efb161

internal class AndroidDiskCache(context: Context) : DiskCache {
    private val cacheDirPath = "${context.cacheDir.path}/certificate-transparency-android"
    private val resources = context.resources

    override suspend fun get(): RawLogListResult? {
        mutex.withLock {
            return try {
                val jsonFile = File(cacheDirPath, LOG_LIST_FILE)
                val sigFile = File(cacheDirPath, SIG_FILE)
                val logList = jsonFile.readBytes()
                val signature = sigFile.readBytes()

                RawLogListResult.Success(logList, signature)
            } catch (ignored: IOException) {
                with(this::class.java.classLoader) {
                    val logList = resources.openRawResource(R.raw.log_list_json)?.use { it.readBytes() } ?: return RawLogListResult.Failure()
                    val signature = resources.openRawResource(R.raw.log_list_sig)?.use { it.readBytes() } ?: return RawLogListResult.Failure()

                    return RawLogListResult.Success(logList, signature)
                }
            }
        }
    }

    override suspend fun set(value: RawLogListResult) {
        mutex.withLock {
            if (value is RawLogListResult.Success) {
                try {
                    File(cacheDirPath).mkdirs()

                    File(cacheDirPath, LOG_LIST_FILE).writeBytes(value.logList)
                    File(cacheDirPath, SIG_FILE).writeBytes(value.signature)
                } catch (ignored: IOException) {
                    // non fatal
                }
            }
        }
    }

    public companion object {
        private const val LOG_LIST_FILE = "loglist.json"
        private const val SIG_FILE = "loglist.sig"

        /**
         * Ensure only one instance of AndroidDiskCache can read/write at a time
         */
        private val mutex = Mutex()
    }
}

@dsatija
Copy link

dsatija commented Apr 25, 2024

Thankyou so much !
@sergeich do you know what happens after 70 days , since the last commit was on mar 7 ? may 17 would make it 70 days old

@mattmook
Copy link
Member

@dsatija CT checks will continue to work even after 70 days assuming the device is caching locally and/or can download a fresh copy of the log list files. Basically the small edge case is a fresh install where the list cannot be updated to a newer version (for example if google were to move the file) then at that point the client follows how Chrome works in that scenario and will disable CT checks.

@mattmook
Copy link
Member

mattmook commented May 17, 2024

@gnair03 The log-list.sig file is signed by Googles private key, so you cannot simply create one directly. Google provide a zip file which contains matching json and sig so in that sense it doesn't necessarily matter. Of course, if you want to sign the log-list file yourself with your own private key then you can do that and provide a public key to the createDataSource function.

@mattmook
Copy link
Member

@gnair03 The longer answer to your initial question around the 70 days is while we attempt to update the library with an updated cached version as per my comment 2 messages up in most use cases it doesn't really matter.

Indeed, the original version of the library didn't have any log-list file embedded and solely relies on being able to download the file. So, the newer version is an improvement on that giving that 70 day period where checks can still be enforced even if the client is unable to update the list itself.

So as long as the log-list is cached then the risk is to clients who are unable to update for 70 days; the hope is this is quite a small number of clients.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants