Safer code, add some try catch blocks.
Filter out system alias before reading the keyStore entry. use `size` instead of `count()` Kotlin style.
This commit is contained in:
parent
f1790c9a7a
commit
f29f46b9e9
1 changed files with 38 additions and 24 deletions
|
|
@ -20,6 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
|
import java.security.KeyStoreException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
|
|
@ -37,21 +38,28 @@ class DefaultUserCertificatesProvider @Inject constructor() : UserCertificatesPr
|
||||||
* in encoded form.
|
* in encoded form.
|
||||||
*/
|
*/
|
||||||
override fun provides(): List<ByteArray> {
|
override fun provides(): List<ByteArray> {
|
||||||
val certs = mutableListOf<ByteArray>()
|
|
||||||
|
|
||||||
// At least for API 34 the `AndroidCAStore` `Keystore` type contained user certificates as well.
|
// At least for API 34 the `AndroidCAStore` `Keystore` type contained user certificates as well.
|
||||||
// I have not found this to be documented anywhere.
|
// I have not found this to be documented anywhere.
|
||||||
val keyStore: KeyStore = KeyStore.getInstance("AndroidCAStore").apply {
|
val keyStore: KeyStore = try {
|
||||||
load(null)
|
KeyStore.getInstance("AndroidCAStore")
|
||||||
|
} catch (e: KeyStoreException) {
|
||||||
|
Timber.w(e, "Failed to get AndroidCAStore keystore")
|
||||||
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
val aliases = keyStore.aliases()
|
keyStore.load(null)
|
||||||
|
} catch (e: Exception) {
|
||||||
while (aliases.hasMoreElements()) {
|
Timber.w(e, "Failed to load AndroidCAStore keystore")
|
||||||
val alias = aliases.nextElement()
|
return emptyList()
|
||||||
val entry = keyStore.getEntry(alias, null)
|
}
|
||||||
|
val aliases = try {
|
||||||
if (entry is KeyStore.TrustedCertificateEntry) {
|
keyStore.aliases()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.w(e, "Failed to get aliases from AndroidCAStore keystore")
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
return aliases.toList()
|
||||||
|
.filter { alias ->
|
||||||
// The certificate alias always contains the prefix `system` or
|
// The certificate alias always contains the prefix `system` or
|
||||||
// `user` and the MD5 subject hash separated by a colon.
|
// `user` and the MD5 subject hash separated by a colon.
|
||||||
//
|
//
|
||||||
|
|
@ -59,19 +67,25 @@ class DefaultUserCertificatesProvider @Inject constructor() : UserCertificatesPr
|
||||||
// openssl x509 -subject_hash_old -noout -in mycert.cer
|
// openssl x509 -subject_hash_old -noout -in mycert.cer
|
||||||
//
|
//
|
||||||
// Again, I have not found this to be documented somewhere.
|
// Again, I have not found this to be documented somewhere.
|
||||||
if (alias.startsWith("user")) {
|
alias.startsWith("user")
|
||||||
certs.add(entry.trustedCertificate.encoded)
|
}
|
||||||
|
.mapNotNull { alias ->
|
||||||
|
try {
|
||||||
|
keyStore.getEntry(alias, null)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.w(e, "Failed to get entry for alias $alias")
|
||||||
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.filterIsInstance<KeyStore.TrustedCertificateEntry>()
|
||||||
|
.map { trustedCertificateEntry ->
|
||||||
// Let's at least log the number of user-installed certificates we found,
|
trustedCertificateEntry.trustedCertificate.encoded
|
||||||
// since the alias isn't particularly useful nor does the issuer seem to
|
}
|
||||||
// be easily available.
|
.also {
|
||||||
val certCount = certs.count()
|
// Let's at least log the number of user-installed certificates we found,
|
||||||
|
// since the alias isn't particularly useful nor does the issuer seem to
|
||||||
Timber.i("Found $certCount additional user-provided certificates.")
|
// be easily available.
|
||||||
|
Timber.i("Found ${it.size} additional user-provided certificates.")
|
||||||
return certs
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue