/** * Returns the {@code PrivateKey} for the requested alias, or null if no there is no result. * * <p>This method may block while waiting for a connection to another process, and must never be * called from the main thread. * * @param alias The alias of the desired private key, typically returned via {@link * KeyChainAliasCallback#alias}. * @throws KeyChainException if the alias was valid but there was some problem accessing it. * @throws IllegalStateException if called from the main thread. */ @Nullable @WorkerThread public static PrivateKey getPrivateKey(@NonNull Context context, @NonNull String alias) throws KeyChainException, InterruptedException { if (alias == null) { throw new NullPointerException("alias == null"); } KeyChainConnection keyChainConnection = bind(context); try { final IKeyChainService keyChainService = keyChainConnection.getService(); final String keyId = keyChainService.requestPrivateKey(alias); if (keyId == null) { throw new KeyChainException("keystore had a problem"); } return AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore( KeyStore.getInstance(), keyId); } catch (RemoteException e) { throw new KeyChainException(e); } catch (RuntimeException e) { // only certain RuntimeExceptions can be propagated across the IKeyChainService call throw new KeyChainException(e); } catch (UnrecoverableKeyException e) { throw new KeyChainException(e); } finally { keyChainConnection.close(); } }