Merge "Keystore:Expected exception for invalid Keys" am: 4fe1ed8e51 am: d3472b9eed

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2175743

Change-Id: I1dbbc1492d1ec5bc69f39cf1a5325a62799163ff
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot
2022-10-04 17:07:28 +00:00
committed by Automerger Merge Worker
4 changed files with 66 additions and 4 deletions

View File

@@ -65,6 +65,7 @@ public final class KeymasterDefs {
public static final int KM_TAG_PADDING = Tag.PADDING; // KM_ENUM_REP | 6; public static final int KM_TAG_PADDING = Tag.PADDING; // KM_ENUM_REP | 6;
public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7; public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7;
public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8; public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8;
public static final int KM_TAG_EC_CURVE = Tag.EC_CURVE; // KM_ENUM | 10;
public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200;
public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202;

View File

@@ -18,13 +18,19 @@ package android.security.keystore2;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.security.KeyStoreSecurityLevel; import android.security.KeyStoreSecurityLevel;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties; import android.security.keystore.KeyProperties;
import android.system.keystore2.Authorization;
import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyMetadata; import android.system.keystore2.KeyMetadata;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec; import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint; import java.security.spec.ECPoint;
import java.security.spec.InvalidParameterSpecException;
/** /**
* {@link ECPublicKey} backed by keystore. * {@link ECPublicKey} backed by keystore.
@@ -56,11 +62,45 @@ public class AndroidKeyStoreECPublicKey extends AndroidKeyStorePublicKey impleme
} }
} }
private static String getEcCurveFromKeymaster(int ecCurve) {
switch (ecCurve) {
case android.hardware.security.keymint.EcCurve.P_224:
return "secp224r1";
case android.hardware.security.keymint.EcCurve.P_256:
return "secp256r1";
case android.hardware.security.keymint.EcCurve.P_384:
return "secp384r1";
case android.hardware.security.keymint.EcCurve.P_521:
return "secp521r1";
}
return "";
}
private ECParameterSpec getCurveSpec(String name)
throws NoSuchAlgorithmException, InvalidParameterSpecException {
AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
parameters.init(new ECGenParameterSpec(name));
return parameters.getParameterSpec(ECParameterSpec.class);
}
@Override @Override
public AndroidKeyStorePrivateKey getPrivateKey() { public AndroidKeyStorePrivateKey getPrivateKey() {
ECParameterSpec params = mParams;
for (Authorization a : getAuthorizations()) {
try {
if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) {
params = getCurveSpec(getEcCurveFromKeymaster(
a.keyParameter.value.getEcCurve()));
break;
}
} catch (Exception e) {
throw new RuntimeException("Unable to parse EC curve "
+ a.keyParameter.value.getEcCurve());
}
}
return new AndroidKeyStoreECPrivateKey( return new AndroidKeyStoreECPrivateKey(
getUserKeyDescriptor(), getKeyIdDescriptor().nspace, getAuthorizations(), getUserKeyDescriptor(), getKeyIdDescriptor().nspace, getAuthorizations(),
getSecurityLevel(), mParams); getSecurityLevel(), params);
} }
@Override @Override

View File

@@ -31,6 +31,8 @@ import java.security.NoSuchAlgorithmException;
import java.security.ProviderException; import java.security.ProviderException;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.interfaces.ECKey;
import java.security.interfaces.XECKey;
import java.security.spec.AlgorithmParameterSpec; import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -132,6 +134,15 @@ public class AndroidKeyStoreKeyAgreementSpi extends KeyAgreementSpi
throw new InvalidKeyException("key == null"); throw new InvalidKeyException("key == null");
} else if (!(key instanceof PublicKey)) { } else if (!(key instanceof PublicKey)) {
throw new InvalidKeyException("Only public keys supported. Key: " + key); throw new InvalidKeyException("Only public keys supported. Key: " + key);
} else if (!(mKey instanceof ECKey && key instanceof ECKey)
&& !(mKey instanceof XECKey && key instanceof XECKey)) {
throw new InvalidKeyException(
"Public and Private key should be of the same type:");
} else if (mKey instanceof ECKey
&& !((ECKey) key).getParams().getCurve()
.equals(((ECKey) mKey).getParams().getCurve())) {
throw new InvalidKeyException(
"Public and Private key parameters should be same.");
} else if (!lastPhase) { } else if (!lastPhase) {
throw new IllegalStateException( throw new IllegalStateException(
"Only one other party supported. lastPhase must be set to true."); "Only one other party supported. lastPhase must be set to true.");

View File

@@ -22,16 +22,18 @@ import android.system.keystore2.Authorization;
import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyDescriptor;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.interfaces.EdECKey; import java.security.interfaces.XECPrivateKey;
import java.security.spec.NamedParameterSpec; import java.security.spec.NamedParameterSpec;
import java.util.Optional;
/** /**
* X25519 Private Key backed by Keystore. * X25519 Private Key backed by Keystore.
* instance of {@link PrivateKey} and {@link EdECKey} * instance of {@link PrivateKey} and {@link XECPrivateKey}
* *
* @hide * @hide
*/ */
public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey { public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey
implements XECPrivateKey {
public AndroidKeyStoreXDHPrivateKey( public AndroidKeyStoreXDHPrivateKey(
@NonNull KeyDescriptor descriptor, long keyId, @NonNull KeyDescriptor descriptor, long keyId,
@NonNull Authorization[] authorizations, @NonNull Authorization[] authorizations,
@@ -44,4 +46,12 @@ public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey impl
public NamedParameterSpec getParams() { public NamedParameterSpec getParams() {
return NamedParameterSpec.X25519; return NamedParameterSpec.X25519;
} }
@Override
public Optional<byte[]> getScalar() {
/* An empty Optional if the scalar cannot be extracted (e.g. if the provider is a hardware
* token and the private key is not allowed to leave the crypto boundary).
*/
return Optional.empty();
}
} }