abstract class IdentityCredential


Class used to read data from a previously provisioned credential. Use getCredentialByName to get a IdentityCredential instance.

Summary

Public functions

abstract KeyPair

Create an ephemeral key pair to use to establish a secure channel with a reader.

abstract ByteArray<Byte>
decryptMessageFromReader(messageCiphertext: ByteArray)

Decrypt a message received from the reader.

ByteArray<Byte>
delete(challenge: ByteArray)

Deletes a credential.

abstract ByteArray<Byte>
encryptMessageToReader(messagePlaintext: ByteArray)

Encrypt a message for transmission to the reader.

abstract (Mutable)Collection<X509Certificate!>

Gets a collection of dynamic authentication keys that need certification.

abstract IntArray<Int>

Get the number of times the dynamic authentication keys have been used.

abstract (Mutable)Collection<X509Certificate!>

Gets the X.509 certificate chain for the CredentialKey which identifies this credential to the issuing authority.

abstract BiometricPrompt.CryptoObject?

Gets a BiometricPrompt.CryptoObject which can be used with this IdentityCredential.

abstract ResultData
getEntries(
    requestMessage: ByteArray?,
    entriesToRequest: (Mutable)Map<String!, (Mutable)Collection<String!>!>,
    readerSignature: ByteArray?
)

Retrieve data entries and associated data from this IdentityCredential.

ByteArray<Byte>

Proves ownership of a credential.

abstract Unit
setAllowUsingExhaustedKeys(allowUsingExhaustedKeys: Boolean)

Sets whether to allow using an authentication key which use count has been exceeded if no other key is available.

Unit
setAllowUsingExpiredKeys(allowUsingExpiredKeys: Boolean)

Sets whether to allow using an authentication key which has been expired if no other key is available.

abstract Unit
setAvailableAuthenticationKeys(keyCount: Int, maxUsesPerKey: Int)

Sets the number of dynamic authentication keys the IdentityCredential will maintain, and the number of times each should be used.

abstract Unit
setReaderEphemeralPublicKey(readerEphemeralPublicKey: PublicKey)

Set the ephemeral public key provided by the reader.

abstract Unit
setSessionTranscript(sessionTranscript: ByteArray)

Set the session transcript.

abstract Unit
storeStaticAuthenticationData(
    authenticationKey: X509Certificate,
    staticAuthData: ByteArray
)

This function is deprecated.

Use storeStaticAuthenticationData instead.

Unit
storeStaticAuthenticationData(
    authenticationKey: X509Certificate,
    expirationDate: Calendar,
    staticAuthData: ByteArray
)

Store authentication data associated with a dynamic authentication key.

ByteArray<Byte>
update(personalizationData: PersonalizationData)

Updates the credential with new access control profiles and data items.

Public functions

createEphemeralKeyPair

Added in 1.0.0-alpha04
abstract fun createEphemeralKeyPair(): KeyPair

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 and decryptMessageFromReader. The private key is also provided for applications that wish to use a cipher suite that is not supported by IdentityCredentialStore.

Returns
KeyPair

ephemeral key pair to use to establish a secure channel with a reader.

decryptMessageFromReader

Added in 1.0.0-alpha04
abstract fun decryptMessageFromReader(messageCiphertext: ByteArray): ByteArray<Byte>

Decrypt a message received from the reader.

In order for this to work, setSessionTranscript and setReaderEphemeralPublicKey must have already been called.

Parameters
messageCiphertext: ByteArray

encrypted message to decrypt.

Returns
ByteArray<Byte>

decrypted message.

Throws
androidx.security.identity.MessageDecryptionException

if the ciphertext couldn't be decrypted.

delete

Added in 1.0.0-alpha04
fun delete(challenge: ByteArray): ByteArray<Byte>

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 if isDeleteSupported returns true. If not the call fails with UnsupportedOperationException.

Parameters
challenge: ByteArray

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
ByteArray<Byte>

the COSE_Sign1 data structure above

encryptMessageToReader

Added in 1.0.0-alpha04
abstract fun encryptMessageToReader(messagePlaintext: ByteArray): ByteArray<Byte>

Encrypt a message for transmission to the reader.

In order for this to work, setSessionTranscript and setReaderEphemeralPublicKey must have already been called.

Parameters
messagePlaintext: ByteArray

unencrypted message to encrypt.

Returns
ByteArray<Byte>

encrypted message.

getAuthKeysNeedingCertification

Added in 1.0.0-alpha04
abstract fun getAuthKeysNeedingCertification(): (Mutable)Collection<X509Certificate!>

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 using storeStaticAuthenticationData.

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 isUpdateSupported returns true, 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
(Mutable)Collection<X509Certificate!>

A collection of X.509 certificates for dynamic authentication keys that need issuer certification.

getAuthenticationDataUsageCount

Added in 1.0.0-alpha04
abstract fun getAuthenticationDataUsageCount(): IntArray<Int>

Get the number of times the dynamic authentication keys have been used.

Returns
IntArray<Int>

int array of dynamic authentication key usage counts.

getCredentialKeyCertificateChain

Added in 1.0.0-alpha04
abstract fun getCredentialKeyCertificateChain(): (Mutable)Collection<X509Certificate!>

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 by getCredentialKeyCertificateChain when the credential was first created and its Android Keystore extension will contain the challenge data set at that time. See the documentation for that method for important information about this certificate chain.

Returns
(Mutable)Collection<X509Certificate!>

the certificate chain for this credential's CredentialKey.

getCryptoObject

Added in 1.0.0-alpha04
abstract fun getCryptoObject(): BiometricPrompt.CryptoObject?

Gets a BiometricPrompt.CryptoObject which can be used with this IdentityCredential.

If IdentityCredential is not hardware-backed the returned BiometricPrompt.CryptoObject is associated with a java.security.Signature object. If IdentityCredential is hardware-backed, the returned BiometricPrompt.CryptoObject is associated android.security.identity.IdentityCredential object from the Android Framework. Because of this, this method is the preferred way to obtain a BiometricPrompt.CryptoObject rather than to construct it manually.

If the credential has no access control profiles with user-authentication, the value null may be returned.

getEntries

Added in 1.0.0-alpha04
abstract fun getEntries(
    requestMessage: ByteArray?,
    entriesToRequest: (Mutable)Map<String!, (Mutable)Collection<String!>!>,
    readerSignature: ByteArray?
): ResultData

Retrieve data entries and associated data from this IdentityCredential.

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 getStatus method on each of the requested entries.

It is the responsibility of the calling application to know if authentication is needed and use e.g. androidx.biometric.BiometricPrompt to make the user authenticate using a androidx.biometric.BiometricPrompt.CryptoObject which references this object. If needed, this must be done before calling getEntries.

It is permissible to call this method multiple times using the same instance.

If not null the requestMessage 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 the setSessionTranscript was called, the X and Y coordinates of the public part of the key-pair previously generated by createEphemeralKeyPair must appear somewhere in the byte array that was set. 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 not null it must be the bytes of a COSE_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 the requestMessage parameter.

The public key corresponding to the key used to make the signature, can be found in the x5chain unprotected header element of the COSE_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 an AccessControlProfile configured with an X.509 certificate which appears in the certificate chain.

Note that only items referenced in entriesToRequest are returned - the requestMessage parameter is used only for enforcing reader authentication.

The reason for having requestMessage and entriesToRequest 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: ByteArray?

If not null, must contain CBOR data conforming to the schema mentioned above.

entriesToRequest: (Mutable)Map<String!, (Mutable)Collection<String!>!>

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: ByteArray?

A COSE_Sign1 structure as described above or null if reader authentication is not being used.

Returns
ResultData

A ResultData object containing entry data organized by namespace and a cryptographically authenticated representation of the same data.

Throws
androidx.security.identity.NoAuthenticationKeyAvailableException

is thrown if authentication keys were never provisioned, none are available, or the available ones are all exhausted and setAllowUsingExhaustedKeys was called with false.

androidx.security.identity.InvalidReaderSignatureException

if the reader signature is invalid, or it doesn't contain a certificate chain, or if the signature failed to validate.

androidx.security.identity.InvalidRequestMessageException

if the requestMessage is malformed.

androidx.security.identity.EphemeralPublicKeyNotFoundException

if the ephemeral public key was not found in the session transcript.

proveOwnership

Added in 1.0.0-alpha04
fun proveOwnership(challenge: ByteArray): ByteArray<Byte>

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 if isProveOwnershipSupported returns true. If not the call fails with UnsupportedOperationException.

Parameters
challenge: ByteArray

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
ByteArray<Byte>

the COSE_Sign1 data structure above

setAllowUsingExhaustedKeys

Added in 1.0.0-alpha04
abstract fun setAllowUsingExhaustedKeys(allowUsingExhaustedKeys: Boolean): Unit

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 calling getEntries or using a BiometricPrompt.CryptoObject which references this object.

By default this is set to true.

Parameters
allowUsingExhaustedKeys: Boolean

whether to allow using an authentication key which use count has been exceeded if no other key is available.

setAllowUsingExpiredKeys

Added in 1.0.0-alpha04
fun setAllowUsingExpiredKeys(allowUsingExpiredKeys: Boolean): Unit

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 getEntries or using a BiometricPrompt.CryptoObject which references this object.

By default this is set to false.

This is only implemented if isStaticAuthenticationDataExpirationSupported returns true. If not the call fails with UnsupportedOperationException.

Parameters
allowUsingExpiredKeys: Boolean

whether to allow using an authentication key which use count has been exceeded if no other key is available.

setAvailableAuthenticationKeys

Added in 1.0.0-alpha04
abstract fun setAvailableAuthenticationKeys(keyCount: Int, maxUsesPerKey: Int): Unit

Sets the number of dynamic authentication keys the IdentityCredential will maintain, and the number of times each should be used.

IdentityCredentials will select the least-used dynamic authentication key each time getEntries is called. IdentityCredentials for which this method has not been called behave as though it had been called wit keyCount 0 and maxUsesPerKey 1.

Parameters
keyCount: Int

The number of active, certified dynamic authentication keys the IdentityCredential will try to keep available. This value must be non-negative.

maxUsesPerKey: Int

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.

setReaderEphemeralPublicKey

Added in 1.0.0-alpha04
abstract fun setReaderEphemeralPublicKey(readerEphemeralPublicKey: PublicKey): Unit

Set the ephemeral public key provided by the reader. This must be called before encryptMessageToReader or decryptMessageFromReader can be called.

Parameters
readerEphemeralPublicKey: PublicKey

The ephemeral public key provided by the reader to establish a secure session.

Throws
java.security.InvalidKeyException

if the given key is invalid.

setSessionTranscript

Added in 1.0.0-alpha04
abstract fun setSessionTranscript(sessionTranscript: ByteArray): Unit

Set the session transcript. This must be called before encryptMessageToReader or decryptMessageFromReader can be called.

This method can only be called once per IdentityCredential instance.

Parameters
sessionTranscript: ByteArray

the session transcript.

storeStaticAuthenticationData

Added in 1.0.0-alpha04
Deprecated in 1.0.0-alpha04
abstract fun storeStaticAuthenticationData(
    authenticationKey: X509Certificate,
    staticAuthData: ByteArray
): Unit

Store authentication data associated with a dynamic authentication key.

This should only be called for an authenticated key returned by getAuthKeysNeedingCertification.

Parameters
authenticationKey: X509Certificate

The dynamic authentication key for which certification and associated static authentication data is being provided.

staticAuthData: ByteArray

Static authentication data provided by the issuer that validates the authenticity and integrity of the credential data fields.

Throws
androidx.security.identity.UnknownAuthenticationKeyException

If the given authentication key is not recognized.

storeStaticAuthenticationData

Added in 1.0.0-alpha04
fun storeStaticAuthenticationData(
    authenticationKey: X509Certificate,
    expirationDate: Calendar,
    staticAuthData: ByteArray
): Unit

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 if isStaticAuthenticationDataExpirationSupported returns true. If not the call fails with UnsupportedOperationException.

Parameters
authenticationKey: X509Certificate

The dynamic authentication key for which certification and associated static authentication data is being provided.

expirationDate: Calendar

The expiration date of the static authentication data.

staticAuthData: ByteArray

Static authentication data provided by the issuer that validates the authenticity and integrity of the credential data fields.

Throws
androidx.security.identity.UnknownAuthenticationKeyException

If the given authentication key is not recognized.

update

Added in 1.0.0-alpha04
fun update(personalizationData: PersonalizationData): ByteArray<Byte>

Updates the credential with new access control profiles and data items.

This method is similar to personalize 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 if isUpdateSupported returns true. If not the call fails with UnsupportedOperationException.

Parameters
personalizationData: PersonalizationData

The data to update, including access control profiles and data elements and their values, grouped into namespaces.

Returns
ByteArray<Byte>

A COSE_Sign1 data structure, see above.