Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a91c751 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Preserve interrupted state across waiting for future"

parents 4156ab69 edcacd53
Loading
Loading
Loading
Loading
+43 −27
Original line number Original line Diff line number Diff line
@@ -485,14 +485,14 @@ public class KeyStore {
            mBinder.asBinder().linkToDeath(promise, 0);
            mBinder.asBinder().linkToDeath(promise, 0);
            int errorCode = mBinder.addRngEntropy(promise, data, flags);
            int errorCode = mBinder.addRngEntropy(promise, data, flags);
            if (errorCode == NO_ERROR) {
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get().getErrorCode() == NO_ERROR;
                return interruptedPreservingGet(promise.getFuture()).getErrorCode() == NO_ERROR;
            } else {
            } else {
                return false;
                return false;
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return false;
            return false;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AddRngEntropy completed with exception", e);
            Log.e(TAG, "AddRngEntropy completed with exception", e);
            return false;
            return false;
        } finally {
        } finally {
@@ -550,7 +550,7 @@ public class KeyStore {


    private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
    private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
            int flags, KeyCharacteristics outCharacteristics)
            int flags, KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        int error = NO_ERROR;
        int error = NO_ERROR;
        KeyCharacteristicsCallbackResult result = null;
        KeyCharacteristicsCallbackResult result = null;
@@ -561,7 +561,7 @@ public class KeyStore {
                Log.e(TAG, "generateKeyInternal failed on request " + error);
                Log.e(TAG, "generateKeyInternal failed on request " + error);
                return error;
                return error;
            }
            }
            result = promise.getFuture().get();
            result = interruptedPreservingGet(promise.getFuture());
        } finally {
        } finally {
            mBinder.asBinder().unlinkToDeath(promise, 0);
            mBinder.asBinder().unlinkToDeath(promise, 0);
        }
        }
@@ -594,7 +594,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "generateKey completed with exception", e);
            Log.e(TAG, "generateKey completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        }
        }
