/** * Returns the {@code X509Certificate} chain 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 certificate chain, 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 X509Certificate[] getCertificateChain( @NonNull Context context, @NonNull String alias) throws KeyChainException, InterruptedException { if (alias == null) { throw new NullPointerException("alias == null"); } KeyChainConnection keyChainConnection = bind(context); try { IKeyChainService keyChainService = keyChainConnection.getService(); final byte[] certificateBytes = keyChainService.getCertificate(alias); if (certificateBytes == null) { return null; } TrustedCertificateStore store = new TrustedCertificateStore(); List<X509Certificate> chain = store.getCertificateChain(toCertificate(certificateBytes)); return chain.toArray(new X509Certificate[chain.size()]); } catch (CertificateException e) { throw new KeyChainException(e); } catch (RemoteException e) { throw new KeyChainException(e); } catch (RuntimeException e) { // only certain RuntimeExceptions can be propagated across the IKeyChainService call throw new KeyChainException(e); } finally { keyChainConnection.close(); } }
/** * 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(); } }