Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Applications
android-components
Commits
a4fc129a
Commit
a4fc129a
authored
Feb 11, 2020
by
Emily Kager
Committed by
ekager
Feb 14, 2020
Browse files
For Fenix #8324 - Adds flags for optionally not accessing Keystore
parent
214378d3
Changes
2
Hide whitespace changes
Inline
Side-by-side
components/lib/dataprotect/src/main/java/mozilla/components/lib/dataprotect/SecureAbove22Preferences.kt
View file @
a4fc129a
...
...
@@ -59,9 +59,13 @@ private interface KeyValuePreferences {
*
* @param context A [Context], used for accessing [SharedPreferences].
* @param name A name for this storage, used for isolating different instances of [SecureAbove22Preferences].
* @param forceInsecure A flag indicating whether to force plaintext storage. If set to `true`,
* [InsecurePreferencesImpl21] will be used as a storage layer, otherwise a storage implementation
* will be decided based on Android API version, with a preference given to secure storage
*/
class
SecureAbove22Preferences
(
context
:
Context
,
name
:
String
)
:
KeyValuePreferences
{
private
val
impl
=
if
(
Build
.
VERSION
.
SDK_INT
>=
M
)
{
class
SecureAbove22Preferences
(
context
:
Context
,
name
:
String
,
forceInsecure
:
Boolean
=
false
)
:
KeyValuePreferences
{
private
val
impl
=
if
(
Build
.
VERSION
.
SDK_INT
>=
M
&&
!
forceInsecure
)
{
SecurePreferencesImpl23
(
context
,
name
)
}
else
{
InsecurePreferencesImpl21
(
context
,
name
)
...
...
@@ -82,13 +86,40 @@ class SecureAbove22Preferences(context: Context, name: String) : KeyValuePrefere
* A simple [KeyValuePreferences] implementation which entirely delegates to [SharedPreferences] and doesn't perform any
* encryption/decryption.
*/
private
class
InsecurePreferencesImpl21
(
context
:
Context
,
name
:
String
)
:
KeyValuePreferences
{
@SuppressWarnings
(
"TooGenericExceptionCaught"
)
private
class
InsecurePreferencesImpl21
(
context
:
Context
,
name
:
String
,
migrateFromSecureStorage
:
Boolean
=
true
)
:
KeyValuePreferences
{
companion
object
{
private
const
val
SUFFIX
=
"_kp_pre_m"
}
internal
val
logger
=
Logger
(
"mozac/InsecurePreferencesImpl21"
)
private
val
prefs
=
context
.
getSharedPreferences
(
"$name$SUFFIX"
,
MODE_PRIVATE
)
init
{
// Check if we have any encrypted values stored on disk.
if
(
migrateFromSecureStorage
&&
Build
.
VERSION
.
SDK_INT
>=
M
&&
prefs
.
all
.
isEmpty
())
{
val
secureStorage
=
SecurePreferencesImpl23
(
context
,
name
,
false
)
// Copy over any old values.
try
{
secureStorage
.
all
().
forEach
{
putString
(
it
.
key
,
it
.
value
)
}
}
catch
(
e
:
Exception
)
{
// Certain devices crash on various Keystore exceptions. While trying to migrate
// to use the plaintext storage we don't want to crash if we can't access secure
// storage, and just catch the errors.
logger
.
error
(
"Migrating from secure storage failed"
,
e
)
}
// Erase old storage.
secureStorage
.
clear
()
}
}
override
fun
all
():
Map
<
String
,
String
>
{
return
prefs
.
all
.
mapNotNull
{
if
(
it
.
value
is
String
)
{
...
...
@@ -112,7 +143,11 @@ private class InsecurePreferencesImpl21(context: Context, name: String) : KeyVal
* A [KeyValuePreferences] which is backed by [SharedPreferences] and performs encryption/decryption of values.
*/
@TargetApi
(
M
)
private
class
SecurePreferencesImpl23
(
context
:
Context
,
name
:
String
)
:
KeyValuePreferences
{
private
class
SecurePreferencesImpl23
(
context
:
Context
,
name
:
String
,
migrateFromPlaintextStorage
:
Boolean
=
true
)
:
KeyValuePreferences
{
companion
object
{
private
const
val
SUFFIX
=
"_kp_post_m"
private
const
val
BASE_64_FLAGS
=
Base64
.
URL_SAFE
or
Base64
.
NO_PADDING
...
...
@@ -120,19 +155,21 @@ private class SecurePreferencesImpl23(context: Context, name: String) : KeyValue
private
val
logger
=
Logger
(
"SecurePreferencesImpl23"
)
private
val
prefs
=
context
.
getSharedPreferences
(
"$name$SUFFIX"
,
MODE_PRIVATE
)
private
val
keystore
=
Keystore
(
context
.
packageName
)
private
val
keystore
by
lazy
{
Keystore
(
context
.
packageName
)
}
init
{
// Check if we have any plaintext values stored on disk. That indicates that we've hit an API upgrade situation.
// We just went from pre-M to post-M. Since we already have the plaintext keys, we can transparently migrate
// them to use the encrypted storage layer.
val
insecureStorage
=
InsecurePreferencesImpl21
(
context
,
name
)
// Copy over any old values.
insecureStorage
.
all
().
forEach
{
putString
(
it
.
key
,
it
.
value
)
if
(
migrateFromPlaintextStorage
&&
prefs
.
all
.
isEmpty
())
{
// Check if we have any plaintext values stored on disk. That indicates that we've hit
// an API upgrade situation. We just went from pre-M to post-M. Since we already have
// the plaintext keys, we can transparently migrate them to use the encrypted storage layer.
val
insecureStorage
=
InsecurePreferencesImpl21
(
context
,
name
,
false
)
// Copy over any old values.
insecureStorage
.
all
().
forEach
{
putString
(
it
.
key
,
it
.
value
)
}
// Erase old storage.
insecureStorage
.
clear
()
}
// Erase old storage.
insecureStorage
.
clear
()
}
override
fun
all
():
Map
<
String
,
String
>
{
...
...
components/service/firefox-accounts/src/main/java/mozilla/components/service/fxa/AccountStorage.kt
View file @
a4fc129a
...
...
@@ -9,6 +9,7 @@ import android.content.SharedPreferences
import
mozilla.components.concept.sync.OAuthAccount
import
mozilla.components.lib.crash.CrashReporter
import
mozilla.components.lib.dataprotect.SecureAbove22Preferences
import
mozilla.components.support.base.log.logger.Logger
const
val
FXA_STATE_PREFS_KEY
=
"fxaAppState"
const
val
FXA_STATE_KEY
=
"fxaState"
...
...
@@ -26,19 +27,33 @@ internal interface AccountStorage {
* Migration from [SecureAbove22AccountStorage] will happen upon initialization,
* unless disabled via [migrateFromSecureStorage].
*/
@SuppressWarnings
(
"TooGenericExceptionCaught"
)
internal
class
SharedPrefAccountStorage
(
val
context
:
Context
,
crashReporter
:
CrashReporter
?
=
null
,
migrateFromSecureStorage
:
Boolean
=
true
)
:
AccountStorage
{
internal
val
logger
=
Logger
(
"mozac/SharedPrefAccountStorage"
)
init
{
if
(
migrateFromSecureStorage
)
{
// In case we switched from SecureAbove22AccountStorage to this implementation, migrate persisted account
// and clear out the old storage layer.
val
secureStorage
=
SecureAbove22AccountStorage
(
context
,
crashReporter
,
migrateFromPlaintextStorage
=
false
)
secureStorage
.
read
()
?.
let
{
secureAccount
->
this
.
write
(
secureAccount
.
toJSONString
())
secureStorage
.
clear
()
val
secureStorage
=
SecureAbove22AccountStorage
(
context
,
crashReporter
,
migrateFromPlaintextStorage
=
false
)
try
{
secureStorage
.
read
()
?.
let
{
secureAccount
->
this
.
write
(
secureAccount
.
toJSONString
())
secureStorage
.
clear
()
}
}
catch
(
e
:
Exception
)
{
// Certain devices crash on various Keystore exceptions. While trying to migrate
// to use the plaintext storage we don't want to crash if we can't access secure
// storage, and just catch the errors.
logger
.
error
(
"Migrating from secure storage failed"
,
e
)
}
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment