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:
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user