Skip to content
This repository has been archived by the owner on Apr 17, 2024. It is now read-only.

Commit

Permalink
Should not generate master key when Android Keystore is unavailable.
Browse files Browse the repository at this point in the history
This is a fix for #142.

Also run AndroidKeysetManagerTest on Android K/L devices to detect these issues.

PiperOrigin-RevId: 215775656
GitOrigin-RevId: 9d12db529cda4b83dee9aa71fc2ba218c09ac64b
  • Loading branch information
thaidn authored and Tink Team committed Oct 4, 2018
1 parent 84edcd2 commit d32ac27
Showing 1 changed file with 20 additions and 15 deletions.
Expand Up @@ -39,9 +39,6 @@
*
* <p>This class reads and writes to shared preferences, thus is best not to run on the UI thread.
*
* <p>On Android M or newer, the keysets are encrypted with master keys generated and stored in <a
* href="https://developer.android.com/training/articles/keystore.html">Android Keystore</a>.
*
* <h3>Usage</h3>
*
* <pre>{@code
Expand All @@ -63,21 +60,21 @@
* {@code my_keyset_name} preference of the {@code my_pref_file_name} shared preferences file.
*
* <p>On Android M or newer and if a master key URI is set with {@link
* AndroidKeysetManager.Builder#withKeyTemplate}, the keyset will be encrypted when written to
* storage and decrypted when read.
* AndroidKeysetManager.Builder#withMasterKeyUri}, the keyset is encrypted with a master key
* generated and stored in <a
* href="https://developer.android.com/training/articles/keystore.html">Android Keystore</a>. When
* Tink cannot decrypt the keyset it would assume that it is not encrypted.
*
* <p>The master key URI must start with {@code android-keystore://}. If the master key doesn't
* exist, a fresh one is generated. Usage of Android Keystore can be disabled with {@link
* AndroidKeysetManager.Builder#doNotUseKeystore}.
*
* <p>If a master key URI is not chosen or on Android L or older, the keyset will be stored in
* <p>On Android L or older, or when the master key URI is not set, the keyset will be stored in
* cleartext in private preferences which, thanks to the security of the Android framework, no other
* apps can read or write.
*
* <p>When Tink cannot decrypt some keyset it would assume that the keyset is in cleartext.
*
* <p>The resulting manager supports all operations that supported by {@link KeysetManager}. For
* example to rotate the keyset, one can do:
* <p>The resulting manager supports all operations supported by {@link KeysetManager}. For example
* to rotate the keyset, one can do:
*
* <pre>{@code
* manager.rotate(SignatureKeyTemplates.ECDSA_P256);
Expand Down Expand Up @@ -113,11 +110,15 @@ private AndroidKeysetManager(Builder builder) throws GeneralSecurityException, I
}

useKeystore = builder.useKeystore;
masterKey = builder.masterKey;
if (useKeystore && masterKey == null) {
if (useKeystore && builder.masterKeyUri == null) {
throw new IllegalArgumentException(
"need a master key URI, please set it with Builder#masterKeyUri");
}
if (shouldUseKeystore()) {
masterKey = AndroidKeystoreKmsClient.getOrGenerateNewAeadKey(builder.masterKeyUri);
} else {
masterKey = null;
}

keyTemplate = builder.keyTemplate;
keysetManager = readOrGenerateNewKeyset();
Expand All @@ -127,7 +128,7 @@ private AndroidKeysetManager(Builder builder) throws GeneralSecurityException, I
public static final class Builder {
private KeysetReader reader = null;
private KeysetWriter writer = null;
private Aead masterKey = null;
private String masterKeyUri = null;
private boolean useKeystore = true;
private KeyTemplate keyTemplate = null;

Expand All @@ -153,8 +154,12 @@ public Builder withSharedPref(Context context, String keysetName, String prefFil
* <p>Only master keys stored in Android Keystore is supported. The URI must start with {@code
* android-keystore://}.
*/
public Builder withMasterKeyUri(String val) throws GeneralSecurityException, IOException {
masterKey = AndroidKeystoreKmsClient.getOrGenerateNewAeadKey(val);
public Builder withMasterKeyUri(String val) {
if (!val.startsWith(AndroidKeystoreKmsClient.PREFIX)) {
throw new IllegalArgumentException(
"key URI must start with " + AndroidKeystoreKmsClient.PREFIX);
}
masterKeyUri = val;
return this;
}

Expand Down

1 comment on commit d32ac27

@thaidn
Copy link
Contributor Author

@thaidn thaidn commented on d32ac27 Oct 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes #142.

Please sign in to comment.