Class IdentityCredential
- java.lang.Object
-
- com.android.identity.IdentityCredential
-
public abstract class IdentityCredential extends java.lang.Object
Class used to read data from a previously provisioned credential. UseIdentityCredentialStore.getCredentialByName(String, int)
to get aIdentityCredential
instance.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description abstract java.security.KeyPair
createEphemeralKeyPair()
Deprecated.UsePresentationSession
instead.abstract byte[]
decryptMessageFromReader(byte[] messageCiphertext)
Deprecated.Applications should usePresentationSession
and implement encryption/decryption themselves.byte[]
delete(byte[] challenge)
Deletes a credential.abstract byte[]
encryptMessageToReader(byte[] messagePlaintext)
Deprecated.Applications should usePresentationSession
and implement encryption/decryption themselves.java.util.List<android.icu.util.Calendar>
getAuthenticationDataExpirations()
Get the expiration times of dynamic authentication keys.abstract int[]
getAuthenticationDataUsageCount()
Get the number of times the dynamic authentication keys have been used.abstract java.util.Collection<java.security.cert.X509Certificate>
getAuthKeysNeedingCertification()
Gets a collection of dynamic authentication keys that need certification.abstract java.util.Collection<java.security.cert.X509Certificate>
getCredentialKeyCertificateChain()
Gets the X.509 certificate chain for the CredentialKey which identifies this credential to the issuing authority.abstract androidx.biometric.BiometricPrompt.CryptoObject
getCryptoObject()
Gets aBiometricPrompt.CryptoObject
which can be used with thisIdentityCredential
.abstract ResultData
getEntries(byte[] requestMessage, java.util.Map<java.lang.String,java.util.Collection<java.lang.String>> entriesToRequest, byte[] readerSignature)
Deprecated.UsePresentationSession
instead.byte[]
proveOwnership(byte[] challenge)
Proves ownership of a credential.abstract void
setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys)
Deprecated.UsePresentationSession
instead.void
setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys)
Deprecated.UsePresentationSession
instead.abstract void
setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey)
Deprecated.UsesetAvailableAuthenticationKeys(int, int, long)
instead.void
setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey, long minValidTimeMillis)
Sets the number of dynamic authentication keys theIdentityCredential
will maintain, the number of times each should be used, and the minimum amount of time it's valid for.void
setIncrementKeyUsageCount(boolean incrementKeyUsageCount)
Deprecated.UsePresentationSession
instead.abstract void
setReaderEphemeralPublicKey(java.security.PublicKey readerEphemeralPublicKey)
Deprecated.UsePresentationSession
instead.abstract void
setSessionTranscript(byte[] sessionTranscript)
Deprecated.UsePresentationSession
instead.abstract void
storeStaticAuthenticationData(java.security.cert.X509Certificate authenticationKey, byte[] staticAuthData)
Deprecated.void
storeStaticAuthenticationData(java.security.cert.X509Certificate authenticationKey, android.icu.util.Calendar expirationDate, byte[] staticAuthData)
Store authentication data associated with a dynamic authentication key.byte[]
update(PersonalizationData personalizationData)
Updates the credential with new access control profiles and data items.
-
-
-
Method Detail
-
createEphemeralKeyPair
@Deprecated @NonNull public abstract java.security.KeyPair createEphemeralKeyPair()
Deprecated.UsePresentationSession
instead.Create an ephemeral key pair to use to establish a secure channel with a reader.Most applications will use only the public key, and only to send it to the reader, allowing the private key to be used internally for
encryptMessageToReader(byte[])
anddecryptMessageFromReader(byte[])
. The private key is also provided for applications that wish to use a cipher suite that is not supported byIdentityCredentialStore
.- Returns:
- ephemeral key pair to use to establish a secure channel with a reader.
-
setReaderEphemeralPublicKey
@Deprecated public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey readerEphemeralPublicKey) throws java.security.InvalidKeyException
Deprecated.UsePresentationSession
instead.Set the ephemeral public key provided by the reader. This must be called beforeencryptMessageToReader(byte[])
ordecryptMessageFromReader(byte[])
can be called.- Parameters:
readerEphemeralPublicKey
- The ephemeral public key provided by the reader to establish a secure session.- Throws:
java.security.InvalidKeyException
- if the given key is invalid.
-
setSessionTranscript
@Deprecated public abstract void setSessionTranscript(@NonNull byte[] sessionTranscript)
Deprecated.UsePresentationSession
instead.Set the session transcript. This must be called beforeencryptMessageToReader(byte[])
ordecryptMessageFromReader(byte[])
can be called.This method can only be called once per
IdentityCredential
instance.- Parameters:
sessionTranscript
- the session transcript.
-
encryptMessageToReader
@Deprecated @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[] messagePlaintext)
Deprecated.Applications should usePresentationSession
and implement encryption/decryption themselves.Encrypt a message for transmission to the reader.In order for this to work,
setSessionTranscript(byte[])
andsetReaderEphemeralPublicKey(PublicKey)
must have already been called.- Parameters:
messagePlaintext
- unencrypted message to encrypt.- Returns:
- encrypted message.
-
decryptMessageFromReader
@Deprecated @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[] messageCiphertext) throws MessageDecryptionException
Deprecated.Applications should usePresentationSession
and implement encryption/decryption themselves.Decrypt a message received from the reader.In order for this to work,
setSessionTranscript(byte[])
andsetReaderEphemeralPublicKey(PublicKey)
must have already been called.- Parameters:
messageCiphertext
- encrypted message to decrypt.- Returns:
- decrypted message.
- Throws:
MessageDecryptionException
- if the ciphertext couldn't be decrypted.
-
getCredentialKeyCertificateChain
@NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain()
Gets the X.509 certificate chain for the CredentialKey which identifies this credential to the issuing authority. This is the same certificate chain that was returned byWritableIdentityCredential.getCredentialKeyCertificateChain(byte[])
when the credential was first created and its Android Keystore extension will contain thechallenge
data set at that time. See the documentation for that method for important information about this certificate chain.- Returns:
- the certificate chain for this credential's CredentialKey.
-
setAllowUsingExhaustedKeys
@Deprecated public abstract void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys)
Deprecated.UsePresentationSession
instead.Sets whether to allow using an authentication key which use count has been exceeded if no other key is available. This must be called prior to callinggetEntries(byte[], Map, byte[])
or using aBiometricPrompt.CryptoObject
which references this object.By default this is set to true.
- Parameters:
allowUsingExhaustedKeys
- whether to allow using an authentication key which use count has been exceeded if no other key is available.
-
setAllowUsingExpiredKeys
@Deprecated public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys)
Deprecated.UsePresentationSession
instead.Sets whether to allow using an authentication key which has been expired if no other key is available. This must be called prior to callinggetEntries(byte[], Map, byte[])
or using aBiometricPrompt.CryptoObject
which references this object.By default this is set to false.
This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202201
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
allowUsingExpiredKeys
- whether to allow using an authentication key which use count has been exceeded if no other key is available.
-
setIncrementKeyUsageCount
@Deprecated public void setIncrementKeyUsageCount(boolean incrementKeyUsageCount)
Deprecated.UsePresentationSession
instead.Sets whether the usage count of an authentication key should be increased. This must be called prior to callinggetEntries(byte[], Map, byte[])
or using aBiometricPrompt.CryptoObject
which references this object.By default this is set to true.
This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202201
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
incrementKeyUsageCount
- whether the usage count of the key should be increased.
-
getCryptoObject
@Nullable public abstract androidx.biometric.BiometricPrompt.CryptoObject getCryptoObject()
Gets aBiometricPrompt.CryptoObject
which can be used with thisIdentityCredential
.If
IdentityCredential
is hardware-backed, the returnedBiometricPrompt.CryptoObject
is associatedIdentityCredential
object from the Android Framework. If it's not hardware-backed it's not defined which kind of object it's associated with. Because of this, this method is the preferred way to obtain aBiometricPrompt.CryptoObject
rather than to construct it manually.If the credential has no access control profiles with user-authentication and timeout 0, the value
null
may be returned. This just means the application won't have aBiometricPrompt.CryptoObject
to pass toBiometricPrompt
and will have to passnull
instead.- Returns:
- A
BiometricPrompt.CryptoObject
which can be used withBiometricPrompt
ornull
.
-
getEntries
@Deprecated @NonNull public abstract ResultData getEntries(@Nullable byte[] requestMessage, @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>> entriesToRequest, @Nullable byte[] readerSignature) throws NoAuthenticationKeyAvailableException, InvalidReaderSignatureException, EphemeralPublicKeyNotFoundException, InvalidRequestMessageException
Deprecated.UsePresentationSession
instead.Retrieve data entries and associated data from thisIdentityCredential
.If an access control check fails for one of the requested entries or if the entry doesn't exist, the entry is simply not returned. The application can detect this by using the
ResultData.getStatus(String, String)
method on each of the requested entries.It is permissible to call this method multiple times using the same instance. If this is done the same auth-key will be used.
The application should not make any assumptions on whether user authentication is needed. Instead, the application should request the data elements values first and then examine the returned
ResultData
. IfResultData.STATUS_USER_AUTHENTICATION_FAILED
is returned the application should callgetCryptoObject()
and use the returnedBiometricPrompt.CryptoObject
with aBiometricPrompt
. Upon successful authentication the application may callgetEntries(byte[], Map, byte[])
again.If not
null
therequestMessage
parameter must contain data for the request from the verifier. The content can be defined in the way appropriate for the credential, but there are three requirements that must be met to work with this API:- The content must be a CBOR-encoded structure.
- The CBOR structure must be a map.
- The map must contain a tstr key "nameSpaces" whose value contains a map, as described in the example below.
If these requirements are not met the
InvalidRequestMessageException
exception is thrown.Here's an example of CBOR which conforms to this requirement:
ItemsRequest = { ? "docType" : DocType, "nameSpaces" : NameSpaces, ? "RequestInfo" : {* tstr => any} ; Additional info the reader wants to provide } DocType = tstr NameSpaces = { + NameSpace => DataElements ; Requested data elements for each NameSpace } NameSpace = tstr DataElements = { + DataElement => IntentToRetain } DataElement = tstr IntentToRetain = bool
If mdoc session encryption is used (e.g. if
createEphemeralKeyPair()
has been called) and ifsetSessionTranscript(byte[])
was called, the X and Y coordinates of the public part of the key-pair previously generated bycreateEphemeralKeyPair()
must appear somewhere in the bytes of the CBOR. Each of these coordinates must appear encoded with the most significant bits first and use the exact amount of bits indicated by the key size of the ephemeral keys. For example, if the ephemeral key is using the P-256 curve then the 32 bytes for the X coordinate encoded with the most significant bits first must appear somewhere in the CBOR and ditto for the 32 bytes for the Y coordinate.If
readerAuth
is notnull
it must be the bytes of aCOSE_Sign1
structure as defined in RFC 8152. For the payload nil shall be used and the detached payload is the ReaderAuthenticationBytes CBOR described below.ReaderAuthentication = [ "ReaderAuthentication", SessionTranscript, ItemsRequestBytes ] ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest) ReaderAuthenticationBytes = #6.24(bstr .cbor ReaderAuthentication)
where
ItemsRequestBytes
are the bytes in therequestMessage
parameter.The public key corresponding to the key used to make the signature, can be found in the
x5chain
unprotected header element of theCOSE_Sign1
structure (as as described in draft-ietf-cose-x509-04). There will be at least one certificate in said element and there may be more (and if so, each certificate must be signed by its successor).Data elements protected by reader authentication are returned if, and only if, they are mentioned in
requestMessage
,requestMessage
is signed by the top-most certificate in the reader's certificate chain, and the data element is configured with anAccessControlProfile
configured with an X.509 certificate which appears in the certificate chain.Note that only items referenced in
entriesToRequest
are returned - therequestMessage
parameter is used only for enforcing reader authentication.The reason for having
requestMessage
andentriesToRequest
as separate parameters is that the former represents a request from the remote verifier device (optionally signed) and this allows the application to filter the request to not include data elements which the user has not consented to sharing.- Parameters:
requestMessage
- If notnull
, must contain CBOR data conforming to the schema mentioned above.entriesToRequest
- The entries to request, organized as a map of namespace names with each value being a collection of data elements in the given namespace.readerSignature
- ACOSE_Sign1
structure as described above ornull
if reader authentication is not being used.- Returns:
- A
ResultData
object containing entry data organized by namespace and a cryptographically authenticated representation of the same data. - Throws:
NoAuthenticationKeyAvailableException
- is thrown if authentication keys were never provisioned, none are available, or the available ones are all exhausted andsetAllowUsingExhaustedKeys(boolean)
was called withfalse
.InvalidReaderSignatureException
- if the reader signature is invalid, or it doesn't contain a certificate chain, or if the signature failed to validate.InvalidRequestMessageException
- if the requestMessage is malformed.EphemeralPublicKeyNotFoundException
- if the ephemeral public key was not found in the session transcript.CredentialInvalidatedException
- if the credential has been invalidated
-
setAvailableAuthenticationKeys
public abstract void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey)
Deprecated.UsesetAvailableAuthenticationKeys(int, int, long)
instead.Sets the number of dynamic authentication keys theIdentityCredential
will maintain, and the number of times each should be used.IdentityCredential
s will select the least-used dynamic authentication key each timegetEntries(byte[], Map, byte[])
is called.IdentityCredential
s for which this method has not been called behave as though it had been called witkeyCount
0 andmaxUsesPerKey
1.The effect of this method is like calling
setAvailableAuthenticationKeys(int, int, long)
with the last parameter is set to 0.- Parameters:
keyCount
- The number of active, certified dynamic authentication keys theIdentityCredential
will try to keep available. This value must be non-negative.maxUsesPerKey
- The maximum number of times each of the keys will be used before it's eligible for replacement. This value must be greater than zero.
-
getAuthKeysNeedingCertification
@NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getAuthKeysNeedingCertification()
Gets a collection of dynamic authentication keys that need certification.When there aren't enough certified dynamic authentication keys (either because the key count has been increased, one or more keys have reached their usage count, or keys have expired), this method will generate replacement keys and certificates and return them for issuer certification. The issuer certificates and associated static authentication data must then be provided back to the
IdentityCredential
usingstoreStaticAuthenticationData(X509Certificate, Calendar, byte[])
.Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey can be obtained using the
getCredentialKeyCertificateChain()
method.The following non-optional fields for the X.509 certificate are set as follows:
- version: INTEGER 2 (means v3 certificate).
- serialNumber: INTEGER 1 (fixed value: same on all certs).
- signature: must be set to ECDSA.
- subject: CN shall be set to "Android Identity Credential Authentication Key" (fixed value: same on all certs).
- issuer: CN shall be set to "Android Identity Credential Key" (fixed value: same on all certs).
- validity: should be from current time and one year in the future (365 days).
- subjectPublicKeyInfo: must contain attested public key.
If running on a store with
IdentityCredentialStore.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:ProofOfBinding = [ "ProofOfBinding", bstr, // Contains SHA-256(ProofOfProvisioning) ]
This CBOR enables an issuer to determine the exact state of the credential it returns issuer-signed data for.
- Returns:
- A collection of X.509 certificates for dynamic authentication keys that need issuer certification.
-
storeStaticAuthenticationData
@Deprecated public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate authenticationKey, @NonNull byte[] staticAuthData) throws UnknownAuthenticationKeyException
Deprecated.Store authentication data associated with a dynamic authentication key.This should only be called for an authenticated key returned by
getAuthKeysNeedingCertification()
.- Parameters:
authenticationKey
- The dynamic authentication key for which certification and associated static authentication data is being provided.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.
-
storeStaticAuthenticationData
public void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate authenticationKey, @NonNull android.icu.util.Calendar expirationDate, @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
getAuthKeysNeedingCertification()
.This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202101
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
authenticationKey
- The dynamic authentication key for which certification and associated static authentication data is being provided.expirationDate
- The expiration date of the static authentication data.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.
-
getAuthenticationDataUsageCount
@NonNull public abstract int[] getAuthenticationDataUsageCount()
Get the number of times the dynamic authentication keys have been used.- Returns:
- int array of dynamic authentication key usage counts.
-
proveOwnership
@NonNull public byte[] proveOwnership(@NonNull byte[] challenge)
Proves ownership of a credential.This method returns a COSE_Sign1 data structure signed by the CredentialKey with payload set to
ProofOfOwnership
as defined below.ProofOfOwnership = [ "ProofOfOwnership", ; tstr tstr, ; DocType bstr, ; Challenge bool ; true if this is a test credential, should ; always be false. ]
This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202101
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
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.- Returns:
- the COSE_Sign1 data structure above
-
delete
@NonNull public byte[] delete(@NonNull byte[] challenge)
Deletes a credential.This method returns a COSE_Sign1 data structure signed by the CredentialKey with payload set to
ProofOfDeletion
as defined below.ProofOfDeletion = [ "ProofOfDeletion", ; tstr tstr, ; DocType bstr, ; Challenge bool ; true if this is a test credential, should ; always be false. ]
This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202101
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
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.- Returns:
- the COSE_Sign1 data structure above
-
update
@NonNull public byte[] update(@NonNull PersonalizationData personalizationData)
Updates the credential with new access control profiles and data items.This method is similar to
WritableIdentityCredential.personalize(PersonalizationData)
except that it operates on an existing credential, see the documentation for that method for the format of the returned data.If this call succeeds an side-effect is that all dynamic authentication keys for the credential are deleted. The application will need to use
getAuthKeysNeedingCertification()
to generate replacement keys and return them for issuer certification.This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202101
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
personalizationData
- The data to update, including access control profiles and data elements and their values, grouped into namespaces.- Returns:
- A COSE_Sign1 data structure, see above.
-
setAvailableAuthenticationKeys
public void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey, long minValidTimeMillis)
Sets the number of dynamic authentication keys theIdentityCredential
will maintain, the number of times each should be used, and the minimum amount of time it's valid for.The Identity Credential system will select the least-used dynamic authentication key each time
getEntries(byte[], Map, byte[])
is called. Identity Credentials for which this method has not been called behave as though it had been called witkeyCount
0,maxUsesPerKey
1, andminValidTimeMillis
0.This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202301
, fails withUnsupportedOperationException
if using a store with a lesser version.- Parameters:
keyCount
- The number of active, certified dynamic authentication keys theIdentityCredential
will try to keep available. This value must be non-negative.maxUsesPerKey
- The maximum number of times each of the keys will be used before it's eligible for replacement. This value must be greater than zero.minValidTimeMillis
- If a key has less time left than this value it will be eliglible for replacement.
-
getAuthenticationDataExpirations
@NonNull public java.util.List<android.icu.util.Calendar> getAuthenticationDataExpirations()
Get the expiration times of dynamic authentication keys.The returned array may have
null
values if the key hasn't been certified or if it was certified without an expiration date.This is only implemented on
IdentityCredentialStore.FEATURE_VERSION_202301
, fails withUnsupportedOperationException
if using a store with a lesser version.- Returns:
- list of authentication key expirations.
-
-