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

Commit efaff8f6 authored by Janis Danisevskis's avatar Janis Danisevskis
Browse files

Keystore 2.0 SPI: Bug fixes

* Correctly recover public key from certificate.
* KeyStore2ParameterUtils: iterate through set flags instead of unset
  flags.
* Return private key on Keystore.getKey() instead of public key.

Test: Keystore CTS tests
Change-Id: I99c1bd49ff5cf7a2d89b54559504e67b3def0cd3
parent bdb4677d
Loading
Loading
Loading
Loading
+5 −26
Original line number Diff line number Diff line
@@ -31,9 +31,7 @@ import android.system.keystore2.KeyEntryResponse;
import android.system.keystore2.KeyMetadata;
import android.system.keystore2.ResponseCode;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.ProviderException;
import java.security.PublicKey;
@@ -42,8 +40,6 @@ import java.security.Signature;
import java.security.UnrecoverableKeyException;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;
import javax.crypto.Mac;
@@ -237,28 +233,11 @@ public class AndroidKeyStoreProvider extends Provider {
            throw new UnrecoverableKeyException("Failed to obtain X.509 form of public key."
                    + " Keystore has no public certificate stored.");
        }
        final byte[] x509EncodedPublicKey = metadata.certificate;
        final byte[] x509PublicCert = metadata.certificate;

        String jcaKeyAlgorithm;
        try {
            jcaKeyAlgorithm = KeyProperties.KeyAlgorithm.fromKeymasterAsymmetricKeyAlgorithm(
                    algorithm);
        } catch (IllegalArgumentException e) {
            throw (UnrecoverableKeyException)
                    new UnrecoverableKeyException("Failed to load private key")
                            .initCause(e);
        }
        PublicKey publicKey = AndroidKeyStoreSpi.toCertificate(x509PublicCert).getPublicKey();

        PublicKey publicKey;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(jcaKeyAlgorithm);
            publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedPublicKey));
        } catch (NoSuchAlgorithmException e) {
            throw new ProviderException(
                    "Failed to obtain " + jcaKeyAlgorithm + " KeyFactory", e);
        } catch (InvalidKeySpecException e) {
            throw new ProviderException("Invalid X.509 encoding of public key", e);
        }
        String jcaKeyAlgorithm = publicKey.getAlgorithm();

        KeyStoreSecurityLevel securityLevel = iSecurityLevel;
        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
@@ -358,7 +337,7 @@ public class AndroidKeyStoreProvider extends Provider {

        KeyDescriptor descriptor = new KeyDescriptor();
        if (namespace == KeyProperties.NAMESPACE_APPLICATION) {
            descriptor.nspace = 0; // ignored;
            descriptor.nspace = KeyProperties.NAMESPACE_APPLICATION; // ignored;
            descriptor.domain = Domain.APP;
        } else {
            descriptor.nspace = namespace;
@@ -407,7 +386,7 @@ public class AndroidKeyStoreProvider extends Provider {
                keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
            return makeAndroidKeyStorePublicKeyFromKeyEntryResponse(descriptor, response.metadata,
                    new KeyStoreSecurityLevel(response.iSecurityLevel),
                    keymasterAlgorithm);
                    keymasterAlgorithm).getPrivateKey();
        } else {
            throw new UnrecoverableKeyException("Key algorithm unknown");
        }
+1 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
    }

    /**
     * RSA cipher with OAEP encryption padding. Only SHA-1 based MGF1 is supported as MGF.
     * RSA cipher with OAEP encryption padding.
     */
    abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {

+1 −1
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
        return null;
    }

    private static X509Certificate toCertificate(byte[] bytes) {
    static X509Certificate toCertificate(byte[] bytes) {
        try {
            final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            return (X509Certificate) certFactory.generateCertificate(
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ public abstract class KeyStore2ParameterUtils {
    static void forEachSetFlag(int flags, Consumer<Integer> consumer) {
        int offset = 0;
        while (flags != 0) {
            if ((flags & 1) == 0) {
            if ((flags & 1) == 1) {
                consumer.accept(1 << offset);
            }
            offset += 1;