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
This commit is contained in:
Janis Danisevskis
2020-12-07 08:39:29 -08:00
parent bdb4677dc4
commit efaff8f604
4 changed files with 8 additions and 29 deletions

View File

@@ -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");
}

View File

@@ -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 {

View File

@@ -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(

View File

@@ -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;