All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyTrustManagerBasic.kt Maven / Gradle / Ivy

There is a newer version: 2.5.65
Show newest version
/*
 * Copyright 2021-2024 Appmattus Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.appmattus.certificatetransparency.internal.verifier

import com.appmattus.certificatetransparency.CTLogger
import com.appmattus.certificatetransparency.CTPolicy
import com.appmattus.certificatetransparency.VerificationResult
import com.appmattus.certificatetransparency.cache.DiskCache
import com.appmattus.certificatetransparency.chaincleaner.CertificateChainCleanerFactory
import com.appmattus.certificatetransparency.datasource.DataSource
import com.appmattus.certificatetransparency.internal.utils.asn1.query.query
import com.appmattus.certificatetransparency.internal.utils.asn1.toAsn1
import com.appmattus.certificatetransparency.internal.verifier.model.Host
import com.appmattus.certificatetransparency.loglist.LogListResult
import com.appmattus.certificatetransparency.loglist.LogListService
import java.lang.reflect.Method
import java.security.cert.Certificate
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.X509TrustManager

@Suppress("LongParameterList", "CustomX509TrustManager")
internal class CertificateTransparencyTrustManagerBasic(
    private val delegate: X509TrustManager,
    includeHosts: Set,
    excludeHosts: Set,
    certificateChainCleanerFactory: CertificateChainCleanerFactory?,
    logListService: LogListService?,
    logListDataSource: DataSource?,
    policy: CTPolicy?,
    diskCache: DiskCache?,
    private val failOnError: Boolean = true,
    private val logger: CTLogger? = null
) : X509TrustManager, CertificateTransparencyTrustManager {

    private val ctBase = CertificateTransparencyBase(
        includeHosts = includeHosts,
        excludeHosts = excludeHosts,
        certificateChainCleanerFactory = certificateChainCleanerFactory,
        trustManager = delegate,
        logListService = logListService,
        logListDataSource = logListDataSource,
        policy = policy,
        diskCache = diskCache
    )

    private val checkServerTrustedMethod: Method? = try {
        delegate::class.java.getDeclaredMethod(
            "checkServerTrusted",
            Array::class.java,
            String::class.java,
            String::class.java
        )
    } catch (ignored: NoSuchMethodException) {
        null
    }

    private val isSameTrustConfigurationMethod: Method? = try {
        delegate::class.java.getDeclaredMethod("isSameTrustConfiguration", String::class.java, String::class.java)
    } catch (ignored: NoSuchMethodException) {
        null
    }

    override fun verifyCertificateTransparency(host: String, certificates: List): VerificationResult =
        ctBase.verifyCertificateTransparency(host, certificates)

    override fun checkClientTrusted(chain: Array, authType: String) = delegate.checkClientTrusted(
        chain,
        authType
    )

    override fun checkServerTrusted(chain: Array, authType: String) {
        delegate.checkServerTrusted(chain, authType)

        val leafCertificate = chain.first()

        val commonName = leafCertificate.subjectX500Principal.encoded.toAsn1().query {
            seq().firstOrNull { it.seq().first().seq().first().oid() == "2.5.4.3" }?.seq()?.first()?.seq()?.get(1)?.string()
        } ?: throw CertificateException("No commonName found in certificate subjectDN")

        val result = verifyCertificateTransparency(commonName, chain.toList())

        logger?.log(commonName, result)

        if (result is VerificationResult.Failure && failOnError) {
            throw CertificateException("Certificate transparency failed")
        }
    }

    // Called through reflection by X509TrustManagerExtensions on Android
    @Suppress("unused")
    fun checkServerTrusted(chain: Array, authType: String, host: String): List {
        @Suppress("UNCHECKED_CAST")
        val certs = checkServerTrustedMethod!!.invoke(delegate, chain, authType, host) as List

        val result = verifyCertificateTransparency(host, certs.toList())

        logger?.log(host, result)

        if (result is VerificationResult.Failure && failOnError) {
            throw CertificateException("Certificate transparency failed")
        }

        return certs
    }

    // Called through reflection by X509TrustManagerExtensions on Android
    @Suppress("unused")
    fun isSameTrustConfiguration(hostname1: String?, hostname2: String?): Boolean {
        return isSameTrustConfigurationMethod!!.invoke(delegate, hostname1, hostname2) as Boolean
    }

    override fun getAcceptedIssuers(): Array = delegate.acceptedIssuers
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy