Merge "Identity Credential: API changes for Android 12" am: 40d6635701
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1464362 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: Iefd4c9ff03bcb208c0817f144aabec19b887708f
This commit is contained in:
@@ -12128,6 +12128,8 @@ package android.content.pm {
|
||||
field public static final String FEATURE_GAMEPAD = "android.hardware.gamepad";
|
||||
field public static final String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors";
|
||||
field public static final String FEATURE_HOME_SCREEN = "android.software.home_screen";
|
||||
field public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE = "android.hardware.identity_credential";
|
||||
field public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS = "android.hardware.identity_credential_direct_access";
|
||||
field public static final String FEATURE_INPUT_METHODS = "android.software.input_methods";
|
||||
field public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels";
|
||||
field public static final String FEATURE_IRIS = "android.hardware.biometrics.iris";
|
||||
@@ -36082,15 +36084,20 @@ package android.security.identity {
|
||||
public abstract class IdentityCredential {
|
||||
method @NonNull public abstract java.security.KeyPair createEphemeralKeyPair();
|
||||
method @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[]) throws android.security.identity.MessageDecryptionException;
|
||||
method @NonNull public byte[] delete(@NonNull byte[]);
|
||||
method @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[]);
|
||||
method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getAuthKeysNeedingCertification();
|
||||
method @NonNull public abstract int[] getAuthenticationDataUsageCount();
|
||||
method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain();
|
||||
method @NonNull public abstract android.security.identity.ResultData getEntries(@Nullable byte[], @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>, @Nullable byte[], @Nullable byte[]) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException, android.security.identity.SessionTranscriptMismatchException;
|
||||
method @NonNull public byte[] proveOwnership(@NonNull byte[]);
|
||||
method public abstract void setAllowUsingExhaustedKeys(boolean);
|
||||
method public void setAllowUsingExpiredKeys(boolean);
|
||||
method public abstract void setAvailableAuthenticationKeys(int, int);
|
||||
method public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
|
||||
method public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
|
||||
method @Deprecated public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
|
||||
method public void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull java.time.Instant, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
|
||||
method @NonNull public byte[] update(@NonNull android.security.identity.PersonalizationData);
|
||||
}
|
||||
|
||||
public class IdentityCredentialException extends java.lang.Exception {
|
||||
@@ -36100,7 +36107,7 @@ package android.security.identity {
|
||||
|
||||
public abstract class IdentityCredentialStore {
|
||||
method @NonNull public abstract android.security.identity.WritableIdentityCredential createCredential(@NonNull String, @NonNull String) throws android.security.identity.AlreadyPersonalizedException, android.security.identity.DocTypeNotSupportedException;
|
||||
method @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
|
||||
method @Deprecated @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
|
||||
method @Nullable public abstract android.security.identity.IdentityCredential getCredentialByName(@NonNull String, int) throws android.security.identity.CipherSuiteNotSupportedException;
|
||||
method @Nullable public static android.security.identity.IdentityCredentialStore getDirectAccessInstance(@NonNull android.content.Context);
|
||||
method @Nullable public static android.security.identity.IdentityCredentialStore getInstance(@NonNull android.content.Context);
|
||||
|
||||
@@ -2123,6 +2123,35 @@ public abstract class PackageManager {
|
||||
@SdkConstant(SdkConstantType.FEATURE)
|
||||
public static final String FEATURE_CTS = "android.software.cts";
|
||||
|
||||
/**
|
||||
* Feature for {@link #getSystemAvailableFeatures} and
|
||||
* {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
|
||||
* {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
|
||||
* at the given feature version.
|
||||
*
|
||||
* <p>Known feature versions include:
|
||||
* <ul>
|
||||
* <li><code>202009</code>: corresponds to the features included in the Identity Credential
|
||||
* API shipped in Android 11.
|
||||
* <li><code>202101</code>: corresponds to the features included in the Identity Credential
|
||||
* API shipped in Android 12.
|
||||
* </ul>
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.FEATURE)
|
||||
public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE =
|
||||
"android.hardware.identity_credential";
|
||||
|
||||
/**
|
||||
* Feature for {@link #getSystemAvailableFeatures} and
|
||||
* {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
|
||||
* {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
|
||||
* with direct access at the given feature version.
|
||||
* See {@link #FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known feature versions.
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.FEATURE)
|
||||
public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS =
|
||||
"android.hardware.identity_credential_direct_access";
|
||||
|
||||
/**
|
||||
* Feature for {@link #getSystemAvailableFeatures} and
|
||||
* {@link #hasSystemFeature}: The device supports one or more methods of
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@@ -237,12 +238,18 @@ class CredstoreIdentityCredential extends IdentityCredential {
|
||||
}
|
||||
|
||||
private boolean mAllowUsingExhaustedKeys = true;
|
||||
private boolean mAllowUsingExpiredKeys = false;
|
||||
|
||||
@Override
|
||||
public void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
|
||||
mAllowUsingExhaustedKeys = allowUsingExhaustedKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
|
||||
mAllowUsingExpiredKeys = allowUsingExpiredKeys;
|
||||
}
|
||||
|
||||
private boolean mOperationHandleSet = false;
|
||||
private long mOperationHandle = 0;
|
||||
|
||||
@@ -256,7 +263,8 @@ class CredstoreIdentityCredential extends IdentityCredential {
|
||||
public long getCredstoreOperationHandle() {
|
||||
if (!mOperationHandleSet) {
|
||||
try {
|
||||
mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys);
|
||||
mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys,
|
||||
mAllowUsingExpiredKeys);
|
||||
mOperationHandleSet = true;
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
@@ -306,7 +314,8 @@ class CredstoreIdentityCredential extends IdentityCredential {
|
||||
rnsParcels,
|
||||
sessionTranscript != null ? sessionTranscript : new byte[0],
|
||||
readerSignature != null ? readerSignature : new byte[0],
|
||||
mAllowUsingExhaustedKeys);
|
||||
mAllowUsingExhaustedKeys,
|
||||
mAllowUsingExpiredKeys);
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
} catch (android.os.ServiceSpecificException e) {
|
||||
@@ -409,6 +418,34 @@ class CredstoreIdentityCredential extends IdentityCredential {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeStaticAuthenticationData(X509Certificate authenticationKey,
|
||||
Instant expirationDate,
|
||||
byte[] staticAuthData)
|
||||
throws UnknownAuthenticationKeyException {
|
||||
try {
|
||||
AuthKeyParcel authKeyParcel = new AuthKeyParcel();
|
||||
authKeyParcel.x509cert = authenticationKey.getEncoded();
|
||||
long millisSinceEpoch = (expirationDate.getEpochSecond() * 1000)
|
||||
+ (expirationDate.getNano() / 1000000);
|
||||
mBinder.storeStaticAuthenticationDataWithExpiration(authKeyParcel,
|
||||
millisSinceEpoch, staticAuthData);
|
||||
} catch (CertificateEncodingException e) {
|
||||
throw new RuntimeException("Error encoding authenticationKey", e);
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
} catch (android.os.ServiceSpecificException e) {
|
||||
if (e.errorCode == ICredentialStore.ERROR_NOT_SUPPORTED) {
|
||||
throw new UnsupportedOperationException("Not supported", e);
|
||||
} else if (e.errorCode == ICredentialStore.ERROR_AUTHENTICATION_KEY_NOT_FOUND) {
|
||||
throw new UnknownAuthenticationKeyException(e.getMessage(), e);
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected ServiceSpecificException with code "
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull int[] getAuthenticationDataUsageCount() {
|
||||
try {
|
||||
@@ -421,4 +458,49 @@ class CredstoreIdentityCredential extends IdentityCredential {
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull byte[] proveOwnership(@NonNull byte[] challenge) {
|
||||
try {
|
||||
byte[] proofOfOwnership = mBinder.proveOwnership(challenge);
|
||||
return proofOfOwnership;
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
} catch (android.os.ServiceSpecificException e) {
|
||||
if (e.errorCode == ICredentialStore.ERROR_NOT_SUPPORTED) {
|
||||
throw new UnsupportedOperationException("Not supported", e);
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected ServiceSpecificException with code "
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull byte[] delete(@NonNull byte[] challenge) {
|
||||
try {
|
||||
byte[] proofOfDeletion = mBinder.deleteWithChallenge(challenge);
|
||||
return proofOfDeletion;
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
} catch (android.os.ServiceSpecificException e) {
|
||||
throw new RuntimeException("Unexpected ServiceSpecificException with code "
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull byte[] update(@NonNull PersonalizationData personalizationData) {
|
||||
try {
|
||||
IWritableCredential binder = mBinder.update();
|
||||
byte[] proofOfProvision =
|
||||
CredstoreWritableIdentityCredential.personalize(binder, personalizationData);
|
||||
return proofOfProvision;
|
||||
} catch (android.os.RemoteException e) {
|
||||
throw new RuntimeException("Unexpected RemoteException ", e);
|
||||
} catch (android.os.ServiceSpecificException e) {
|
||||
throw new RuntimeException("Unexpected ServiceSpecificException with code "
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,5 +162,4 @@ class CredstoreIdentityCredentialStore extends IdentityCredentialStore {
|
||||
+ e.errorCode, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,14 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
|
||||
|
||||
@NonNull @Override
|
||||
public byte[] personalize(@NonNull PersonalizationData personalizationData) {
|
||||
return personalize(mBinder, personalizationData);
|
||||
}
|
||||
|
||||
// Used by both personalize() and CredstoreIdentityCredential.update().
|
||||
//
|
||||
@NonNull
|
||||
static byte[] personalize(IWritableCredential binder,
|
||||
@NonNull PersonalizationData personalizationData) {
|
||||
Collection<AccessControlProfile> accessControlProfiles =
|
||||
personalizationData.getAccessControlProfiles();
|
||||
|
||||
@@ -144,7 +151,7 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
|
||||
secureUserId = getRootSid();
|
||||
}
|
||||
try {
|
||||
byte[] personalizationReceipt = mBinder.personalize(acpParcels, ensParcels,
|
||||
byte[] personalizationReceipt = binder.personalize(acpParcels, ensParcels,
|
||||
secureUserId);
|
||||
return personalizationReceipt;
|
||||
} catch (android.os.RemoteException e) {
|
||||
@@ -164,5 +171,4 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
|
||||
return rootSid;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.security.InvalidKeyException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -113,6 +114,25 @@ public abstract class IdentityCredential {
|
||||
*/
|
||||
public abstract void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys);
|
||||
|
||||
/**
|
||||
* Sets whether to allow using an authentication key which has been expired if no
|
||||
* other key is available. This must be called prior to calling
|
||||
* {@link #getEntries(byte[], Map, byte[], byte[])}.
|
||||
*
|
||||
* <p>By default this is set to false.
|
||||
*
|
||||
* <p>This is only implemented in feature version 202101 or later. If not implemented, the call
|
||||
* fails with {@link UnsupportedOperationException}. See
|
||||
* {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
|
||||
* feature versions.
|
||||
*
|
||||
* @param allowUsingExpiredKeys whether to allow using an authentication key which use count
|
||||
* has been exceeded if no other key is available.
|
||||
*/
|
||||
public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by android.hardware.biometrics.CryptoObject#getOpId() to get an
|
||||
* operation handle.
|
||||
@@ -289,6 +309,21 @@ public abstract class IdentityCredential {
|
||||
*
|
||||
* <p>Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey
|
||||
* can be obtained using the {@link #getCredentialKeyCertificateChain()} method.
|
||||
|
||||
* <p>If the implementation is feature version 202101 or later,
|
||||
* each X.509 certificate contains an X.509 extension at OID 1.3.6.1.4.1.11129.2.1.26 which
|
||||
* contains a DER encoded OCTET STRING with the bytes of the CBOR with the following CDDL:
|
||||
* <pre>
|
||||
* ProofOfBinding = [
|
||||
* "ProofOfBinding",
|
||||
* bstr, // Contains SHA-256(ProofOfProvisioning)
|
||||
* ]
|
||||
* </pre>
|
||||
* <p>This CBOR enables an issuer to determine the exact state of the credential it
|
||||
* returns issuer-signed data for.
|
||||
*
|
||||
* <p> See {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for
|
||||
* known feature versions.
|
||||
*
|
||||
* @return A collection of X.509 certificates for dynamic authentication keys that need issuer
|
||||
* certification.
|
||||
@@ -308,16 +343,136 @@ public abstract class IdentityCredential {
|
||||
* the authenticity
|
||||
* and integrity of the credential data fields.
|
||||
* @throws UnknownAuthenticationKeyException If the given authentication key is not recognized.
|
||||
* @deprecated Use {@link #storeStaticAuthenticationData(X509Certificate, Instant, byte[])}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void storeStaticAuthenticationData(
|
||||
@NonNull X509Certificate authenticationKey,
|
||||
@NonNull byte[] staticAuthData)
|
||||
throws UnknownAuthenticationKeyException;
|
||||
|
||||
/**
|
||||
* Store authentication data associated with a dynamic authentication key.
|
||||
*
|
||||
* This should only be called for an authenticated key returned by
|
||||
* {@link #getAuthKeysNeedingCertification()}.
|
||||
*
|
||||
* <p>This is only implemented in feature version 202101 or later. If not implemented, the call
|
||||
* fails with {@link UnsupportedOperationException}. See
|
||||
* {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
|
||||
* feature versions.
|
||||
*
|
||||
* @param authenticationKey The dynamic authentication key for which certification and
|
||||
* associated static
|
||||
* authentication data is being provided.
|
||||
* @param expirationDate The expiration date of the static authentication data.
|
||||
* @param staticAuthData Static authentication data provided by the issuer that validates
|
||||
* the authenticity
|
||||
* and integrity of the credential data fields.
|
||||
* @throws UnknownAuthenticationKeyException If the given authentication key is not recognized.
|
||||
*/
|
||||
public void storeStaticAuthenticationData(
|
||||
@NonNull X509Certificate authenticationKey,
|
||||
@NonNull Instant expirationDate,
|
||||
@NonNull byte[] staticAuthData)
|
||||
throws UnknownAuthenticationKeyException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of times the dynamic authentication keys have been used.
|
||||
*
|
||||
* @return int array of dynamic authentication key usage counts.
|
||||
*/
|
||||
public @NonNull abstract int[] getAuthenticationDataUsageCount();
|
||||
|
||||
/**
|
||||
* Proves ownership of a credential.
|
||||
*
|
||||
* <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey
|
||||
* with payload set to {@code ProofOfDeletion} as defined below.</p>
|
||||
*
|
||||
* <p>The returned CBOR is the following:</p>
|
||||
* <pre>
|
||||
* ProofOfOwnership = [
|
||||
* "ProofOfOwnership", ; tstr
|
||||
* tstr, ; DocType
|
||||
* bstr, ; Challenge
|
||||
* bool ; true if this is a test credential, should
|
||||
* ; always be false.
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* <p>This is only implemented in feature version 202101 or later. If not implemented, the call
|
||||
* fails with {@link UnsupportedOperationException}. See
|
||||
* {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
|
||||
* feature versions.
|
||||
*
|
||||
* @param challenge is a non-empty byte array whose contents should be unique, fresh and
|
||||
* provided by the issuing authority. The value provided is embedded in the
|
||||
* generated CBOR and enables the issuing authority to verify that the
|
||||
* returned proof is fresh.
|
||||
* @return the COSE_Sign1 data structure above
|
||||
*/
|
||||
public @NonNull byte[] proveOwnership(@NonNull byte[] challenge) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a credential.
|
||||
*
|
||||
* <p>This method returns a COSE_Sign1 data structure signed by the CredentialKey
|
||||
* with payload set to {@code ProofOfDeletion} as defined below.</p>
|
||||
*
|
||||
* <pre>
|
||||
* ProofOfDeletion = [
|
||||
* "ProofOfDeletion", ; tstr
|
||||
* tstr, ; DocType
|
||||
* bstr, ; Challenge
|
||||
* bool ; true if this is a test credential, should
|
||||
* ; always be false.
|
||||
* ]
|
||||
* </pre>
|
||||
*
|
||||
* <p>This is only implemented in feature version 202101 or later. If not implemented, the call
|
||||
* fails with {@link UnsupportedOperationException}. See
|
||||
* {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
|
||||
* feature versions.
|
||||
*
|
||||
* @param challenge is a non-empty byte array whose contents should be unique, fresh and
|
||||
* provided by the issuing authority. The value provided is embedded in the
|
||||
* generated CBOR and enables the issuing authority to verify that the
|
||||
* returned proof is fresh.
|
||||
* @return the COSE_Sign1 data structure above
|
||||
*/
|
||||
public @NonNull byte[] delete(@NonNull byte[] challenge) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the credential with new access control profiles and data items.
|
||||
*
|
||||
* <p>This method is similar to
|
||||
* {@link WritableIdentityCredential#personalize(PersonalizationData)} except that it operates
|
||||
* on an existing credential, see the documentation for that method for the format of the
|
||||
* returned data.
|
||||
*
|
||||
* <p>If this call succeeds an side-effect is that all dynamic authentication keys for the
|
||||
* credential are deleted. The application will need to use
|
||||
* {@link #getAuthKeysNeedingCertification()} to generate replacement keys and return
|
||||
* them for issuer certification.
|
||||
*
|
||||
* <p>This is only implemented in feature version 202101 or later. If not implemented, the call
|
||||
* fails with {@link UnsupportedOperationException}. See
|
||||
* {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
|
||||
* feature versions.
|
||||
*
|
||||
* @param personalizationData The data to update, including access control profiles
|
||||
* and data elements and their values, grouped into namespaces.
|
||||
* @return A COSE_Sign1 data structure, see above.
|
||||
*/
|
||||
public @NonNull byte[] update(@NonNull PersonalizationData personalizationData) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,17 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* <p>Credentials provisioned to the direct access store should <strong>always</strong> use reader
|
||||
* authentication to protect data elements. The reason for this is user authentication or user
|
||||
* approval of data release is not possible when the device is off.
|
||||
*
|
||||
* <p>The Identity Credential API is designed to be able to evolve and change over time
|
||||
* but still provide 100% backwards compatibility. This is complicated by the fact that
|
||||
* there may be a version skew between the API used by the application and the version
|
||||
* implemented in secure hardware. To solve this problem, the API provides for a way
|
||||
* for the application to query which feature version the hardware implements (if any
|
||||
* at all) using
|
||||
* {@link android.content.pm#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} and
|
||||
* {@link android.content.pm#FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS}.
|
||||
* Methods which only work on certain feature versions are clearly documented as
|
||||
* such.
|
||||
*/
|
||||
public abstract class IdentityCredentialStore {
|
||||
IdentityCredentialStore() {}
|
||||
@@ -193,7 +204,9 @@ public abstract class IdentityCredentialStore {
|
||||
* @param credentialName the name of the credential to delete.
|
||||
* @return {@code null} if the credential was not found, the COSE_Sign1 data structure above
|
||||
* if the credential was found and deleted.
|
||||
* @deprecated Use {@link IdentityCredential#delete(byte[])} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract @Nullable byte[] deleteCredentialByName(@NonNull String credentialName);
|
||||
|
||||
/** @hide */
|
||||
@@ -201,5 +214,4 @@ public abstract class IdentityCredentialStore {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Ciphersuite {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user