Fixed issue with missing cipher storage name. Also did some small refactorings and adding to comments.

This commit is contained in:
Pelle Stenild Coltau 2017-06-18 12:55:48 +04:00
parent 32c5caff39
commit 1c0552f88b
2 changed files with 29 additions and 12 deletions

View File

@ -12,14 +12,14 @@ import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.oblador.keychain.PrefsStorage.ResultSet;
import com.oblador.keychain.exceptions.CryptoFailedException;
import com.oblador.keychain.exceptions.EmptyParameterException;
import com.oblador.keychain.exceptions.KeyStoreAccessException;
import com.oblador.keychain.cipherStorage.CipherStorage;
import com.oblador.keychain.cipherStorage.CipherStorage.DecryptionResult;
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
import com.oblador.keychain.cipherStorage.CipherStorageKeystoreAESCBC;
import com.oblador.keychain.exceptions.CryptoFailedException;
import com.oblador.keychain.exceptions.EmptyParameterException;
import com.oblador.keychain.exceptions.KeyStoreAccessException;
import java.util.HashMap;
import java.util.Map;
@ -96,8 +96,8 @@ public class KeychainModule extends ReactContextBaseJavaModule {
decryptionResult = currentCipherStorage.decrypt(service, resultSet.usernameBytes, resultSet.passwordBytes);
}
else {
// The encrypted data is encrypted using an older CipherStorage, so we need to decrypt the data, encrypt it using the current CipherStorage and then store it again
CipherStorage oldCipherStorage = cipherStorageMap.get(resultSet.cipherStorageName);
// The encrypted data is encrypted using an older CipherStorage, so we need to decrypt the data first, then encrypt it using the current CipherStorage, then store it again and return
CipherStorage oldCipherStorage = getCipherStorageByName(resultSet.cipherStorageName);
// decrypt using the older cipher storage
decryptionResult = oldCipherStorage.decrypt(service, resultSet.usernameBytes, resultSet.passwordBytes);
// encrypt using the current cipher storage
@ -130,7 +130,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
// First we clean up the cipher storage (using the cipher storage that was used to store the entry)
ResultSet resultSet = prefsStorage.getEncryptedEntry(service);
if (resultSet != null) {
CipherStorage cipherStorage = cipherStorageMap.get(resultSet.cipherStorageName);
CipherStorage cipherStorage = getCipherStorageByName(resultSet.cipherStorageName);
if (cipherStorage != null) {
cipherStorage.removeKey(service);
}
@ -160,7 +160,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
resetGenericPasswordForOptions(server, promise);
}
// The "Current" CipherStorage is the cipherStorage with the highest API level that is lower than the current API level
// The "Current" CipherStorage is the cipherStorage with the highest API level that is lower than or equal to the current API level
private CipherStorage getCipherStorageForCurrentAPILevel() {
int currentAPILevel = Build.VERSION.SDK_INT;
CipherStorage currentCipherStorage = null;
@ -175,4 +175,8 @@ public class KeychainModule extends ReactContextBaseJavaModule {
}
return currentCipherStorage;
}
private CipherStorage getCipherStorageByName(String cipherStorageName) {
return cipherStorageMap.get(cipherStorageName);
}
}

View File

@ -6,6 +6,7 @@ import android.util.Base64;
import com.facebook.react.bridge.ReactApplicationContext;
import com.oblador.keychain.cipherStorage.CipherStorage.EncryptionResult;
import com.oblador.keychain.cipherStorage.CipherStorageFacebookConceal;
public class PrefsStorage {
public static final String KEYCHAIN_DATA = "RN_KEYCHAIN";
@ -33,6 +34,10 @@ public class PrefsStorage {
byte[] bytesForPassword = getBytesForPassword(service);
String cipherStorageName = getCipherStorageName(service);
if (bytesForUsername != null && bytesForPassword != null) {
if (cipherStorageName == null) {
// If the CipherStorage name is not found, we assume it is because the entry was written by an older version of this library. The older version used Facebook Conceal, so we default to that.
cipherStorageName = CipherStorageFacebookConceal.CIPHER_STORAGE_NAME;
}
return new ResultSet(cipherStorageName, bytesForUsername, bytesForPassword);
}
return null;
@ -43,13 +48,21 @@ public class PrefsStorage {
String keyForPassword = getKeyForPassword(service);
String keyForCipherStorage = getKeyForCipherStorage(service);
prefs.edit().remove(keyForUsername).remove(keyForPassword).remove(keyForCipherStorage).apply();
prefs.edit()
.remove(keyForUsername)
.remove(keyForPassword)
.remove(keyForCipherStorage).apply();
}
public void storeEncryptedEntry(String service, EncryptionResult encryptionResult) {
prefs.edit().putString(getKeyForUsername(service), Base64.encodeToString(encryptionResult.username, Base64.DEFAULT))
.putString(getKeyForPassword(service), Base64.encodeToString(encryptionResult.password, Base64.DEFAULT))
.putString(getKeyForCipherStorage(service), encryptionResult.cipherStorage.getCipherStorageName())
String keyForUsername = getKeyForUsername(service);
String keyForPassword = getKeyForPassword(service);
String keyForCipherStorage = getKeyForCipherStorage(service);
prefs.edit()
.putString(keyForUsername, Base64.encodeToString(encryptionResult.username, Base64.DEFAULT))
.putString(keyForPassword, Base64.encodeToString(encryptionResult.password, Base64.DEFAULT))
.putString(keyForCipherStorage, encryptionResult.cipherStorage.getCipherStorageName())
.apply();
}
@ -77,7 +90,7 @@ public class PrefsStorage {
}
private String getKeyForCipherStorage(String service) {
return service + ":" + "i";
return service + ":" + "c";
}
private byte[] getBytes(String key) {