@@ -5,6 +5,7 @@ import android.security.KeyChain
5
5
import android.security.KeyChainException
6
6
import com.x8bit.bitwarden.data.platform.datasource.disk.model.MutualTlsCertificate
7
7
import com.x8bit.bitwarden.data.platform.datasource.disk.model.MutualTlsKeyHost
8
+ import com.x8bit.bitwarden.data.platform.error.MissingPropertyException
8
9
import com.x8bit.bitwarden.data.platform.manager.model.ImportPrivateKeyResult
9
10
import timber.log.Timber
10
11
import java.io.IOException
@@ -24,7 +25,7 @@ class KeyManagerImpl(
24
25
private val context : Context ,
25
26
) : KeyManager {
26
27
27
- @Suppress(" CyclomaticComplexMethod" )
28
+ @Suppress(" LongMethod " , " CyclomaticComplexMethod" )
28
29
override fun importMutualTlsCertificate (
29
30
key : ByteArray ,
30
31
alias : String ,
@@ -35,51 +36,59 @@ class KeyManagerImpl(
35
36
.inputStream()
36
37
.use { stream ->
37
38
try {
38
- KeyStore .getInstance(KEYSTORE_TYPE_PKCS12 )
39
+ KeyStore
40
+ .getInstance(KEYSTORE_TYPE_PKCS12 )
39
41
.also { it.load(stream, password.toCharArray()) }
40
42
} catch (e: KeyStoreException ) {
41
43
Timber .Forest .e(e, " Failed to load PKCS12 bytes" )
42
- return ImportPrivateKeyResult .Error .UnsupportedKey
44
+ return ImportPrivateKeyResult .Error .UnsupportedKey (throwable = e)
43
45
} catch (e: IOException ) {
44
46
Timber .Forest .e(e, " Format or password error while loading PKCS12 bytes" )
45
47
return when (e.cause) {
46
48
is UnrecoverableKeyException -> {
47
- ImportPrivateKeyResult .Error .UnrecoverableKey
49
+ ImportPrivateKeyResult .Error .UnrecoverableKey (throwable = e)
48
50
}
49
51
50
52
else -> {
51
- ImportPrivateKeyResult .Error .KeyStoreOperationFailed
53
+ ImportPrivateKeyResult .Error .KeyStoreOperationFailed (throwable = e)
52
54
}
53
55
}
54
56
} catch (e: CertificateException ) {
55
57
Timber .Forest .e(e, " Unable to load certificate chain" )
56
- return ImportPrivateKeyResult .Error .InvalidCertificateChain
58
+ return ImportPrivateKeyResult .Error .InvalidCertificateChain (throwable = e)
57
59
} catch (e: NoSuchAlgorithmException ) {
58
60
Timber .Forest .e(e, " Cryptographic algorithm not supported" )
59
- return ImportPrivateKeyResult .Error .UnsupportedKey
61
+ return ImportPrivateKeyResult .Error .UnsupportedKey (throwable = e)
60
62
}
61
63
}
62
64
63
65
// Step 2: Get a list of aliases and choose the first one.
64
66
val internalAlias = pkcs12KeyStore.aliases()
65
67
?.takeIf { it.hasMoreElements() }
66
68
?.nextElement()
67
- ? : return ImportPrivateKeyResult .Error .UnsupportedKey
69
+ ? : return ImportPrivateKeyResult .Error .UnsupportedKey (
70
+ throwable = MissingPropertyException (" Internal Alias" ),
71
+ )
68
72
69
73
// Step 3: Extract PrivateKey and X.509 certificate from the KeyStore and verify
70
74
// certificate alias.
71
75
val privateKey = try {
72
- pkcs12KeyStore.getKey(internalAlias, password.toCharArray())
73
- ? : return ImportPrivateKeyResult .Error .UnrecoverableKey
76
+ pkcs12KeyStore
77
+ .getKey(internalAlias, password.toCharArray())
78
+ ? : return ImportPrivateKeyResult .Error .UnrecoverableKey (
79
+ throwable = MissingPropertyException (" Private Key" ),
80
+ )
74
81
} catch (e: UnrecoverableKeyException ) {
75
82
Timber .Forest .e(e, " Failed to get private key" )
76
- return ImportPrivateKeyResult .Error .UnrecoverableKey
83
+ return ImportPrivateKeyResult .Error .UnrecoverableKey (throwable = e)
77
84
}
78
85
79
86
val certChain: Array <Certificate > = pkcs12KeyStore
80
87
.getCertificateChain(internalAlias)
81
88
?.takeUnless { it.isEmpty() }
82
- ? : return ImportPrivateKeyResult .Error .InvalidCertificateChain
89
+ ? : return ImportPrivateKeyResult .Error .InvalidCertificateChain (
90
+ throwable = MissingPropertyException (" Certificate Chain" ),
91
+ )
83
92
84
93
// Step 4: Store the private key and X.509 certificate in the AndroidKeyStore if the alias
85
94
// does not exists.
@@ -92,7 +101,7 @@ class KeyManagerImpl(
92
101
setKeyEntry(alias, privateKey, null , certChain)
93
102
} catch (e: KeyStoreException ) {
94
103
Timber .Forest .e(e, " Failed to import key into Android KeyStore" )
95
- return ImportPrivateKeyResult .Error .KeyStoreOperationFailed
104
+ return ImportPrivateKeyResult .Error .KeyStoreOperationFailed (throwable = e)
96
105
}
97
106
}
98
107
return ImportPrivateKeyResult .Success (alias)
0 commit comments