IdentityCredential
abstract class IdentityCredential
kotlin.Any | |
↳ | androidx.security.identity.IdentityCredential |
Class used to read data from a previously provisioned credential. Use IdentityCredentialStore#getCredentialByName(String, int)
to get a IdentityCredential
instance.
Summary
Public methods | |
---|---|
abstract KeyPair |
Create an ephemeral key pair to use to establish a secure channel with a reader. |
abstract ByteArray |
decryptMessageFromReader(@NonNull messageCiphertext: ByteArray) Decrypt a message received from the reader. |
abstract ByteArray |
encryptMessageToReader(@NonNull messagePlaintext: ByteArray) Encrypt a message for transmission to the reader. |
abstract MutableCollection<X509Certificate!> |
Gets a collection of dynamic authentication keys that need certification. |
abstract IntArray |
Get the number of times the dynamic authentication keys have been used. |
abstract MutableCollection<X509Certificate!> |
Gets the X. |
abstract BiometricPrompt.CryptoObject? |
Gets a |
abstract ResultData |
getEntries(@Nullable requestMessage: ByteArray?, @NonNull entriesToRequest: MutableMap<String!, MutableCollection<String!>!>, @Nullable readerSignature: ByteArray?) Retrieve data entries and associated data from this |
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. |
abstract Unit |
setAvailableAuthenticationKeys(keyCount: Int, maxUsesPerKey: Int) Sets the number of dynamic authentication keys the |
abstract Unit |
setReaderEphemeralPublicKey(@NonNull readerEphemeralPublicKey: PublicKey) Set the ephemeral public key provided by the reader. |
abstract Unit |
setSessionTranscript(@NonNull sessionTranscript: ByteArray) Set the session transcript. |
abstract Unit |
storeStaticAuthenticationData(@NonNull authenticationKey: X509Certificate, @NonNull staticAuthData: ByteArray) Store authentication data associated with a dynamic authentication key. |
Public methods
createEphemeralKeyPair
@NonNull 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(byte[])
and decryptMessageFromReader(byte[])
. The private key is also provided for applications that wish to use a cipher suite that is not supported by IdentityCredentialStore
.
Return | |
---|---|
KeyPair |
ephemeral key pair to use to establish a secure channel with a reader. |
decryptMessageFromReader
@NonNull abstract fun decryptMessageFromReader(@NonNull messageCiphertext: ByteArray): ByteArray
Decrypt a message received from the reader.
In order for this to work, setSessionTranscript(byte[])
and setReaderEphemeralPublicKey(PublicKey)
must have already been called.
Parameters | |
---|---|
messageCiphertext |
ByteArray: encrypted message to decrypt. |
Return | |
---|---|
ByteArray |
decrypted message. |
Exceptions | |
---|---|
MessageDecryptionException |
if the ciphertext couldn't be decrypted. |
encryptMessageToReader
@NonNull abstract fun encryptMessageToReader(@NonNull messagePlaintext: ByteArray): ByteArray
Encrypt a message for transmission to the reader.
In order for this to work, setSessionTranscript(byte[])
and setReaderEphemeralPublicKey(PublicKey)
must have already been called.
Parameters | |
---|---|
messagePlaintext |
ByteArray: unencrypted message to encrypt. |
Return | |
---|---|
ByteArray |
encrypted message. |
getAuthKeysNeedingCertification
@NonNull abstract fun getAuthKeysNeedingCertification(): MutableCollection<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 or because one or more keys have reached their usage count, 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(X509Certificate, byte[])
.
Each X.509 certificate is signed by CredentialKey. The certificate chain for CredentialKey can be obtained using the getCredentialKeyCertificateChain()
method.
Return | |
---|---|
MutableCollection<X509Certificate!> |
A collection of X.509 certificates for dynamic authentication keys that need issuer certification. |
getAuthenticationDataUsageCount
@NonNull abstract fun getAuthenticationDataUsageCount(): IntArray
Get the number of times the dynamic authentication keys have been used.
Return | |
---|---|
IntArray |
int array of dynamic authentication key usage counts. |
getCredentialKeyCertificateChain
@NonNull abstract fun getCredentialKeyCertificateChain(): MutableCollection<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 WritableIdentityCredential#getCredentialKeyCertificateChain(byte[])
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.
Return | |
---|---|
MutableCollection<X509Certificate!> |
the certificate chain for this credential's CredentialKey. |
getCryptoObject
@Nullable 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.
Return | |
---|---|
BiometricPrompt.CryptoObject? |
A BiometricPrompt.CryptoObject which can be used with BiometricPrompt or null . |
getEntries
@NonNull abstract fun getEntries(
@Nullable requestMessage: ByteArray?,
@NonNull entriesToRequest: MutableMap<String!, MutableCollection<String!>!>,
@Nullable 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 ResultData#getStatus(String, String)
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(byte[], Map, byte[])
.
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(byte[])
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 |
MutableMap<String!, MutableCollection<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. |
Return | |
---|---|
ResultData |
A ResultData object containing entry data organized by namespace and a cryptographically authenticated representation of the same data. |
Exceptions | |
---|---|
NoAuthenticationKeyAvailableException |
is thrown if authentication keys were never provisioned, none are available, or the available ones are all exhausted and setAllowUsingExhaustedKeys(boolean) was called with false . |
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. |