Skip to content

Commit

Permalink
Android: Fix #354: Don't use StrongBox on Google Pixel devices (1.4.x)
Browse files Browse the repository at this point in the history
This fix adds transparent data re-encryption in case that SDK is configured to do not use StrongBox backed key on supported devices. By default, SDK do not use StrongBox backed keys.
  • Loading branch information
hvge committed Mar 16, 2021
1 parent 3cf6322 commit 9f4fb66
Show file tree
Hide file tree
Showing 15 changed files with 1,255 additions and 68 deletions.
15 changes: 14 additions & 1 deletion docs/PowerAuth-SDK-for-Android.md
Expand Up @@ -148,10 +148,23 @@ The following levels of keychain protection are defined:

- `HARDWARE` - The content of the keychain is encrypted with key generated by Android KeyStore and the key is stored and managed by [Trusted Execution Environment](https://en.wikipedia.org/wiki/Trusted_execution_environment).

- `STRONGBOX` - The content of the keychain is encrypted with key generated by Android KeyStore and the key is stored inside of Secure Element (e.g. StrongBox). This is the highest level of Keychain protection currently available.
- `STRONGBOX` - The content of the keychain is encrypted with key generated by Android KeyStore and the key is stored inside of Secure Element (e.g. StrongBox). This is the highest level of Keychain protection currently available, but not enabled by default. See [note below](#strongbox-support-note).

Be aware, that enforcing the required level of protection must be properly reflected in your application's user interface. That means that you should inform the user in case that the device has an insufficient capabilities to run your application securely.

#### StrongBox support note

The StrongBox backed keys are by default turned-off due to poor reliability and low performance of StrongBox implementations on the current Android devices. If you want to turn support on in your application, then use the following code at your application's startup:

```java
try {
KeychainFactory.setStrongBoxEnabled(context, true);
} catch (PowerAuthErrorException e) {
// You must alter the configuration before any keychain is accessed.
// Basically, you should not create any PowerAuthSDK instance before the change.
}
```

## Activation

After you configure the SDK instance, you are ready to make your first activation.
Expand Down
@@ -0,0 +1,57 @@
/*
* Copyright 2021 Wultra s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getlime.security.powerauth.keychain;

import io.getlime.security.powerauth.keychain.StrongBoxSupport;

/**
* Testing implementation of {@link StrongBoxSupport} interface that can simulate StrongBox support
* level during the unit test.
*/
public class FakeStrongBoxSupport implements StrongBoxSupport {

private final boolean isSupported;
private final boolean isEnabled;

/**
* Set StrongBox as not supported.
*/
public FakeStrongBoxSupport() {
isSupported = false;
isEnabled = false;
}

/**
* Set any combination of emulated StrongBox support.
* @param supported Set StrongBox supported.
* @param enabled Set StrongBox enabled.
*/
public FakeStrongBoxSupport(boolean supported, boolean enabled) {
isSupported = supported;
isEnabled = enabled;
}

@Override
public boolean isStrongBoxSupported() {
return isSupported;
}

@Override
public boolean isStrongBoxEnabled() {
return isSupported && isEnabled;
}
}
Expand Up @@ -47,10 +47,10 @@ public void setUp() {
@Test
public void testCachedKeychains() throws Exception {
final Keychain keychain1_a = KeychainFactory.getKeychain(androidContext, KEYCHAIN_1_NAME, KeychainProtection.NONE);
final Keychain keychain1_b = KeychainFactory.getKeychain(androidContext, KEYCHAIN_1_NAME, KeychainProtection.NONE);
assertEquals(keychain1_a, keychain1_b);
final Keychain keychain2_a = KeychainFactory.getKeychain(androidContext, KEYCHAIN_2_NAME, KeychainProtection.NONE);
final Keychain keychain1_b = KeychainFactory.getKeychain(androidContext, KEYCHAIN_1_NAME, KeychainProtection.NONE);
final Keychain keychain2_b = KeychainFactory.getKeychain(androidContext, KEYCHAIN_2_NAME, KeychainProtection.NONE);
assertEquals(keychain1_a, keychain1_b);
assertEquals(keychain2_a, keychain2_b);
}

Expand Down

0 comments on commit 9f4fb66

Please sign in to comment.