Android Keystore keys are no longer backed by Conscrypt.

This switches Android Keystore asymmetric keys from being backed by
Conscrypt (via keystore-engine which is an OpenSSL/BoringSSL ENGINE
which talks to keystore via the old KeyStore API) to being backed by
the AndroidKeyStore Provider which talks to keystore via the new
KeyStore API. In effect, this switches asymmetric crypto offered by
Android Keystore from old Keystore API to new KeyStore API, enabling
all the new features such as enforcement of authorizations on key use.

Some algorithms offered by Android Keystore, such as RSA with OAEP
or PSS padding schemes, are not supported by other providers. This
complicates matters because Android Keystore only supports public key
operations if the corresponding private key is in the keystore. Thus,
Android Keystore can only offer these operations for its own public
keys only. This requires AndroidKeyStore to use its own subclasses of
PublicKey everywhere. The ugliest place is where it needs to return
its own subclass of X509Certificate only to be able to return its
own subclass of PublicKey from Certificate.getPublicKey().

Bug: 18088752
Bug: 19284418
Bug: 20912868
Change-Id: Id234f9ab9ff72d353ca1ff66768bd3d46da50d64
This commit is contained in:
Alex Klyubin
2015-06-09 13:25:20 -07:00
parent f22030d1c5
commit 4a0ff7ca98
15 changed files with 675 additions and 202 deletions

View File

@ -29,15 +29,14 @@ import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.security.keystore.KeyInfo;
import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyProperties;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@ -47,7 +46,6 @@ import java.util.Locale;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import com.android.org.conscrypt.OpenSSLEngine;
import com.android.org.conscrypt.TrustedCertificateStore;
/**
@ -90,8 +88,6 @@ import com.android.org.conscrypt.TrustedCertificateStore;
// TODO reference intent for credential installation when public
public final class KeyChain {
private static final String TAG = "KeyChain";
/**
* @hide Also used by KeyChainService implementation
*/
@ -372,15 +368,14 @@ public final class KeyChain {
if (keyId == null) {
throw new KeyChainException("keystore had a problem");
}
final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
return engine.getPrivateKeyById(keyId);
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 (InvalidKeyException e) {
} catch (UnrecoverableKeyException e) {
throw new KeyChainException(e);
} finally {
keyChainConnection.close();