Merge "Reset AndroidKeyStore Mac and Cipher state when init fails."

This commit is contained in:
Alex Klyubin
2015-04-24 17:52:35 +00:00
committed by Gerrit Code Review
2 changed files with 80 additions and 23 deletions

View File

@@ -152,29 +152,58 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
@Override @Override
protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
resetAll();
boolean success = false;
try {
init(opmode, key, random); init(opmode, key, random);
initAlgorithmSpecificParameters(); initAlgorithmSpecificParameters();
ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized();
success = true;
} finally {
if (!success) {
resetAll();
}
}
} }
@Override @Override
protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException { throws InvalidKeyException, InvalidAlgorithmParameterException {
resetAll();
boolean success = false;
try {
init(opmode, key, random); init(opmode, key, random);
initAlgorithmSpecificParameters(params); initAlgorithmSpecificParameters(params);
ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized();
success = true;
} finally {
if (!success) {
resetAll();
}
}
} }
@Override @Override
protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
resetAll();
boolean success = false;
try {
init(opmode, key, random); init(opmode, key, random);
initAlgorithmSpecificParameters(params); initAlgorithmSpecificParameters(params);
ensureKeystoreOperationInitialized(); ensureKeystoreOperationInitialized();
success = true;
} finally {
if (!success) {
resetAll();
}
}
} }
private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException { private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
resetAll();
if (!(key instanceof KeyStoreSecretKey)) { if (!(key instanceof KeyStoreSecretKey)) {
throw new InvalidKeyException( throw new InvalidKeyException(
"Unsupported key: " + ((key != null) ? key.getClass().getName() : "null")); "Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));

View File

@@ -69,9 +69,10 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
private final int mKeymasterDigest; private final int mKeymasterDigest;
private final int mMacSizeBytes; private final int mMacSizeBytes;
private String mKeyAliasInKeyStore; // Fields below are populated by engineInit and should be preserved after engineDoFinal.
private KeyStoreSecretKey mKey;
// The fields below are reset by the engineReset operation. // Fields below are reset when engineDoFinal succeeds.
private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer; private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer;
private IBinder mOperationToken; private IBinder mOperationToken;
private Long mOperationHandle; private Long mOperationHandle;
@@ -89,28 +90,39 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
@Override @Override
protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
InvalidAlgorithmParameterException { InvalidAlgorithmParameterException {
resetAll();
boolean success = false;
try {
init(key, params);
ensureKeystoreOperationInitialized();
success = true;
} finally {
if (!success) {
resetAll();
}
}
}
private void init(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
InvalidAlgorithmParameterException {
if (key == null) { if (key == null) {
throw new InvalidKeyException("key == null"); throw new InvalidKeyException("key == null");
} else if (!(key instanceof KeyStoreSecretKey)) { } else if (!(key instanceof KeyStoreSecretKey)) {
throw new InvalidKeyException( throw new InvalidKeyException(
"Only Android KeyStore secret keys supported. Key: " + key); "Only Android KeyStore secret keys supported. Key: " + key);
} }
mKey = (KeyStoreSecretKey) key;
if (params != null) { if (params != null) {
throw new InvalidAlgorithmParameterException( throw new InvalidAlgorithmParameterException(
"Unsupported algorithm parameters: " + params); "Unsupported algorithm parameters: " + params);
} }
mKeyAliasInKeyStore = ((KeyStoreSecretKey) key).getAlias();
if (mKeyAliasInKeyStore == null) {
throw new InvalidKeyException("Key's KeyStore alias not known");
}
engineReset();
ensureKeystoreOperationInitialized();
} }
@Override private void resetAll() {
protected void engineReset() { mKey = null;
IBinder operationToken = mOperationToken; IBinder operationToken = mOperationToken;
if (operationToken != null) { if (operationToken != null) {
mOperationToken = null; mOperationToken = null;
@@ -120,11 +132,26 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
mChunkedStreamer = null; mChunkedStreamer = null;
} }
private void resetWhilePreservingInitState() {
IBinder operationToken = mOperationToken;
if (operationToken != null) {
mOperationToken = null;
mKeyStore.abort(operationToken);
}
mOperationHandle = null;
mChunkedStreamer = null;
}
@Override
protected void engineReset() {
resetWhilePreservingInitState();
}
private void ensureKeystoreOperationInitialized() { private void ensureKeystoreOperationInitialized() {
if (mChunkedStreamer != null) { if (mChunkedStreamer != null) {
return; return;
} }
if (mKeyAliasInKeyStore == null) { if (mKey == null) {
throw new IllegalStateException("Not initialized"); throw new IllegalStateException("Not initialized");
} }
@@ -132,7 +159,8 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC); keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_HMAC);
keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest); keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
OperationResult opResult = mKeyStore.begin(mKeyAliasInKeyStore, OperationResult opResult = mKeyStore.begin(
mKey.getAlias(),
KeymasterDefs.KM_PURPOSE_SIGN, KeymasterDefs.KM_PURPOSE_SIGN,
true, true,
keymasterArgs, keymasterArgs,
@@ -184,7 +212,7 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
throw KeyStore.getCryptoOperationException(e); throw KeyStore.getCryptoOperationException(e);
} }
engineReset(); resetWhilePreservingInitState();
return result; return result;
} }