@@ -2,7 +2,6 @@ package at.favre.lib.armadillo.datastore
22
33import android.content.Context
44import android.os.Build
5- import android.util.Log
65import androidx.datastore.Serializer
76import at.favre.lib.armadillo.*
87import at.favre.lib.armadillo.Armadillo.CONTENT_KEY_OUT_BYTE_LENGTH
@@ -12,15 +11,10 @@ import java.io.OutputStream
1211import java.security.Provider
1312import java.security.SecureRandom
1413
15- interface ProtobufProtocol <T > {
16- fun toBytes (data : T ): ByteArray
17- fun fromBytes (bytes : ByteArray ): T
18- fun fromNothing (): T
19- }
20-
2114class ArmadilloSerializer <T >(
2215 context : Context ,
2316 private val protocol : ProtobufProtocol <T >,
17+ password : CharArray? = null ,
2418 fingerprintData : List <String > = emptyList(),
2519 secureRandom : SecureRandom = SecureRandom (),
2620 additionalDecryptionConfigs : List <EncryptionProtocolConfig > = listOf(),
@@ -29,36 +23,38 @@ class ArmadilloSerializer<T>(
2923 preferencesSalt : ByteArray = BuildConfig .PREF_SALT
3024) : Serializer<T> {
3125
32- private val password : ByteArrayRuntimeObfuscator ?
26+ private val serializerPassword : ByteArrayRuntimeObfuscator ?
3327 private val encryptionProtocol: EncryptionProtocol
3428 private val fingerprint: EncryptionFingerprint = EncryptionFingerprintFactory .create(
3529 context,
3630 buildString { fingerprintData.forEach(::append) }
3731 )
32+ private val defaultConfig = EncryptionProtocolConfig .newDefaultConfig()
33+ private val kitKatConfig by lazy {
34+ @Suppress(" DEPRECATION" )
35+ EncryptionProtocolConfig .newBuilder(defaultConfig.build())
36+ .authenticatedEncryption(AesCbcEncryption (secureRandom, provider))
37+ .protocolVersion(Armadillo .KITKAT_PROTOCOL_VERSION )
38+ .build()
39+ }
3840
3941 init {
40- val defaultConfig = EncryptionProtocolConfig .newDefaultConfig()
4142
4243 val stringMessageDigest = HkdfMessageDigest (
4344 BuildConfig .PREF_SALT ,
4445 CONTENT_KEY_OUT_BYTE_LENGTH
4546 )
46- val kitKatConfig = takeIf { enabledKitkatSupport }?.run {
47- @Suppress(" DEPRECATION" )
48- EncryptionProtocolConfig .newBuilder(defaultConfig.build())
49- .authenticatedEncryption(AesCbcEncryption (secureRandom, provider))
50- .protocolVersion(Armadillo .KITKAT_PROTOCOL_VERSION )
51- .build()
52- }
47+
5348 val config =
54- if (kitKatConfig != null && Build .VERSION .SDK_INT < Build .VERSION_CODES .LOLLIPOP ) {
49+ if (Build .VERSION .SDK_INT < Build .VERSION_CODES .LOLLIPOP ) {
5550 kitKatConfig
5651 } else {
5752 EncryptionProtocolConfig
5853 .newBuilder(defaultConfig.build())
5954 .authenticatedEncryption(AesGcmEncryption (secureRandom, provider))
6055 .build()
61- }.also { checkKitKatSupport(it.authenticatedEncryption) }
56+ }
57+ checkKitKatSupport(config.authenticatedEncryption)
6258
6359 val factory = DefaultEncryptionProtocol .Factory (
6460 config,
@@ -74,7 +70,7 @@ class ArmadilloSerializer<T>(
7470 )
7571
7672 encryptionProtocol = factory.create(preferencesSalt)
77- password = null // TODO Add password config factory.obfuscatePassword( )
73+ serializerPassword = password?. let (factory::obfuscatePassword )
7874 }
7975
8076
@@ -86,56 +82,45 @@ class ArmadilloSerializer<T>(
8682 }
8783
8884 companion object {
89- private const val CRYPTO_KEY = " ArmadilloStore"
85+ private const val CRYPTO_KEY = " ArmadilloStoreSerializer"
86+ }
87+
88+
89+ private fun encrypt (content : ByteArray ): ByteArray = with (encryptionProtocol) {
90+ encrypt(
91+ deriveContentKey(CRYPTO_KEY ),
92+ deobfuscatePassword(serializerPassword),
93+ content
94+ )
9095 }
9196
9297
93- private fun encrypt (content : ByteArray ): ByteArray =
94- try {
98+ private fun decrypt (encrypted : ByteArray ): ByteArray? =
99+ if (encrypted.isEmpty()) {
100+ null
101+ } else {
95102 encryptionProtocol
96- .encrypt (
103+ .decrypt (
97104 encryptionProtocol.deriveContentKey(CRYPTO_KEY ),
98- encryptionProtocol.deobfuscatePassword(password ),
99- content
105+ encryptionProtocol.deobfuscatePassword(serializerPassword ),
106+ encrypted
100107 )
101- } catch (e: Throwable ) {
102- throw IllegalStateException (e)
103108 }
104109
105-
106- private fun decrypt (encrypted : ByteArray ): ByteArray? {
107- if (encrypted.isEmpty()) {
108- return null
109- }
110- try {
111- return encryptionProtocol
112- .decrypt(
113- encryptionProtocol.deriveContentKey(CRYPTO_KEY ),
114- encryptionProtocol.deobfuscatePassword(password),
115- encrypted
116- )
117- } catch (e: Throwable ) {
118- Log .e(" DataStrore" , " decetyp" , e)
119- // recoveryPolicy.handleBrokenConte(e, keyHash, base64Encrypted, password != null, this)
120- // TODO handle this
121- }
122- return null
123- }
124-
125110 override fun readFrom (input : InputStream ): T =
126111 input
127112 .readBytes()
128113 .let (::decrypt)
129114 .let {
130115 val bytes = it ? : byteArrayOf()
131- if (bytes.isEmpty()) protocol.fromNothing ()
132- else protocol.fromBytes (bytes)
116+ if (bytes.isEmpty()) protocol.default ()
117+ else protocol.decode (bytes)
133118 }
134119
135120
136121 override fun writeTo (t : T , output : OutputStream ) {
137122 protocol
138- .toBytes (t)
123+ .encode (t)
139124 .let (::encrypt)
140125 .also (output::write)
141126 }
0 commit comments