Don't crash on certificates without subject alternative names
This commit is contained in:
parent
28892810f4
commit
213c8c7d11
3 changed files with 49 additions and 6 deletions
|
@ -23,7 +23,7 @@ class FormatServerCertificateError(
|
||||||
val notValidBeforeInstant = Instant.fromEpochMilliseconds(certificate.notBefore.time)
|
val notValidBeforeInstant = Instant.fromEpochMilliseconds(certificate.notBefore.time)
|
||||||
val notValidAfterInstant = Instant.fromEpochMilliseconds(certificate.notAfter.time)
|
val notValidAfterInstant = Instant.fromEpochMilliseconds(certificate.notAfter.time)
|
||||||
|
|
||||||
val subjectAlternativeNames = certificate.subjectAlternativeNames.map { it[1].toString() }
|
val subjectAlternativeNames = certificate.subjectAlternativeNames.orEmpty().map { it[1].toString() }
|
||||||
|
|
||||||
val notValidBefore = dateFormat.format(Date(notValidBeforeInstant.toEpochMilliseconds()))
|
val notValidBefore = dateFormat.format(Date(notValidBeforeInstant.toEpochMilliseconds()))
|
||||||
val notValidAfter = dateFormat.format(Date(notValidAfterInstant.toEpochMilliseconds()))
|
val notValidAfter = dateFormat.format(Date(notValidAfterInstant.toEpochMilliseconds()))
|
||||||
|
|
|
@ -39,12 +39,14 @@ internal fun ServerCertificateView(
|
||||||
TextHeadline6(stringResource(R.string.account_server_certificate_section_title))
|
TextHeadline6(stringResource(R.string.account_server_certificate_section_title))
|
||||||
Spacer(modifier = Modifier.height(MainTheme.spacings.double))
|
Spacer(modifier = Modifier.height(MainTheme.spacings.double))
|
||||||
|
|
||||||
TextSubtitle2(stringResource(R.string.account_server_certificate_subject_alternative_names))
|
if (serverCertificateProperties.subjectAlternativeNames.isNotEmpty()) {
|
||||||
for (subjectAlternativeName in serverCertificateProperties.subjectAlternativeNames) {
|
TextSubtitle2(stringResource(R.string.account_server_certificate_subject_alternative_names))
|
||||||
BulletedListItem(serverNameFormatter.format(subjectAlternativeName))
|
for (subjectAlternativeName in serverCertificateProperties.subjectAlternativeNames) {
|
||||||
}
|
BulletedListItem(serverNameFormatter.format(subjectAlternativeName))
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(MainTheme.spacings.double))
|
Spacer(modifier = Modifier.height(MainTheme.spacings.double))
|
||||||
|
}
|
||||||
|
|
||||||
TextSubtitle2(stringResource(R.string.account_server_certificate_not_valid_before))
|
TextSubtitle2(stringResource(R.string.account_server_certificate_not_valid_before))
|
||||||
TextBody1(text = serverCertificateProperties.notValidBefore)
|
TextBody1(text = serverCertificateProperties.notValidBefore)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package app.k9mail.feature.account.server.certificate.domain.usecase
|
||||||
import app.k9mail.feature.account.server.certificate.domain.entity.ServerCertificateError
|
import app.k9mail.feature.account.server.certificate.domain.entity.ServerCertificateError
|
||||||
import app.k9mail.feature.account.server.certificate.domain.entity.ServerCertificateProperties
|
import app.k9mail.feature.account.server.certificate.domain.entity.ServerCertificateProperties
|
||||||
import assertk.assertThat
|
import assertk.assertThat
|
||||||
|
import assertk.assertions.isEmpty
|
||||||
import assertk.assertions.isEqualTo
|
import assertk.assertions.isEqualTo
|
||||||
import java.security.cert.CertificateFactory
|
import java.security.cert.CertificateFactory
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
|
@ -51,6 +52,22 @@ class FormatServerCertificateErrorTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `format certificate without subject alternative names`() {
|
||||||
|
val formatCertificateError = FormatServerCertificateError(
|
||||||
|
dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.ROOT),
|
||||||
|
)
|
||||||
|
val serverCertificateError = ServerCertificateError(
|
||||||
|
hostname = "10.0.0.1",
|
||||||
|
port = 993,
|
||||||
|
certificateChain = listOf(readCertificate(CERTIFICATE_WITHOUT_SAN)),
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = formatCertificateError(serverCertificateError)
|
||||||
|
|
||||||
|
assertThat(result.serverCertificateProperties.subjectAlternativeNames).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
private fun readCertificate(asciiArmoredCertificate: String): X509Certificate {
|
private fun readCertificate(asciiArmoredCertificate: String): X509Certificate {
|
||||||
val inputStream = asciiArmoredCertificate.byteInputStream()
|
val inputStream = asciiArmoredCertificate.byteInputStream()
|
||||||
|
|
||||||
|
@ -92,5 +109,29 @@ class FormatServerCertificateErrorTest {
|
||||||
RwxPuzZEaFZcVlmtqoq8
|
RwxPuzZEaFZcVlmtqoq8
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
|
val CERTIFICATE_WITHOUT_SAN = """
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDfDCCAmSgAwIBAgIJAJB2iRjpM5OgMA0GCSqGSIb3DQEBCwUAME4xMTAvBgNV
|
||||||
|
BAsMKE5vIFNOSSBwcm92aWRlZDsgcGxlYXNlIGZpeCB5b3VyIGNsaWVudC4xGTAX
|
||||||
|
BgNVBAMTEGludmFsaWQyLmludmFsaWQwHhcNMTUwMTAxMDAwMDAwWhcNMzAwMTAx
|
||||||
|
MDAwMDAwWjBOMTEwLwYDVQQLDChObyBTTkkgcHJvdmlkZWQ7IHBsZWFzZSBmaXgg
|
||||||
|
eW91ciBjbGllbnQuMRkwFwYDVQQDExBpbnZhbGlkMi5pbnZhbGlkMIIBIjANBgkq
|
||||||
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzWJP5cMThJgMBeTvRKKl7N6ZcZAbKDVA
|
||||||
|
tNBNnRhIgSitXxCzKtt9rp2RHkLn76oZjdNO25EPp+QgMiWU/rkkB00Y18Oahw5f
|
||||||
|
i8s+K9dRv6i+gSOiv2jlIeW/S0hOswUUDH0JXFkEPKILzpl5ML7wdp5kt93vHxa7
|
||||||
|
HswOtAxEz2WtxMdezm/3CgO3sls20wl3W03iI+kCt7HyvhGy2aRPLhJfeABpQr0U
|
||||||
|
ku3q6mtomy2cgFawekN/X/aH8KknX799MPcuWutM2q88mtUEBsuZmy2nsjK9J7/y
|
||||||
|
hhCRDzOV/yY8c5+l/u/rWuwwkZ2lgzGp4xBBfhXdr6+m9kmwWCUm9QIDAQABo10w
|
||||||
|
WzAOBgNVHQ8BAf8EBAMCAqQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
|
||||||
|
MA8GA1UdEwEB/wQFMAMBAf8wGQYDVR0OBBIEELsPOJZvPr5PK0bQQWrUrLUwDQYJ
|
||||||
|
KoZIhvcNAQELBQADggEBALnZ4lRc9WHtafO4Y+0DWp4qgSdaGygzS/wtcRP+S2V+
|
||||||
|
HFOCeYDmeZ9qs0WpNlrtyeBKzBH8hOt9y8aUbZBw2M1F2Mi23Q+dhAEUfQCOKbIT
|
||||||
|
tunBuVfDTTbAHUuNl/eyr78v8Egi133z7zVgydVG1KA0AOSCB+B65glbpx+xMCpg
|
||||||
|
ZLux9THydwg3tPo/LfYbRCof+Mb8I3ZCY9O6FfZGjuxJn+0ux3SDora3NX/FmJ+i
|
||||||
|
kTCTsMtIFWhH3hoyYAamOOuITpPZHD7yP0lfbuncGDEqAQu2YWbYxRixfq2VSxgv
|
||||||
|
gWbFcmkgBLYpE8iDWT3Kdluo1+6PHaDaLg2SacOY6Go=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue