### Basic Installation Example (Android) Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs the CT provider with a basic configuration including a domain. This is suitable for Android applications. ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() installCertificateTransparencyProvider { +"*.example.com" } } } ``` -------------------------------- ### Basic CRInterceptorBuilder Setup Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRInterceptorBuilder.md Demonstrates basic setup of CRInterceptorBuilder, adding a CRL, setting a logger, and building the OkHttp client with the interceptor. ```kotlin val interceptor = CRInterceptorBuilder() .addCrl( issuerDistinguishedName = "ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQQ==", serialNumbers = listOf( "Aa8e+91erglSMgsk/mtVaA==", "A3G1iob2zpw+y3v0L5II/A==" ) ) .setLogger(MyRevocationLogger()) .build() val httpClient = OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build() ``` -------------------------------- ### Installation with Logging Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs the CT provider with a custom logger and includes/excludes specific domains. Useful for debugging and controlling verification. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate() installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) +"example.com" -"internal.example.com" } } } ``` -------------------------------- ### Java Security Provider Usage Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTLogger.md Example of installing the Certificate Transparency Java Security Provider and configuring a CTLogger. ```kotlin installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) +"*.example.com" } ``` -------------------------------- ### Install Certificate Transparency Provider on Android Source: https://github.com/appmattus/certificatetransparency/blob/main/README.md Configure certificate transparency at app startup on Android by installing the Java Security Provider. This setup works across network types and with WebViews, but avoid on Android 6.0 and lower due to known issues. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate() installCertificateTransparencyProvider { // Setup a logger // NOTE: The logger outputs the host name and certificate // transparency results which could be considered sensitive data. // Please ensure you review your usage. logger = BasicAndroidCTLogger(BuildConfig.DEBUG) // Setup disk cache diskCache = AndroidDiskCache(applicationContext) // Exclude any subdomain but not "appmattus.com" with no subdomain -"*.appmattus.com" // Exclude specified domain -"example.com" // Override the exclusion by including a specific subdomain +"allowed.appmattus.com" } } } ``` -------------------------------- ### Installation with Disk Cache Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs the CT provider with a logger and a disk cache for performance. This configuration is beneficial for caching verification results. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate()n installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) diskCache = AndroidDiskCache(this@SampleApplication) +"*.example.com" } } } ``` -------------------------------- ### Install Certificate Transparency Provider as Security Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTTrustManagerBuilder.md Installs the Certificate Transparency provider as a Java Security Provider for all connections. This example demonstrates configuring logger, disk cache, and common name inclusion via the DSL. ```kotlin // Install as Java Security Provider for all connections installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) diskCache = AndroidDiskCache(context) +"*.example.com" } ``` -------------------------------- ### Usage with Java Security Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md Example of installing the Certificate Transparency provider with a disk cache in an Android Application's onCreate method. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate() installCertificateTransparencyProvider { diskCache = AndroidDiskCache(this) +("*.example.com") } } } ``` -------------------------------- ### WebView Integration with CTProvider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Demonstrates how to integrate the CTProvider for securing all WebView connections. Ensure the provider is installed early, for example, in Application.onCreate(). Note potential issues on Android 6.0 and below. ```kotlin class MainActivity : AppCompatActivity() { private lateinit var webView: WebView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Provider installed in Application.onCreate // Now all WebView connections are verified webView = WebView(this) webView.loadUrl("https://example.com") } } ``` -------------------------------- ### Structured Logging Example Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTLogger.md Implement structured logging to record specific details about verification results. This example logs different events with relevant data maps for success and failure cases. ```kotlin class StructuredLogger(private val logger: Logger) : CTLogger { override fun log(host: String, result: VerificationResult) { when (result) { is VerificationResult.Success.Trusted -> { logger.info("ct_success", mapOf( "host" to host, "sct_count" to result.scts.size, "sct_ids" to result.scts.keys.toList() )) } is VerificationResult.Failure.TooFewSctsTrusted -> { logger.warn("ct_failure_too_few_scts", mapOf( "host" to host, "required" to result.minSctCount, "found" to result.scts.count { it.value is SctVerificationResult.Valid } )) } else -> { logger.warn("ct_failure", mapOf( "host" to host, "failure_type" to result::class.simpleName )) } } } } ``` -------------------------------- ### Basic CTTrustManager Setup with Android Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTTrustManagerBuilder.md Demonstrates a basic setup of CTTrustManagerBuilder in an Android environment, including delegate trust manager initialization, common name inclusion/exclusion, logger, and disk cache configuration. ```kotlin val factory = TrustManagerFactory.getInstance("X509").apply { init(null as KeyStore?) } val delegateTrustManager = factory.trustManagers .filterIsInstance() .first() val trustManager = CTTrustManagerBuilder(delegateTrustManager) .includeCommonName("example.com", "*.example.com") .excludeCommonName("internal.example.com") .setLogger(BasicAndroidCTLogger(BuildConfig.DEBUG)) .setDiskCache(AndroidDiskCache(context)) .build() val sslContext = SSLContext.getInstance("TLS").apply { init(null, arrayOf(trustManager), null) } ``` -------------------------------- ### OkHttp Setup with Retrofit and CTInterceptor Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTInterceptorBuilder.md Shows how to integrate the CTInterceptor with Retrofit for API calls. ```kotlin val httpClient = OkHttpClient.Builder() .addNetworkInterceptor( CTInterceptorBuilder() .includeHost("api.example.com") .setLogger(BasicAndroidCTLogger(BuildConfig.DEBUG)) .setDiskCache(AndroidDiskCache(context)) .build() ) .build() val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com") .client(httpClient) .addConverterFactory(GsonConverterFactory.create()) .build() ``` -------------------------------- ### Basic OkHttp Setup with CTInterceptor Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTInterceptorBuilder.md Demonstrates setting up an OkHttp client with the CTInterceptor, including hosts and excluding others. ```kotlin val httpClient = OkHttpClient.Builder() .addNetworkInterceptor( CTInterceptorBuilder() .includeHost("example.com") .excludeHost("internal.example.com") .setLogger(MyLogger()) .setDiskCache(AndroidDiskCache(context)) .build() ) .build() val response = httpClient.newCall(request).execute() ``` -------------------------------- ### Installing and Removing CTProvider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Illustrates the lifecycle management of the CTProvider, including initial installation with specific configurations and subsequent removal or reinstallation with different settings. Note that a provider cannot be reinstalled with the same name until it is removed. ```kotlin // Installation in Application.onCreate installCertificateTransparencyProvider { +"*.example.com" } // Later, if needed, remove removeCertificateTransparencyProvider() // Reinstall with different config installCertificateTransparencyProvider { +"*.different.com" } ``` -------------------------------- ### Basic OkHttp Setup with CTHostnameVerifierBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Demonstrates initializing `CTHostnameVerifierBuilder` with OkHttp, configuring trust managers, hosts, logging, caching, and building the verifier. ```kotlin val trustManager = TrustManagerFactory.getInstance("X509").apply { init(null as KeyStore?) }.trustManagers.filterIsInstance().first() val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setTrustManager(trustManager) .includeHost("example.com", "*.example.com") .excludeHost("internal.example.com") .setLogger(BasicAndroidCTLogger(BuildConfig.DEBUG)) .setDiskCache(AndroidDiskCache(context)) .build() val sslContext = SSLContext.getInstance("TLS").apply { init(null, arrayOf(trustManager), null) } sslContext.socketFactory ``` -------------------------------- ### Basic Setup with CTHostnameVerifierBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Demonstrates how to instantiate BasicAndroidCTLogger and set it on a CTHostnameVerifierBuilder. This is useful for logging verification results during hostname verification. ```kotlin val logger = BasicAndroidCTLogger(BuildConfig.DEBUG) val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setLogger(logger) .build() ``` -------------------------------- ### Troubleshooting: Provider Already Installed Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Demonstrates how to resolve the 'Cannot register duplicate Security Provider' error by removing the existing provider before attempting to install a new one, or by specifying a different name for the new provider. ```kotlin // Error: Cannot register duplicate Security Provider with name "CertificateTransparency" // Solution: Use different name or remove first removeCertificateTransparencyProvider("CertificateTransparency") installCertificateTransparencyProvider() ``` -------------------------------- ### Install Certificate Transparency Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/INDEX.md Install the Certificate Transparency provider globally for all Java/Android TLS connections. Specify hosts to include in the provider's configuration. ```kotlin installCertificateTransparencyProvider { +"example.com" } // Works with all Java/Android TLS connections ``` -------------------------------- ### AndroidDiskCache Usage Example Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DiskCache.md Demonstrates how to instantiate and use AndroidDiskCache with CTInterceptorBuilder. ```kotlin val cache = AndroidDiskCache(context) val interceptor = CTInterceptorBuilder() .setDiskCache(cache) .build() ``` -------------------------------- ### Conditional Logging Example Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTLogger.md Implement conditional logging based on debug mode or an allowed hosts list. This example skips logging for hosts not in the allowed list when not in debug mode. ```kotlin class ConditionalLogger( private val debugMode: Boolean, private val allowedHosts: Set ) : CTLogger { override fun log(host: String, result: VerificationResult) { if (!debugMode && host !in allowedHosts) { return // Skip logging this host in production } Log.d("CT", "$host: $result") } } ``` -------------------------------- ### Install CT Provider with WhitelistPolicy in Java Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTPolicy.md Installs a Certificate Transparency provider in Java security, configuring it with a WhitelistPolicy that trusts specific operators and includes host patterns. ```kotlin installCertificateTransparencyProvider { policy = WhitelistPolicy(setOf("Google", "DigiCert")) +"*.example.com" } ``` -------------------------------- ### Install Certificate Transparency Java Security Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/configuration.md Install the Certificate Transparency Java Security Provider for system-wide checks. Configure the logger, disk cache, and host patterns for inclusion and exclusion. ```kotlin installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) diskCache = AndroidDiskCache(context) // Include patterns +"*.example.com" -"internal.example.com" } ``` -------------------------------- ### Install Multiple CT Providers with Different Configurations Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs two CT providers with distinct configurations and names, then removes one. This allows for flexible and granular CT verification policies. ```kotlin // Install with different configurations installCertificateTransparencyProvider( providerName = "CT-Strict", init = { +"*.critical.com" failOnError = { true } // Always fail on error } ) installCertificateTransparencyProvider( providerName = "CT-Permissive", init = { +"*.example.com" failOnError = { failure -> failure !is VerificationResult.Failure.NoScts } } ) // Later, remove one removeCertificateTransparencyProvider("CT-Permissive") ``` -------------------------------- ### Thread-safe get Method Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md Illustrates the thread-safe implementation of the get method using a Mutex to protect file access. ```kotlin private val mutex = Mutex() override suspend fun get(): RawLogListResult? { mutex.withLock { // Thread-safe file access ... } } ``` -------------------------------- ### CRInterceptorBuilder Setup with Retrofit Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRInterceptorBuilder.md Shows how to integrate CRInterceptorBuilder with Retrofit by adding the interceptor to the OkHttpClient used by Retrofit. ```kotlin val interceptor = CRInterceptorBuilder() .addCrl( issuerDistinguishedName = "ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmM=", serialNumbers = listOf("Aa8e+91erglSMgsk/mtVaA==") ) .setFailOnError(true) .build() val httpClient = OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build() val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com") .client(httpClient) .addConverterFactory(GsonConverterFactory.create()) .build() ``` -------------------------------- ### Install Certificate Transparency Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs a Java Security Provider for CT verification. Configures trust manager via a DSL. Affects all subsequent TLS connections. ```kotlin installCertificateTransparencyProvider( providerName: String = DEFAULT_PROVIDER_NAME, init: CTTrustManagerBuilder.() -> Unit = {} ) ``` -------------------------------- ### Setup with CTTrustManagerBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Shows how to integrate BasicAndroidCTLogger with CTTrustManagerBuilder to log certificate trust verification outcomes. This ensures that trust decisions are logged for debugging or auditing. ```kotlin val logger = BasicAndroidCTLogger(BuildConfig.DEBUG) val trustManager = CTTrustManagerBuilder(delegateTm) .setLogger(logger) .build() ``` -------------------------------- ### Usage Pattern for reuseInflight Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Demonstrates how to use reuseInflight to ensure multiple concurrent get() calls only hit the network once. ```kotlin val dataSource = logListDataSource.reuseInflight() // Multiple concurrent get() calls only hit the network once ``` -------------------------------- ### Install Certificate Transparency Provider with Exclusions and Inclusions Source: https://github.com/appmattus/certificatetransparency/blob/main/docs/using-certificate-transparency-in-sdks.md Configure the Certificate Transparency provider by excluding all domains by default and then explicitly including specific domains and subdomains for checks. This is useful for fine-grained control over CT validation. ```kotlin installCertificateTransparencyProvider(providerName = "CT-SDK") { // Exclude checks on all domains -"*.*" // Override the exclusion for a specific domain +"*.appmattus.com" // or subdomain +"subdomain.appmattus.com" } ``` -------------------------------- ### Integrate Disk Cache with CTHostnameVerifierBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DiskCache.md Example of setting a disk cache for hostname verification. This allows the verifier to use cached data for faster lookups. ```kotlin val cache = AndroidDiskCache(context) val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setDiskCache(cache) .includeHost("*.example.com") .build() ``` -------------------------------- ### CTTrustManagerBuilder Usage Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTLogger.md Example of configuring a CTTrustManagerBuilder with a CTLogger to monitor verification outcomes. ```kotlin val logger = BasicAndroidCTLogger(BuildConfig.DEBUG) val trustManager = CTTrustManagerBuilder(delegateTrustManager) .setLogger(logger) .includeCommonName("*.example.com") .build() ``` -------------------------------- ### Integration with Java Security Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Illustrates setting up BasicAndroidCTLogger when installing the Certificate Transparency Java Security Provider. This allows CT checks to be enabled globally for the application with custom logging. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate() installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) +("*.example.com") } } } ``` -------------------------------- ### WebView Issues on Android 6.0 and Below Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Provides a conditional installation snippet to avoid potential WebView issues on Android 6.0 (API 23) and older versions. The CTProvider is only installed if the Android version is higher than M. ```kotlin if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { installCertificateTransparencyProvider { +"*.example.com" } } ``` -------------------------------- ### CTHostnameVerifierBuilder Usage Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTLogger.md Example of setting a CTLogger with CTHostnameVerifierBuilder to log verification results for specific hosts. ```kotlin val logger = BasicAndroidCTLogger(BuildConfig.DEBUG) val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setLogger(logger) .includeHost("*.example.com") .build() ``` -------------------------------- ### Logging Data Source (Wrapper) Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Wraps another DataSource to log get and set operations. Useful for debugging. ```kotlin class LoggingDataSource( private val delegate: DataSource, private val logger: (String) -> Unit ) : DataSource { override suspend fun get(): T? { logger("Getting value...") return delegate.get().also { logger("Got: $it") } } override suspend fun set(value: T) { logger("Setting value: $value") delegate.set(value) } } ``` -------------------------------- ### Custom CTLogger Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Provides an example of creating a custom CTLogger by implementing the CTLogger interface. This allows for more granular control over how and when verification results are logged, such as filtering for specific outcomes. ```kotlin class CustomCTLogger : CTLogger { override fun log(host: String, result: VerificationResult) { when (result) { is VerificationResult.Success -> { Log.d("CT-Success", host) } is VerificationResult.Failure -> { Log.w("CT-Failure", "$host: $result") } } } } ``` -------------------------------- ### Integrate Disk Cache with CTTrustManagerBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DiskCache.md Example of setting a disk cache for trust management. This enables the trust manager to leverage cached certificate information. ```kotlin val cache = AndroidDiskCache(context) val trustManager = CTTrustManagerBuilder(delegateTrustManager) .setDiskCache(cache) .includeCommonName("*.example.com") .build() ``` -------------------------------- ### Integrate Disk Cache with CTInterceptorBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DiskCache.md Example of configuring a network interceptor with a disk cache. This interceptor can cache and retrieve certificate transparency data. ```kotlin val cache = AndroidDiskCache(context) val interceptor = CTInterceptorBuilder() .setDiskCache(cache) .includeHost("api.example.com") .build() val httpClient = OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build() ``` -------------------------------- ### Implementing Custom Cleanup and Size Retrieval Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md Provides an example of a managed cache that wraps AndroidDiskCache, adding custom methods for clearing the cache and retrieving its size. This allows for more control over cache management. ```kotlin class ManagedAndroidDiskCache(context: Context) { private val cache = AndroidDiskCache(context) private val cacheDir = File(context.cacheDir, "certificate-transparency-android") suspend fun get() = cache.get() suspend fun set(value: RawLogListResult) = cache.set(value) // Clear cache manually fun clearCache() { cacheDir.deleteRecursively() } // Get cache size fun getCacheSize(): Long { return cacheDir.walkTopDown().sumOf { it.length() } } } // Usage val managedCache = ManagedAndroidDiskCache(context) val interceptor = CTInterceptorBuilder() .setDiskCache(managedCache) .build() ``` -------------------------------- ### installCertificateTransparencyProvider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Installs a Java Security Provider that enables CT verification for all TLS connections. This function modifies the Security class to add the provider with high priority and affects all subsequent TLS connections. ```APIDOC ## installCertificateTransparencyProvider ### Description Installs a Java Security Provider that enables CT verification for all TLS connections. This is the recommended approach for Android applications as it works across all network libraries including WebViews. ### Method `installCertificateTransparencyProvider` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **providerName** (`String`) - Optional - Unique name for the security provider. Cannot duplicate existing providers. Defaults to `"CertificateTransparency"`. - **init** (`CTTrustManagerBuilder.() -> Unit`) - Optional - Lambda to configure the trust manager using DSL syntax. ### Returns `Unit` ### Throws - `IllegalArgumentException` if a provider with the same name already exists. ### Side Effects - Modifies `Security` to add provider at position 1 (high priority). - Affects all subsequent TLS connections in the JVM/app. ``` -------------------------------- ### Monitored Android Disk Cache Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md An example of how to wrap the AndroidDiskCache to monitor cache hits and misses using a logger. This is useful for performance analysis. ```kotlin class MonitoredAndroidDiskCache( context: Context, private val logger: Logger ) : DiskCache { private val delegate = AndroidDiskCache(context) override suspend fun get(): RawLogListResult? { return delegate.get().also { result -> if (result != null) { logger.info("Cache hit") } else { logger.info("Cache miss") } } } override suspend fun set(value: RawLogListResult) { delegate.set(value) logger.info("Cache updated") } } ``` -------------------------------- ### Viewing CT Logs with adb logcat Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Shows command-line examples for viewing Certificate Transparency logs using Android's adb logcat tool. This includes filtering by tag and setting specific output formats for continuous monitoring. ```bash # View all CT logs adb logcat CertificateTransparency:I *:S # View CT logs with timestamps adb logcat -v time CertificateTransparency:I *:S # Continuous monitoring adb logcat -f /tmp/ct_logs.txt CertificateTransparency:I ``` -------------------------------- ### Inspect Detailed Error Data Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/errors.md Inspects associated data fields for specific failure types to get detailed debugging information. This example shows how to access SCT details for `TooFewSctsTrusted` failures. ```kotlin when (failure) { is VerificationResult.Failure.TooFewSctsTrusted -> { failure.scts.forEach { (logId, result) -> println("$logId: $result") } } } ``` -------------------------------- ### Build CTInterceptor with OkHttp Source: https://github.com/appmattus/certificatetransparency/blob/main/sampleapp/src/main/resources/okhttp-java.txt Demonstrates how to build a CTInterceptor and add it to an OkHttpClient. Configuration options like excluding and including hosts, and setting fail-on-error behavior are shown. ```java Interceptor networkInterceptor = new CTInterceptorBuilder() .excludeHost("{{.}} ") .includeHost("{{.}} ") .setFailOnError(false) .build(); OkHttpClient client = new OkHttpClient.Builder() .addNetworkInterceptor(networkInterceptor) .build(); ``` -------------------------------- ### Build Retrofit with OkHttpClient Source: https://github.com/appmattus/certificatetransparency/blob/main/docs/retrofit.md Instantiate a Retrofit client by providing a pre-configured OkHttpClient. Ensure the OkHttpClient is set up for Certificate Transparency as described in the OkHttp documentation. ```kotlin val retrofit = Retrofit.Builder() .baseUrl("https://appmattus.com") .client(okHttpClient) .build() ``` -------------------------------- ### Conditional CT Provider Installation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Conditionally installs the CT provider only when the application is not in debug mode. This is useful for enabling stricter security in production builds. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate()n // Only in production if (!BuildConfig.DEBUG) { installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(false) diskCache = AndroidDiskCache(this@SampleApplication) +"*.example.com" } } } } ``` -------------------------------- ### Basic Usage with CTInterceptorBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md Demonstrates setting up AndroidDiskCache with CTInterceptorBuilder to include caching for specific hostnames. ```kotlin val cache = AndroidDiskCache(context) val interceptor = CTInterceptorBuilder() .setDiskCache(cache) .includeHost("*.example.com") .build() val httpClient = OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build() ``` -------------------------------- ### Testing with BasicAndroidCTLogger Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Demonstrates how to instantiate and use BasicAndroidCTLogger within a test to verify its logging behavior. Logs are visible in the test output. ```kotlin @Test fun testWithLogging() { val logger = BasicAndroidCTLogger(true) // Enable for test val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setLogger(logger) .includeHost("test.com") .build() // Logs will appear in test output verifier.verify("test.com", sslSession) } ``` -------------------------------- ### build Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Constructs and returns the configured `HostnameVerifier` instance. ```APIDOC ## build ### Description Constructs and returns the configured `HostnameVerifier` instance. ### Method `build` ### Parameters None ### Returns `HostnameVerifier` - A hostname verifier that performs certificate transparency checks ``` -------------------------------- ### DSL-Style Configuration with CTHostnameVerifierBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Illustrates using Kotlin's DSL features with `CTHostnameVerifierBuilder` for a more concise configuration of logger, cache, host inclusion/exclusion, and failure handling. ```kotlin val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier).apply { logger = BasicAndroidCTLogger(true) diskCache = AndroidDiskCache(context) failOnError = { failure -> when (failure) { is VerificationResult.Failure.DisabledForHost -> false else -> true } } +"example.com" -"internal.example.com" +listOf("api.example.com", "cdn.example.com") }.build() ``` -------------------------------- ### build Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRInterceptorBuilder.md Constructs and returns the configured OkHttp3 Interceptor. ```APIDOC ## build ### Description Constructs and returns the configured OkHttp3 `Interceptor`. ### Method ```kotlin public fun build(): Interceptor ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Returns `okhttp3.Interceptor` - A network interceptor that performs revocation checks ``` -------------------------------- ### In-Flight Request Deduplication Example Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Demonstrates how reuseInflight() prevents duplicate concurrent requests to a DataSource. ```kotlin val dataSource = MyNetworkDataSource().reuseInflight() // Scenario: Two concurrent verification requests val task1 = async { dataSource.get() } // Network request starts val task2 = async { dataSource.get() } // Waits for task1's result val task3 = async { dataSource.get() } // Waits for task1's result // Only one network request happens; all three receive the same result awaitAll(task1, task2, task3) ``` -------------------------------- ### get Method Signature Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Signature for retrieving a value from the data source. May suspend if I/O is performed and is thread-safe. ```kotlin public suspend fun get(): Value? ``` -------------------------------- ### Timeout Data Source Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Wraps another DataSource to enforce a timeout on the get operation. Returns null if the timeout is reached. ```kotlin class TimeoutDataSource( private val delegate: DataSource, private val timeoutMillis: Long = 5000L ) : DataSource { override suspend fun get(): T? = try { withTimeoutOrNull(timeoutMillis) { delegate.get() } } catch (e: TimeoutCancellationException) { null } override suspend fun set(value: T) { delegate.set(value) } } ``` -------------------------------- ### removeCertificateTransparencyProvider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Removes a previously installed CT Security Provider by its name. This is useful for managing multiple CT provider configurations. ```APIDOC ## removeCertificateTransparencyProvider ### Description Removes a previously installed CT Security Provider. ### Method `removeCertificateTransparencyProvider` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **providerName** (`String`) - Optional - Name of the provider to remove. Defaults to `"CertificateTransparency"`. ### Returns `Unit` ``` -------------------------------- ### Complete CT Provider Configuration Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Demonstrates a comprehensive configuration including logging, disk cache, custom error handling, policy, and domain inclusion/exclusion. ```kotlin class SampleApplication : Application() { override fun onCreate() { super.onCreate()n installCertificateTransparencyProvider { // Setup logging logger = BasicAndroidCTLogger(BuildConfig.DEBUG) // Setup disk cache diskCache = AndroidDiskCache(this@SampleApplication) // Configure error handling failOnError = { failure -> when (failure) { VerificationResult.Failure.NoScts -> false // Allow else -> true // Fail on other errors } } // Configure CT policy policy = CustomCTPolicy() // Include domains +"example.com" +"*.example.com" // Exclude specific subdomains -"internal.example.com" } } } ``` -------------------------------- ### Permissive CTPolicy Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTPolicy.md An example implementation of CTPolicy where a single valid SCT is sufficient. Use this for a more lenient validation approach. ```kotlin class PermissiveCTPolicy : CTPolicy { override fun policyVerificationResult( leafCertificate: X509Certificate, sctResults: Map ): VerificationResult { // Only need one valid SCT val validScts = sctResults.count { it.value is SctVerificationResult.Valid } return if (validScts > 0) { VerificationResult.Success.Trusted(sctResults) } else { VerificationResult.Failure.TooFewSctsTrusted( scts = sctResults, minSctCount = 1 ) } } } ``` -------------------------------- ### Retry Logic Data Source Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Wraps a DataSource to automatically retry the get operation a specified number of times with a delay between attempts. ```kotlin class RetryDataSource( private val delegate: DataSource, private val maxRetries: Int = 3, private val delayMillis: Long = 100L ) : DataSource { override suspend fun get(): T? { repeat(maxRetries) { return try { delegate.get() } catch (e: Exception) { if (attempt < maxRetries - 1) { delay(delayMillis * (attempt + 1)) } null } } return null } override suspend fun set(value: T) { delegate.set(value) } } ``` -------------------------------- ### CTHostnameVerifierBuilder Constructor Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Initializes the CTHostnameVerifierBuilder with a delegate HostnameVerifier. ```APIDOC ## CTHostnameVerifierBuilder(delegate: HostnameVerifier) ### Description Initializes the builder with an underlying hostname verifier. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Parameters - **delegate** (`HostnameVerifier`) - Required - The underlying hostname verifier to delegate to before performing CT checks. ``` -------------------------------- ### DataSource Interface Definition Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Defines the core methods for interacting with a data source, including getting, setting, and reusing in-flight requests. ```APIDOC ## Interface DataSource ### Description A generic caching interface used throughout the certificate transparency library. It abstracts storage and retrieval operations with built-in support for deduplicating concurrent requests. ### Methods #### get ```kotlin public suspend fun get(): Value? ``` Retrieves the value from this data source. Returns the cached value, or `null` if not present or on error. May suspend if the implementation performs I/O. Safe to call from multiple coroutines concurrently. #### set ```kotlin public suspend fun set(value: Value) ``` Stores a value in this data source. May suspend if the implementation performs I/O. Safe to call from multiple coroutines concurrently. **Parameters:** - **value** (Value) - Required - The value to store #### reuseInflight ```kotlin public fun reuseInflight(): DataSource ``` Wraps this data source to deduplicate concurrent `get()` calls. Returns a new `DataSource` that reuses in-flight requests. If multiple coroutines call `get()` concurrently, the wrapper ensures only one actual call to the underlying data source, and all concurrent callers receive the same result. After the first call completes, new calls proceed normally. Prevents redundant network requests or database queries. **Usage Pattern:** ```kotlin val dataSource = logListDataSource.reuseInflight() // Multiple concurrent get() calls only hit the network once ``` ``` -------------------------------- ### includeHost Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Adds hosts matching the given patterns for CT verification. Patterns support wildcards (e.g., `*.example.com`). ```APIDOC ## includeHost ### Description Adds hosts matching the given patterns for CT verification. Patterns support wildcards (e.g., `*.example.com`). ### Method `includeHost` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **pattern** (`String` varargs) - Required - Lower-case hostname or wildcard patterns ### Returns Builder instance for method chaining ``` -------------------------------- ### Strict CTPolicy Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTPolicy.md An example implementation of CTPolicy where all SCTs must be valid. Use this when strict adherence to SCT validity is required. ```kotlin class StrictCTPolicy : CTPolicy { override fun policyVerificationResult( leafCertificate: X509Certificate, sctResults: Map ): VerificationResult { // All SCTs must be valid val invalidScts = sctResults.count { it.value !is SctVerificationResult.Valid } return if (invalidScts > 0) { VerificationResult.Failure.TooFewSctsTrusted( scts = sctResults, minSctCount = sctResults.size - invalidScts + 1 ) } else { VerificationResult.Success.Trusted(sctResults) } } } ``` -------------------------------- ### CTProvider Configuration Options Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Shows the various configuration options available for the CTProvider using CTTrustManagerBuilder. This includes setting up error handling, logging, caching, policies, data sources, and certificate chain cleaning. ```kotlin installCertificateTransparencyProvider { // Error handling failOnError = { ... } // Logging logger = ... // Caching diskCache = ... // Policy policy = ... // Data sources logListService = ... logListDataSource = ... // Certificate chain certificateChainCleanerFactory = ... // Inclusion/exclusion +"*.example.com" -"internal.example.com" +"critical.example.com" } ``` -------------------------------- ### Get Human-Readable Error Description Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/errors.md Retrieves a human-readable description of a verification failure using the `toString()` method. This is useful for quick debugging and logging. ```kotlin result.toString() // e.g., "Failure: Too few trusted SCTs, required 2, found 1 in..." ``` -------------------------------- ### Simple In-Memory Cache Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md A basic implementation of the DataSource interface using in-memory storage. ```kotlin class MemoryDataSource : DataSource { private var cachedValue: T? = null override suspend fun get(): T? = cachedValue override suspend fun set(value: T) { cachedValue = value } } ``` -------------------------------- ### Remove Certificate Transparency Provider Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Removes a previously installed CT Security Provider by its name. This function affects subsequent TLS connections. ```kotlin removeCertificateTransparencyProvider( providerName: String = DEFAULT_PROVIDER_NAME ) ``` -------------------------------- ### build Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTTrustManagerBuilder.md Constructs and returns the configured `X509TrustManager` instance. Automatically selects between basic and extended trust manager implementations based on runtime Java/Android version. ```APIDOC ## build ### Description Constructs and returns the configured `X509TrustManager` instance. Automatically selects between basic and extended trust manager implementations based on runtime Java/Android version. ### Method ```kotlin public fun build(): X509TrustManager ``` ### Returns `X509TrustManager` - A trust manager that performs certificate transparency checks **Note:** On Java 1.7+ and Android API 24+, returns an `X509ExtendedTrustManager`. Otherwise returns a basic `X509TrustManager`. ``` -------------------------------- ### Configure Composite Build for Certificate Transparency Source: https://github.com/appmattus/certificatetransparency/blob/main/CONTRIBUTING.md Use this Kotlin script in your project's `settings.gradle.kts` to substitute the certificatetransparency library with your local development version when using composite builds. ```kotlin includeBuild("path-to-root-of-certificatetransparency-project") { dependencySubstitution { substitute(module("com.appmattus.certificatetransparency:certificatetransparency")).with(project(":certificatetransparency")) substitute(module("com.appmattus.certificatetransparency:certificatetransparency-android")).with(project(":certificatetransparency-android")) } } ``` -------------------------------- ### Configure OkHttp with Certificate Transparency Interceptor Source: https://github.com/appmattus/certificatetransparency/blob/main/sampleapp/src/main/resources/okhttp-kotlin.txt Instantiates a Certificate Transparency interceptor and adds it to an OkHttpClient builder. Allows configuration of included/excluded hosts and error handling. ```kotlin val interceptor = certificateTransparencyInterceptor { {{#excludeHosts}} -"{{.}}" {{/excludeHosts}} {{#includeHosts}} +"{{.}}" {{/includeHosts}} {{^failOnError}} failOnError = false {{/failOnError}} } val client = OkHttpClient.Builder().apply { addNetworkInterceptor(interceptor) }.build() ``` -------------------------------- ### reuseInflight Method Signature Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Signature for wrapping a data source to deduplicate concurrent get() calls. Returns a new DataSource that reuses in-flight requests. ```kotlin public fun reuseInflight(): DataSource ``` -------------------------------- ### build Method Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRInterceptorBuilder.md Constructs and returns the configured OkHttp3 Interceptor that performs revocation checks. ```kotlin public fun build(): Interceptor ``` -------------------------------- ### Log List Data Source Initialization Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Initializes a DataSource for LogListResult, potentially loading from the network and enabling request deduplication. ```kotlin val logListDataSource: DataSource = LogListZipNetworkDataSource() // Loads from network .reuseInflight() // Deduplicate concurrent requests // Automatically cached with DiskCache if provided ``` -------------------------------- ### get Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/AndroidDiskCache.md Retrieves the cached log list and its signature from disk. Returns a RawLogListResult.Success if both files exist, otherwise returns null. This operation is suspendable and thread-safe. ```APIDOC ## get() ### Description Retrieves the cached log list and its signature from disk. Returns a RawLogListResult.Success if both files exist, otherwise returns null. This operation is suspendable and thread-safe. ### Method `override suspend fun get(): RawLogListResult?` ### Returns - **RawLogListResult?** - `RawLogListResult.Success` if both files exist, `null` if missing or on error. ### Thread Safety Yes, via internal mutex. ### Exception Handling Catches and suppresses `IOException`, returns `null` instead. ``` -------------------------------- ### Tiered Data Source (Multi-Level Cache) Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DataSource.md Implements DataSource by using a primary cache and falling back to a secondary cache, populating the primary on fallback. ```kotlin class TieredDataSource( private val primary: DataSource, private val secondary: DataSource ) : DataSource { override suspend fun get(): T? { return primary.get() ?: run { secondary.get()?.also { value -> primary.set(value) // Populate primary } } } override suspend fun set(value: T) { primary.set(value) secondary.set(value) } } ``` -------------------------------- ### Handle Certificate Revoked Error Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/errors.md Detect when a certificate is explicitly revoked and reject the connection. This example retrieves the serial number of the revoked certificate for logging. ```kotlin is RevocationResult.Failure.CertificateRevoked -> { val serial = failure.certificate.serialNumber Log.e("Revocation", "Certificate $serial is revoked") return false // Reject connection } ``` -------------------------------- ### Custom Policy Configuration Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Shows how to set a custom `CTPolicy` and configure the builder to log failures without blocking verification, along with a custom logger. ```kotlin val verifier = CTHostnameVerifierBuilder(OkHostnameVerifier) .setPolicy(CustomCTPolicy()) .setFailOnError(false) // Log failures but don't block .setLogger(MyLogger()) .build() ``` -------------------------------- ### Build Hostname Verifier Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTHostnameVerifierBuilder.md Constructs and returns the fully configured `HostnameVerifier` instance after all settings have been applied. ```kotlin public fun build(): HostnameVerifier ``` -------------------------------- ### Setting Logger with CRInterceptorBuilder Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRLogger.md Demonstrates how to set a custom CRLogger when building a CRInterceptor. ```kotlin val logger = BasicAndroidCRLogger(BuildConfig.DEBUG) val interceptor = CRInterceptorBuilder() .addCrl(issuerDn, serialNumbers) .setLogger(logger) .build() val httpClient = OkHttpClient.Builder() .addNetworkInterceptor(interceptor) .build() ``` -------------------------------- ### Operator Diversity CTPolicy Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTPolicy.md An example implementation of CTPolicy that requires SCTs from a specific set of operators. This ensures diversity among SCT providers. ```kotlin class OperatorDiversityPolicy : CTPolicy { private val requiredOperators = setOf( "Google", "DigiCert", "Symantec" ) override fun policyVerificationResult( leafCertificate: X509Certificate, sctResults: Map ): VerificationResult { val validByOperator = sctResults .filterValues { it is SctVerificationResult.Valid } .mapValues { (it.value as SctVerificationResult.Valid).operator } .values .toSet() val foundOperators = validByOperator.intersect(requiredOperators).size return if (foundOperators == requiredOperators.size) { VerificationResult.Success.Trusted(sctResults) } else { VerificationResult.Failure.TooFewDistinctOperators( scts = sctResults, minSctCount = requiredOperators.size - foundOperators + 1 ) } } } ``` -------------------------------- ### DiskCache get Method Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/DiskCache.md Retrieves cached log list and signature data from disk. Returns RawLogListResult.Success if data is cached, null otherwise. May throw IOException. ```kotlin public suspend fun get(): RawLogListResult? ``` -------------------------------- ### Troubleshooting: Debugging Failing Connections Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTProvider.md Shows how to enable detailed logging and configure `failOnError` to log verification failures before deciding whether to fail the connection. This is crucial for diagnosing issues with CT verification. ```kotlin // Add logging to debug installCertificateTransparencyProvider { logger = BasicAndroidCTLogger(BuildConfig.DEBUG) failOnError = { failure -> Log.e("CT", "Verification failed: $failure") true // Fail after logging } } ``` -------------------------------- ### Test Certificate Revocation Check Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRInterceptorBuilder.md Provides a unit test example for verifying the interceptor's functionality. It sets up a mock chain with a revoked certificate and asserts that an SSLHandshakeException is thrown. ```kotlin fun testRevocationCheck() { val interceptor = CRInterceptorBuilder() .addCrl( issuerDistinguishedName = testIssuerDN, serialNumbers = listOf(revokedSerial) ) .build() // Test with mock interceptor chain val mockChain = MockInterceptorChain() mockChain.response.sslPeerCertificates = listOf(certificateWithRevokedSerial) // Should throw SSLHandshakeException try { interceptor.intercept(mockChain) fail("Should have thrown") } catch (e: SSLHandshakeException) { assertTrue(e.cause is RevocationException) } } ``` -------------------------------- ### Build X509TrustManager Instance Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTTrustManagerBuilder.md Constructs and returns the configured `X509TrustManager` instance. Automatically selects between basic and extended trust manager implementations based on runtime Java/Android version. ```kotlin public fun build(): X509TrustManager ``` -------------------------------- ### Filtering CTLogger Wrapper Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/BasicAndroidCTLogger.md Demonstrates wrapping BasicAndroidCTLogger within a custom logger to filter log messages. This example shows how to log only failure results, reducing log noise. ```kotlin class FilteringCTLogger(private val delegate: BasicAndroidCTLogger) : CTLogger { override fun log(host: String, result: VerificationResult) { // Only log failures if (result is VerificationResult.Failure) { delegate.log(host, result) } } } ``` -------------------------------- ### Testing CRLogger Implementation Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CRLogger.md Demonstrates how to test a CRLogger implementation by using a mock logger and asserting the logged values. This is crucial for verifying logger behavior. ```kotlin @Test fun testLogging() { var lastLoggedHost = "" var lastLoggedResult: RevocationResult? = null val testLogger = object : CRLogger { override fun log(host: String, result: RevocationResult) { lastLoggedHost = host lastLoggedResult = result } } val interceptor = CRInterceptorBuilder() .addCrl(issuerDn, revokedSerials) .setLogger(testLogger) .build() // Perform verification // ... // Assert logging occurred assertEquals("example.com", lastLoggedHost) assertTrue(lastLoggedResult is RevocationResult.Failure.CertificateRevoked) } ``` -------------------------------- ### Conditional Error Handling in CTTrustManager Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTTrustManagerBuilder.md Configures CTTrustManagerBuilder with custom error handling logic. This example demonstrates how to selectively fail or log based on specific `VerificationResult.Failure` types, such as missing SCTs. ```kotlin val trustManager = CTTrustManagerBuilder(delegateTrustManager) .setFailOnError { failure -> when (failure) { VerificationResult.Failure.NoScts -> { // Log but don't fail on missing SCTs logger?.log("Missing SCTs", failure) false } VerificationResult.Failure.LogServersFailed -> true VerificationResult.Failure.NoCertificates -> true else -> true } } .build() ``` -------------------------------- ### CTInterceptorBuilder Constructor Source: https://github.com/appmattus/certificatetransparency/blob/main/_autodocs/api-reference/CTInterceptorBuilder.md Initializes a new instance of the CTInterceptorBuilder. No parameters are required for the constructor; all configuration is performed using builder methods. ```APIDOC ## CTInterceptorBuilder ### Description Initializes a new instance of the CTInterceptorBuilder. No parameters are required for the constructor; all configuration is performed using builder methods. ### Constructor ```kotlin public class CTInterceptorBuilder ``` ```