public abstract class DataVault
extends java.lang.Object
SharedDataVault
which uses a ContentProvider
underneath, the other is PrivateDataVault
which saves all data into a local SQLite database which is accessible only by the enclosing application.
Only the built-in implementations are supported. Clients may not (and actually can not) create their own subclasses of this type.
This class and the above subclasses have static lifecycle methods to manage data vault instances with. These can be used to initialize the library and the particular subclasses. Check out the related method documentations for the details.
The static methods of this class always delegate to SharedDataVault
due to historical reasons. To use a PrivateDataVault
, invoke
its appropriate static methods.
A data vault may be either in a locked or an unlocked state. When unlocked, the data contents become accessible via the various setter and getter
methods. If the data vault is locked then a password must be specified first before attempting to call any data access related methods. This can
be done using unlock(char[])
.
The password itself must adhere to a certain password policy, as described by an instance of DataVault.DVPasswordPolicy
. This can be
accessed using the getPasswordPolicy()
and setPasswordPolicy(DVPasswordPolicy)
methods. An important feature of the policy,
apart from defining formal requirements that passwords must meet, is that it defines a lock timeout which if elapses the data vault locks
itself.
Modifier and Type | Class and Description |
---|---|
static class |
DataVault.DVDataName
This class represents a data record name (and type) within the DataVault that was stored by the application.
|
static class |
DataVault.DVPasswordPolicy
Represents the password policy that is used by various
DataVault implementations to enforce certain rules on the configured
passwords. |
Modifier and Type | Field and Description |
---|---|
protected static java.lang.String |
ERR_MSG_INVALID_PARAMETER |
protected static java.lang.String |
ERR_MSG_VAULT_DELETED |
protected static java.lang.String |
ERR_MSG_VAULT_EXISTS |
protected java.lang.String |
id
The data vault identifier.
|
protected java.util.concurrent.locks.ReadWriteLock |
lock
Lock object to perform proper synchronization with.
|
protected static java.lang.String |
LOG_TAG |
Modifier | Constructor and Description |
---|---|
protected |
DataVault(java.lang.String id,
boolean shouldExist,
char[] password,
com.sybase.persistence.ILegacyDataVault legacy,
java.lang.String transformation,
com.sybase.persistence.LowLevelStorage lowLevelStorage,
com.sybase.persistence.EncryptionKeyDerivation preferredDerivation,
com.sybase.persistence.EncryptionKeyDerivation... additionalDerivations)
Creates a new data vault object.
|
Modifier and Type | Method and Description |
---|---|
void |
changePassword(java.lang.String password,
java.lang.String salt)
Deprecated.
|
void |
changePassword(java.lang.String currentPassword,
java.lang.String currentSalt,
java.lang.String newPassword,
java.lang.String newSalt)
Deprecated.
|
static DataVault |
createVault(java.lang.String dataVaultId,
char[] password)
Creates a new shared data vault using
SharedDataVault.createVault(String, char[]) . |
static DataVault |
createVault(java.lang.String dataVaultId,
java.lang.String password,
java.lang.String salt)
Deprecated.
|
byte[] |
decrypt(byte[] cipherBytes)
Decrypts an array of bytes that was previously encrypted by
encrypt(byte[]) . |
void |
decrypt(java.io.InputStream encryptedStream,
java.io.OutputStream unencryptedStream,
EncrypDecryptListener listener)
Decrypts the data from the specified encrypted stream and writes it to the unencrypted one.
|
protected void |
delete()
Deletes this data vault.
|
void |
deleteValue(java.lang.String name)
Deletes the value pertaining to the specific name.
|
static void |
deleteVault(java.lang.String dataVaultId)
Deletes the shared vault using
SharedDataVault.deleteVault(String) . |
byte[] |
encrypt(byte[] plainBytes)
Encrypts an array of bytes.
|
void |
encrypt(java.io.InputStream unencryptedStream,
java.io.OutputStream encryptedStream,
EncrypDecryptListener listener)
Encrypts the data coming from the specified stream and writes it to the output stream.
|
DataVault.DVDataName[] |
getDataNames()
Returns the data entry names and corresponding types.
|
int |
getLockTimeout()
Returns the lock timeout set.
|
DataVault.DVPasswordPolicy |
getPasswordPolicy()
Returns the password policy used by this data vault.
|
int |
getRetryLimit()
Returns the retry limit.
|
java.lang.String |
getString(java.lang.String name)
Returns the value set previously using
setString(String, String) . |
byte[] |
getValue(java.lang.String name)
Returns the value set previously using
setValue(String, byte[]) . |
static DataVault |
getVault(java.lang.String dataVaultId)
Returns an existing shared data vault using
SharedDataVault.getVault(String) . |
static void |
init(android.content.Context context)
Performs initialization using
SharedDataVault.init(Context) . |
boolean |
isDefaultPasswordUsed()
Returns if the default (i.e.
|
boolean |
isLocked()
Returns whether the data vault is locked.
|
void |
lock()
Locks this data vault.
|
void |
modifyPassword(char[] password)
Changes the password/salt of the vault.
|
void |
modifyPassword(char[] currentPassword,
char[] newPassword)
Changes the password but performs an unlock operation beforehand, just like
unlock(char[]) would. |
void |
resetLockTimeout()
Resets the clock on the timeout feature, as if the user has just unlocked the vault.
|
void |
setLockTimeout(int timeoutInSeconds)
Sets the lock timeout.
|
void |
setPasswordPolicy(DataVault.DVPasswordPolicy policy)
Sets the password policy used by this data vault.
|
void |
setRetryLimit(int limit)
Sets the retry limit.
|
void |
setString(java.lang.String name,
java.lang.String value)
Sets the specified key-string pair in the data vault.
|
void |
setValue(java.lang.String name,
byte[] value)
Sets the specified key-binary pair in the data vault.
|
void |
unlock(char[] password)
Unlocks this data vault given the specified password.
|
void |
unlock(java.lang.String password,
java.lang.String salt)
Does the same as
unlock(char[]) but with an additional salt. |
static boolean |
vaultExists(java.lang.String dataVaultId)
Checks shared data vault existence using
SharedDataVault.vaultExists(String) . |
protected static final java.lang.String LOG_TAG
protected static final java.lang.String ERR_MSG_VAULT_DELETED
protected static final java.lang.String ERR_MSG_VAULT_EXISTS
protected static final java.lang.String ERR_MSG_INVALID_PARAMETER
protected final java.lang.String id
protected final java.util.concurrent.locks.ReadWriteLock lock
protected DataVault(java.lang.String id, boolean shouldExist, char[] password, com.sybase.persistence.ILegacyDataVault legacy, java.lang.String transformation, com.sybase.persistence.LowLevelStorage lowLevelStorage, com.sybase.persistence.EncryptionKeyDerivation preferredDerivation, com.sybase.persistence.EncryptionKeyDerivation... additionalDerivations)
ILegacyDataVault.isLegacyVaultPresent()
. The derivation arguments are used to initialize the gatekeeper that controls the lifecycle of the
data vault in terms of locking/unlocking. The low-level storage is responsible for managing how the data is actually stored. These two
submodules should be using compatible encryption algorithms and transformations. This constructor can create a new data vault from scratch
or open an existing one, depending on what it finds in the underlying medium as of MetaInformation.checkProperExistence()
.
id
- the data vault identifier, must be non-nullshouldExist
- if true the vault should exist, if false it shouldn'tpassword
- the password, used only for creation, can be null. If specified then it will be cleared after this call (no
matter the outcome).legacy
- the legacy data vault to migrate away from at the next unlock, can be nulllowLevelStorage
- the low-level storage which is bound to this data vault throughout its lifecycle, must be non-nullpreferredDerivation
- the preferred key derivation, must be non-nulladditionalDerivations
- the optional list of additional derivations to tryDataVaultException
- if any error occurspublic static void init(android.content.Context context)
SharedDataVault.init(Context)
.context
- a context, must be non-nullpublic static DataVault createVault(java.lang.String dataVaultId, char[] password)
SharedDataVault.createVault(String, char[])
.dataVaultId
- the identifier of the new vault, must be non-nullpassword
- password for encrypting the vault, must be non-nullDataVaultException
- if the vault cannot be created@Deprecated public static DataVault createVault(java.lang.String dataVaultId, java.lang.String password, java.lang.String salt)
createVault(String, char[])
. The salt parameter is ignored.dataVaultId
- the identifier of the new vault, must be non-nullpassword
- password for encrypting the vault, must be non-nullsalt
- the salt, ignoredDataVaultException
- if the vault cannot be createdpublic static DataVault getVault(java.lang.String dataVaultId)
SharedDataVault.getVault(String)
. Note that the returned object might be already in
unlocked state. This can happen if a data vault has already been retrieved for this identifier.
This method always returns the same object for the same identifier.
dataVaultId
- the data vault identifier, must be non-nullDataVaultException
- if any error occurs during retrievalpublic static void deleteVault(java.lang.String dataVaultId)
SharedDataVault.deleteVault(String)
.dataVaultId
- the data vault identifier, must be non-nullDataVaultException
- if any error occurs during removalpublic static boolean vaultExists(java.lang.String dataVaultId)
SharedDataVault.vaultExists(String)
.dataVaultId
- the data vault identifier, must be non-nullDataVaultException
- if any error occurspublic final void unlock(char[] password)
Calling this method on a data vault that is already unlocked does not matter. The operation will execute either ways but if the password is incorrect then it will keep the vault unlocked if it was so already.
password
- the password, can be nullDataVaultException
- if the password is incorrect or any other error occurs during the operationpublic final void unlock(java.lang.String password, java.lang.String salt)
unlock(char[])
but with an additional salt. Newest implementations derive the salt internally. This method therefore
needs to be used if the caller is sure that an older implementation is still present in persisted form. This method then will migrate away from
that at the first successful unlock.password
- the password, can be nullsalt
- the salt, can be nullDataVaultException
- if the password and/or salt is incorrect or any other error occurs during the operationpublic final void lock()
DataVaultException
- if the underlying data vault has already been deletedpublic final boolean isLocked()
DataVaultException
- if the underlying data vault has already been deletedpublic final void resetLockTimeout()
DataVaultException
- if the underlying data vault has already been deleted or is in a locked statepublic final void modifyPassword(char[] password)
password
- the new password, can be nullDataVaultException
- if the underlying data vault has already been deleted or is in a locked state or the
password is invalid@Deprecated public final void changePassword(java.lang.String password, java.lang.String salt)
modifyPassword(char[])
. Use that method instead.password
- the password, can be nullsalt
- the salt, unused in this versionDataVaultException
- if the underlying data vault has already been deleted or is in a locked state or the
password is invalidpublic final void modifyPassword(char[] currentPassword, char[] newPassword)
unlock(char[])
would.currentPassword
- the current password, can be nullnewPassword
- the new password, can be nullDataVaultException
- if the underlying data vault has already been deleted, the new password is not valid in
terms of the policy or some other error occurs@Deprecated public final void changePassword(java.lang.String currentPassword, java.lang.String currentSalt, java.lang.String newPassword, java.lang.String newSalt)
unlock(String, String)
would. This implies that this method can be used if an
underlying legacy data vault is expected to be still around.currentPassword
- the current password, can be nullcurrentSalt
- the salt of the current password, can be nullnewPassword
- the new password, can be nullnewSalt
- the salt of the new password, unused in this versionDataVaultException
- if the underlying data vault has already been deleted, the new password is not valid in
terms of the policy or some other error occurspublic final DataVault.DVPasswordPolicy getPasswordPolicy()
DataVaultException
. This is because several fields
of the password policy were stored with encryption in previous versions. In order to change this first an unlock needs to be performed.
Otherwise, if the data vault is locked then all the fields of the password policy are returned except for the expiration days and the lock timeout. If the data vault is unlocked then all fields are returned entirely.
Newly created data vaults will store the policy in the new unencrypted form right from the beginning so in their case the locked state matters only concerning a couple of fields, as described above.
DataVaultException
- if the data vault is locked and the policy is not yet present in an unencrypted representationpublic final void setPasswordPolicy(DataVault.DVPasswordPolicy policy)
The currently set password is not validated against this new policy as it is not possible without it. Therefore the incorrectness of the
password can be detected the next time an attempt is made to unlock the vault with unlock(char[])
, if the password does not adhere to
the requirements of the new policy. The only way to remedy a situation like that is to modify the password using modifyPassword(char[],
char[])
to a new one that is compliant with the newly set policy.
If the data vault is locked then the expiration days and the lock timeout fields are not persisted.
Note that if the policy is not stored in its new unencrypted representation (as documented by getPasswordPolicy()
and this data
vault is locked then this method throws a DataVaultException
. In this case a successful unlock is required.
policy
- the new policy, can be nullDataVaultException
- if the data vault is missing or the policy is invalid, as of DataVault.DVPasswordPolicy.validate()
public final boolean isDefaultPasswordUsed()
public final void setValue(java.lang.String name, byte[] value)
name
- the name of the key to set, must be non-nullvalue
- the value or null if the association is to be deletedDataVaultException
- if the data vault is locked or any other error occurspublic final byte[] getValue(java.lang.String name)
setValue(String, byte[])
.name
- the name of the key to get, must be non-nullDataVaultException
- if the data vault is locked or any other error occurspublic final void setString(java.lang.String name, java.lang.String value)
name
- the name of the key to set, must be non-nullvalue
- the value or null if the association is to be deletedDataVaultException
- if the data vault is locked or any other error occurspublic final java.lang.String getString(java.lang.String name)
setString(String, String)
.name
- the name of the key to get, must be non-nullDataVaultException
- if the data vault is locked or any other error occurspublic final void deleteValue(java.lang.String name)
setValue(String, byte[])
.name
- the name of the key to delete, must be non-nullDataVaultException
- if the data vault is locked or any other error occurspublic final DataVault.DVDataName[] getDataNames()
Unknown (0)
: The record is of unknown type. Best treat it as a simple raw byte array. It's possible only if the contents of
this data vault have been persisted long ago with previous versions.String (2)
: The record is a string. The name can be used to access its value using getString(String)
.Binary (3)
: The record is a byte array. The name can be used to access its value using getValue(String)
.The returned array is not backed by this object.
DataVaultException
- if the data vault is locked or any other error occurspublic final int getLockTimeout()
DataVaultException
- if the data vault is locked or any other error occurspublic void setLockTimeout(int timeoutInSeconds)
timeoutInSeconds
- the lock timeout in seconds to set, must be non-negativeDataVaultException
- if the data vault is locked or any other error occurspublic int getRetryLimit()
DataVaultException
- if any data access error occurspublic void setRetryLimit(int limit)
limit
- the retry limit to set, must be non-negativeDataVaultException
- if the data vault is locked or any other error occurspublic final byte[] encrypt(byte[] plainBytes)
plainBytes
- the bytes to encrypt, can be nullDataVaultException
- if any error occurs during the operationpublic final byte[] decrypt(byte[] cipherBytes)
encrypt(byte[])
. The data vault must be unlocked.cipherBytes
- the bytes to decrypt, can be nullDataVaultException
- if any error occurs during the operationpublic final void encrypt(java.io.InputStream unencryptedStream, java.io.OutputStream encryptedStream, EncrypDecryptListener listener) throws DataVaultException
encrypt(byte[])
would be called on it. Chunks are bytes long.
This method performs the operation on a separate thread and does not close neither of the streams.
unencryptedStream
- the input, unencrypted stream, must be non-nullencryptedStream
- the output stream to write encrypted data to, must be non-nulllistener
- the listener to invoke at the end of the operation, can be nullDataVaultException
- if any error occurspublic final void decrypt(java.io.InputStream encryptedStream, java.io.OutputStream unencryptedStream, EncrypDecryptListener listener) throws DataVaultException
encrypt(InputStream, OutputStream, EncrypDecryptListener)
.
This method performs the operation on a separate thread and does not close neither of the streams.
encryptedStream
- the encrypted stream to read from, must be non-nullunencryptedStream
- the unencrypted stream to write to, must be non-nulllistener
- the listener to be notified at the end of the operation, can be nullDataVaultException
- if any error occursprotected final void delete()