diff options
| author | 2020-12-07 08:39:29 -0800 | |
|---|---|---|
| committer | 2020-12-18 11:09:06 -0800 | |
| commit | efaff8f604d1ebad59af27420852283f0c9b256e (patch) | |
| tree | 97ce5df8f642754e14eadd6cebc21b4f6887fed8 | |
| parent | bdb4677dc4531c6317b7802f4fc053267e187560 (diff) | |
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
4 files changed, 8 insertions, 29 deletions
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index b2e32a3175e3..176507c74d96 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -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"); } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java index 951f91887894..6546bb6654e2 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreRSACipherSpi.java @@ -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 { diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index c42c7b2c41b0..5e7f6482ebed 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -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( diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java index 18c786aa3093..ae2e47503284 100644 --- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java +++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java @@ -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; |