diff --git a/appverifier/src/main/java/com/android/mdl/appreader/fragment/ViewTruststoreFragment.kt b/appverifier/src/main/java/com/android/mdl/appreader/fragment/ViewTruststoreFragment.kt new file mode 100644 index 000000000..0bd53370f --- /dev/null +++ b/appverifier/src/main/java/com/android/mdl/appreader/fragment/ViewTruststoreFragment.kt @@ -0,0 +1,73 @@ +package com.android.mdl.appreader.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedCard +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.unit.dp +import androidx.fragment.app.Fragment +import com.android.mdl.appreader.theme.ReaderAppTheme +import com.android.mdl.appreader.util.KeysAndCertificates +import java.security.cert.X509Certificate +import java.time.Instant + +class ViewTruststoreFragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + val trustedCertificates = KeysAndCertificates.getTrustedIssuerCertificates(requireContext()) + return ComposeView(requireContext()).apply { + setContent { + ReaderAppTheme { + CertificatesList(trustedCertificates) + } + } + } + } +} + +@Composable +private fun CertificatesList(certificates: List) { + val now = Instant.now() + val padding = Modifier.padding(horizontal = 2.dp) + val colorRegular = MaterialTheme.colorScheme.onBackground + val colorError = MaterialTheme.colorScheme.error + + Column(modifier = Modifier.verticalScroll(state = rememberScrollState())) { + certificates.forEach { certificate -> + OutlinedCard(modifier = Modifier.fillMaxWidth()) { + Text( + text = certificate.subjectDN.toString(), + style = MaterialTheme.typography.bodyMedium, + color = colorRegular, + modifier = padding + ) + Text( + text = "Not before: " + certificate.notBefore.toString(), + style = MaterialTheme.typography.bodyMedium, + color = if (now > certificate.notBefore.toInstant()) colorRegular else colorError, + modifier = padding + ) + Text( + text = "Not after: " + certificate.notAfter.toString(), + style = MaterialTheme.typography.bodyMedium, + color = if (now < certificate.notAfter.toInstant()) colorRegular else colorError, + modifier = padding + ) + } + } + } +} diff --git a/appverifier/src/main/res/drawable/ic_truststore.xml b/appverifier/src/main/res/drawable/ic_truststore.xml new file mode 100644 index 000000000..648ce8025 --- /dev/null +++ b/appverifier/src/main/res/drawable/ic_truststore.xml @@ -0,0 +1,7 @@ + + + diff --git a/appverifier/src/main/res/menu/side_navigation_menu.xml b/appverifier/src/main/res/menu/side_navigation_menu.xml index 415628947..262058526 100644 --- a/appverifier/src/main/res/menu/side_navigation_menu.xml +++ b/appverifier/src/main/res/menu/side_navigation_menu.xml @@ -14,7 +14,12 @@ android:enabled="true" android:icon="@drawable/ic_present_document" android:title="@string/menu_reverse_engagement" /> - + + + + \ No newline at end of file diff --git a/appverifier/src/main/res/values/strings.xml b/appverifier/src/main/res/values/strings.xml index 9f8abc2c1..1cff45ea7 100644 --- a/appverifier/src/main/res/values/strings.xml +++ b/appverifier/src/main/res/values/strings.xml @@ -107,5 +107,6 @@ Home Reverse Engagement Settings + View Truststore \ No newline at end of file