blob: dca039a06a0d1eb7d39fb712a533a55e5b1260e7 [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.security.identity;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import java.lang.annotation.Retention;
import java.util.Collection;
/**
* An object that contains the result of retrieving data from a credential. This is used to return
* data requested in a {@link PresentationSession}.
*/
public abstract class CredentialDataResult {
/**
* @hide
*/
protected CredentialDataResult() {}
/**
* Returns a CBOR structure containing the retrieved device-signed data.
*
* <p>This structure - along with the session transcript - may be cryptographically
* authenticated to prove to the reader that the data is from a trusted credential and
* {@link #getDeviceMac()} can be used to get a MAC.
*
* <p>The CBOR structure which is cryptographically authenticated is the
* {@code DeviceAuthenticationBytes} structure according to the following
* <a href="https://tools.ietf.org/html/rfc8610">CDDL</a> schema:
*
* <pre>
* DeviceAuthentication = [
* "DeviceAuthentication",
* SessionTranscript,
* DocType,
* DeviceNameSpacesBytes
* ]
*
* DocType = tstr
* SessionTranscript = any
* DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
* DeviceAuthenticationBytes = #6.24(bstr .cbor DeviceAuthentication)
* </pre>
*
* <p>where
*
* <pre>
* DeviceNameSpaces = {
* * NameSpace => DeviceSignedItems
* }
*
* DeviceSignedItems = {
* + DataItemName => DataItemValue
* }
*
* NameSpace = tstr
* DataItemName = tstr
* DataItemValue = any
* </pre>
*
* <p>The returned data is the binary encoding of the {@code DeviceNameSpaces} structure
* as defined above.
*
* @return The bytes of the {@code DeviceNameSpaces} CBOR structure.
*/
public abstract @NonNull byte[] getDeviceNameSpaces();
/**
* Returns a message authentication code over the {@code DeviceAuthenticationBytes} CBOR
* specified in {@link #getDeviceNameSpaces()}, to prove to the reader that the data
* is from a trusted credential.
*
* <p>The MAC proves to the reader that the data is from a trusted credential. This code is
* produced by using the key agreement and key derivation function from the ciphersuite
* with the authentication private key and the reader ephemeral public key to compute a
* shared message authentication code (MAC) key, then using the MAC function from the
* ciphersuite to compute a MAC of the authenticated data. See section 9.2.3.5 of
* ISO/IEC 18013-5 for details of this operation.
*
* <p>If the session transcript or reader ephemeral key wasn't set on the {@link
* PresentationSession} used to obtain this data no message authencation code will be produced
* and this method will return {@code null}.
*
* @return A COSE_Mac0 structure with the message authentication code as described above
* or {@code null} if the conditions specified above are not met.
*/
public abstract @Nullable byte[] getDeviceMac();
/**
* Returns a signature over the {@code DeviceAuthenticationBytes} CBOR
* specified in {@link #getDeviceNameSpaces()}, to prove to the reader that the data
* is from a trusted credential.
*
* <p>The signature is made using the authentication private key. See section 9.1.3.4 of
* ISO/IEC 18013-5:2021 for details of this operation.
*
* <p>If the session transcript or reader ephemeral key wasn't set on the {@link
* PresentationSession} used to obtain this data no signature will be produced and this method
* will return {@code null}.
*
* <p>This is only implemented in feature version 202301 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.
*
* @return A COSE_Sign1 structure as described above or {@code null} if the conditions
* specified above are not met.
*/
public @Nullable byte[] getDeviceSignature() {
throw new UnsupportedOperationException();
}
/**
* Returns the static authentication data associated with the dynamic authentication
* key used to MAC the data returned by {@link #getDeviceNameSpaces()}.
*
* @return The static authentication data associated with dynamic authentication key used to
* MAC the data.
*/
public abstract @NonNull byte[] getStaticAuthenticationData();
/**
* Gets the device-signed entries that was returned.
*
* @return an object to examine the entries returned.
*/
public abstract @NonNull Entries getDeviceSignedEntries();
/**
* Gets the issuer-signed entries that was returned.
*
* @return an object to examine the entries returned.
*/
public abstract @NonNull Entries getIssuerSignedEntries();
/**
* A class for representing data elements returned.
*/
public interface Entries {
/** Value was successfully retrieved. */
int STATUS_OK = 0;
/** The entry does not exist. */
int STATUS_NO_SUCH_ENTRY = 1;
/** The entry was not requested. */
int STATUS_NOT_REQUESTED = 2;
/** The entry wasn't in the request message. */
int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
/** The entry was not retrieved because user authentication failed. */
int STATUS_USER_AUTHENTICATION_FAILED = 4;
/** The entry was not retrieved because reader authentication failed. */
int STATUS_READER_AUTHENTICATION_FAILED = 5;
/**
* The entry was not retrieved because it was configured without any access
* control profile.
*/
int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
/**
* Gets the names of namespaces with retrieved entries.
*
* @return collection of name of namespaces containing retrieved entries. May be empty if no
* data was retrieved.
*/
@NonNull Collection<String> getNamespaces();
/**
* Get the names of all requested entries in a name space.
*
* <p>This includes the name of entries that wasn't successfully retrieved.
*
* @param namespaceName the namespace name to get entries for.
* @return A collection of names for the given namespace or the empty collection if no
* entries was returned for the given name space.
*/
@NonNull Collection<String> getEntryNames(@NonNull String namespaceName);
/**
* Get the names of all entries that was successfully retrieved from a name space.
*
* <p>This only return entries for which {@link #getStatus(String, String)} will return
* {@link #STATUS_OK}.
*
* @param namespaceName the namespace name to get entries for.
* @return The entries in the given namespace that were successfully rerieved or the
* empty collection if no entries was returned for the given name space.
*/
@NonNull Collection<String> getRetrievedEntryNames(@NonNull String namespaceName);
/**
* Gets the status of an entry.
*
* <p>This returns {@link #STATUS_OK} if the value was retrieved, {@link
* #STATUS_NO_SUCH_ENTRY} if the given entry wasn't retrieved, {@link
* #STATUS_NOT_REQUESTED} if it wasn't requested, {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if
* the request message was set but the entry wasn't present in the request message, {@link
* #STATUS_USER_AUTHENTICATION_FAILED} if the value wasn't retrieved because the necessary
* user authentication wasn't performed, {@link #STATUS_READER_AUTHENTICATION_FAILED} if
* the supplied reader certificate chain didn't match the set of certificates the entry was
* provisioned with, or {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was
* configured without any access control profiles.
*
* @param namespaceName the namespace name of the entry.
* @param name the name of the entry to get the value for.
* @return the status indicating whether the value was retrieved and if not, why.
*/
@Status int getStatus(@NonNull String namespaceName, @NonNull String name);
/**
* Gets the raw CBOR data for the value of an entry.
*
* <p>This should only be called on an entry for which the {@link #getStatus(String,
* String)} method returns {@link #STATUS_OK}.
*
* @param namespaceName the namespace name of the entry.
* @param name the name of the entry to get the value for.
* @return the raw CBOR data or {@code null} if no entry with the given name exists.
*/
@Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name);
/**
* The type of the entry status.
* @hide
*/
@Retention(SOURCE)
@IntDef({STATUS_OK, STATUS_NO_SUCH_ENTRY, STATUS_NOT_REQUESTED,
STATUS_NOT_IN_REQUEST_MESSAGE, STATUS_USER_AUTHENTICATION_FAILED,
STATUS_READER_AUTHENTICATION_FAILED, STATUS_NO_ACCESS_CONTROL_PROFILES})
@interface Status {}
}
}