@@ -616,7 +616,7 @@ public class KeyStore {
            int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
            int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;


            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;


@@ -627,7 +627,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
            Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } finally {
        } finally {
@@ -642,14 +642,14 @@ public class KeyStore {


    private int importKeyInternal(String alias, KeymasterArguments args, int format, byte[] keyData,
    private int importKeyInternal(String alias, KeymasterArguments args, int format, byte[] keyData,
            int uid, int flags, KeyCharacteristics outCharacteristics)
            int uid, int flags, KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        mBinder.asBinder().linkToDeath(promise, 0);
        mBinder.asBinder().linkToDeath(promise, 0);
        try {
        try {
            int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
            int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;


            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());


            error = result.getKeystoreResponse().getErrorCode();
            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;
@@ -677,7 +677,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ImportKey completed with exception", e);
            Log.e(TAG, "ImportKey completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        }
        }
@@ -749,7 +749,7 @@ public class KeyStore {
            String wrappingKeyAlias,
            String wrappingKeyAlias,
            byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid,
            byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid,
            KeyCharacteristics outCharacteristics)
            KeyCharacteristics outCharacteristics)
                    throws RemoteException, ExecutionException, InterruptedException {
                    throws RemoteException, ExecutionException {
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
        mBinder.asBinder().linkToDeath(promise, 0);
        mBinder.asBinder().linkToDeath(promise, 0);
        try {
        try {
@@ -757,7 +757,7 @@ public class KeyStore {
                    wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
                    wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;


            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
            KeyCharacteristicsCallbackResult result = interruptedPreservingGet(promise.getFuture());


            error = result.getKeystoreResponse().getErrorCode();
            error = result.getKeystoreResponse().getErrorCode();
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;
@@ -788,7 +788,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ImportWrappedKey completed with exception", e);
            Log.e(TAG, "ImportWrappedKey completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        }
        }
@@ -820,14 +820,14 @@ public class KeyStore {
            appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
            appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
            int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
            int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
            if (error == NO_ERROR) {
            if (error == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
            } else {
                return new ExportResult(error);
                return new ExportResult(error);
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "ExportKey completed with exception", e);
            Log.e(TAG, "ExportKey completed with exception", e);
            return null;
            return null;
        } finally {
        } finally {
@@ -866,14 +866,14 @@ public class KeyStore {
            int errorCode =  mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
            int errorCode =  mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
                                           entropy, uid);
                                           entropy, uid);
            if (errorCode == NO_ERROR) {
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
            } else {
                return new OperationResult(errorCode);
                return new OperationResult(errorCode);
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Begin completed with exception", e);
            Log.e(TAG, "Begin completed with exception", e);
            return null;
            return null;
        } finally {
        } finally {
@@ -896,14 +896,14 @@ public class KeyStore {
            input = input != null ? input : new byte[0];
            input = input != null ? input : new byte[0];
            int errorCode =  mBinder.update(promise, token, arguments, input);
            int errorCode =  mBinder.update(promise, token, arguments, input);
            if (errorCode == NO_ERROR) {
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
            } else {
                return new OperationResult(errorCode);
                return new OperationResult(errorCode);
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Update completed with exception", e);
            Log.e(TAG, "Update completed with exception", e);
            return null;
            return null;
        } finally {
        } finally {
@@ -932,14 +932,14 @@ public class KeyStore {
            signature = signature != null ? signature : new byte[0];
            signature = signature != null ? signature : new byte[0];
            int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
            int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy);
            if (errorCode == NO_ERROR) {
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get();
                return interruptedPreservingGet(promise.getFuture());
            } else {
            } else {
                return new OperationResult(errorCode);
                return new OperationResult(errorCode);
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return null;
            return null;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Finish completed with exception", e);
            Log.e(TAG, "Finish completed with exception", e);
            return null;
            return null;
        } finally {
        } finally {
@@ -974,14 +974,14 @@ public class KeyStore {
            mBinder.asBinder().linkToDeath(promise, 0);
            mBinder.asBinder().linkToDeath(promise, 0);
            int errorCode = mBinder.abort(promise, token);
            int errorCode = mBinder.abort(promise, token);
            if (errorCode == NO_ERROR) {
            if (errorCode == NO_ERROR) {
                return promise.getFuture().get().getErrorCode();
                return interruptedPreservingGet(promise.getFuture()).getErrorCode();
            } else {
            } else {
                return errorCode;
                return errorCode;
            }
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "Abort completed with exception", e);
            Log.e(TAG, "Abort completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } finally {
        } finally {
@@ -1137,7 +1137,7 @@ public class KeyStore {
            }
            }
            int error = mBinder.attestKey(promise, alias, params);
            int error = mBinder.attestKey(promise, alias, params);
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;
            KeyAttestationCallbackResult result = promise.getFuture().get();
            KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            error = result.getKeystoreResponse().getErrorCode();
            if (error == NO_ERROR) {
            if (error == NO_ERROR) {
                outChain.shallowCopyFrom(result.getCertificateChain());
                outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1146,7 +1146,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AttestKey completed with exception", e);
            Log.e(TAG, "AttestKey completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } finally {
        } finally {
@@ -1166,7 +1166,7 @@ public class KeyStore {
            }
            }
            int error = mBinder.attestDeviceIds(promise, params);
            int error = mBinder.attestDeviceIds(promise, params);
            if (error != NO_ERROR) return error;
            if (error != NO_ERROR) return error;
            KeyAttestationCallbackResult result = promise.getFuture().get();
            KeyAttestationCallbackResult result = interruptedPreservingGet(promise.getFuture());
            error = result.getKeystoreResponse().getErrorCode();
            error = result.getKeystoreResponse().getErrorCode();
            if (error == NO_ERROR) {
            if (error == NO_ERROR) {
                outChain.shallowCopyFrom(result.getCertificateChain());
                outChain.shallowCopyFrom(result.getCertificateChain());
@@ -1175,7 +1175,7 @@ public class KeyStore {
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.w(TAG, "Cannot connect to keystore", e);
            Log.w(TAG, "Cannot connect to keystore", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } catch (ExecutionException | InterruptedException e) {
        } catch (ExecutionException e) {
            Log.e(TAG, "AttestDevicdeIds completed with exception", e);
            Log.e(TAG, "AttestDevicdeIds completed with exception", e);
            return SYSTEM_ERROR;
            return SYSTEM_ERROR;
        } finally {
        } finally {
@@ -1412,4 +1412,20 @@ public class KeyStore {
            int errorCode) {
            int errorCode) {
        return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode));
        return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode));
    }
    }

    private static <R> R interruptedPreservingGet(CompletableFuture<R> future)
            throws ExecutionException {
        boolean wasInterrupted = false;
        while (true) {
            try {
                R result = future.get();
                if (wasInterrupted) {
                    Thread.currentThread().interrupt();
                }
                return result;
            } catch (InterruptedException e) {
                wasInterrupted = true;
            }
        }
    }
}
}