• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.security.identity;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 
25 import java.lang.annotation.Retention;
26 import java.util.Collection;
27 
28 
29 /**
30  * An object that contains the result of retrieving data from a credential. This is used to return
31  * data requested in a {@link PresentationSession}.
32  */
33 public abstract class CredentialDataResult {
34     /**
35      * @hide
36      */
CredentialDataResult()37     protected CredentialDataResult() {}
38 
39     /**
40      * Returns a CBOR structure containing the retrieved device-signed data.
41      *
42      * <p>This structure - along with the session transcript - may be cryptographically
43      * authenticated to prove to the reader that the data is from a trusted credential and
44      * {@link #getDeviceMac()} can be used to get a MAC.
45      *
46      * <p>The CBOR structure which is cryptographically authenticated is the
47      * {@code DeviceAuthenticationBytes} structure according to the following
48      * <a href="https://tools.ietf.org/html/rfc8610">CDDL</a> schema:
49      *
50      * <pre>
51      *   DeviceAuthentication = [
52      *     "DeviceAuthentication",
53      *     SessionTranscript,
54      *     DocType,
55      *     DeviceNameSpacesBytes
56      *   ]
57      *
58      *   DocType = tstr
59      *   SessionTranscript = any
60      *   DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
61      *   DeviceAuthenticationBytes = #6.24(bstr .cbor DeviceAuthentication)
62      * </pre>
63      *
64      * <p>where
65      *
66      * <pre>
67      *   DeviceNameSpaces = {
68      *     * NameSpace => DeviceSignedItems
69      *   }
70      *
71      *   DeviceSignedItems = {
72      *     + DataItemName => DataItemValue
73      *   }
74      *
75      *   NameSpace = tstr
76      *   DataItemName = tstr
77      *   DataItemValue = any
78      * </pre>
79      *
80      * <p>The returned data is the binary encoding of the {@code DeviceNameSpaces} structure
81      * as defined above.
82      *
83      * @return The bytes of the {@code DeviceNameSpaces} CBOR structure.
84      */
getDeviceNameSpaces()85     public abstract @NonNull byte[] getDeviceNameSpaces();
86 
87     /**
88      * Returns a message authentication code over the {@code DeviceAuthenticationBytes} CBOR
89      * specified in {@link #getDeviceNameSpaces()}, to prove to the reader that the data
90      * is from a trusted credential.
91      *
92      * <p>The MAC proves to the reader that the data is from a trusted credential. This code is
93      * produced by using the key agreement and key derivation function from the ciphersuite
94      * with the authentication private key and the reader ephemeral public key to compute a
95      * shared message authentication code (MAC) key, then using the MAC function from the
96      * ciphersuite to compute a MAC of the authenticated data. See section 9.2.3.5 of
97      * ISO/IEC 18013-5 for details of this operation.
98      *
99      * <p>If the session transcript or reader ephemeral key wasn't set on the {@link
100      * PresentationSession} used to obtain this data no message authencation code will be produced
101      * and this method will return {@code null}.
102      *
103      * @return A COSE_Mac0 structure with the message authentication code as described above
104      *         or {@code null} if the conditions specified above are not met.
105      */
getDeviceMac()106     public abstract @Nullable byte[] getDeviceMac();
107 
108     /**
109      * Returns the static authentication data associated with the dynamic authentication
110      * key used to MAC the data returned by {@link #getDeviceNameSpaces()}.
111      *
112      * @return The static authentication data associated with dynamic authentication key used to
113      * MAC the data.
114      */
getStaticAuthenticationData()115     public abstract @NonNull byte[] getStaticAuthenticationData();
116 
117     /**
118      * Gets the device-signed entries that was returned.
119      *
120      * @return an object to examine the entries returned.
121      */
getDeviceSignedEntries()122     public abstract @NonNull Entries getDeviceSignedEntries();
123 
124     /**
125      * Gets the issuer-signed entries that was returned.
126      *
127      * @return an object to examine the entries returned.
128      */
getIssuerSignedEntries()129     public abstract @NonNull Entries getIssuerSignedEntries();
130 
131     /**
132      * A class for representing data elements returned.
133      */
134     public interface Entries {
135         /** Value was successfully retrieved. */
136         int STATUS_OK = 0;
137 
138         /** The entry does not exist. */
139         int STATUS_NO_SUCH_ENTRY = 1;
140 
141         /** The entry was not requested. */
142         int STATUS_NOT_REQUESTED = 2;
143 
144         /** The entry wasn't in the request message. */
145         int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
146 
147         /** The entry was not retrieved because user authentication failed. */
148         int STATUS_USER_AUTHENTICATION_FAILED = 4;
149 
150         /** The entry was not retrieved because reader authentication failed. */
151         int STATUS_READER_AUTHENTICATION_FAILED = 5;
152 
153         /**
154          * The entry was not retrieved because it was configured without any access
155          * control profile.
156          */
157         int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
158 
159         /**
160          * Gets the names of namespaces with retrieved entries.
161          *
162          * @return collection of name of namespaces containing retrieved entries. May be empty if no
163          *     data was retrieved.
164          */
getNamespaces()165         @NonNull Collection<String> getNamespaces();
166 
167         /**
168          * Get the names of all requested entries in a name space.
169          *
170          * <p>This includes the name of entries that wasn't successfully retrieved.
171          *
172          * @param namespaceName the namespace name to get entries for.
173          * @return A collection of names for the given namespace or the empty collection if no
174          *   entries was returned for the given name space.
175          */
getEntryNames(@onNull String namespaceName)176         @NonNull Collection<String> getEntryNames(@NonNull String namespaceName);
177 
178         /**
179          * Get the names of all entries that was successfully retrieved from a name space.
180          *
181          * <p>This only return entries for which {@link #getStatus(String, String)} will return
182          * {@link #STATUS_OK}.
183          *
184          * @param namespaceName the namespace name to get entries for.
185          * @return The entries in the given namespace that were successfully rerieved or the
186          *   empty collection if no entries was returned for the given name space.
187          */
getRetrievedEntryNames(@onNull String namespaceName)188         @NonNull Collection<String> getRetrievedEntryNames(@NonNull String namespaceName);
189 
190         /**
191          * Gets the status of an entry.
192          *
193          * <p>This returns {@link #STATUS_OK} if the value was retrieved, {@link
194          * #STATUS_NO_SUCH_ENTRY} if the given entry wasn't retrieved, {@link
195          * #STATUS_NOT_REQUESTED} if it wasn't requested, {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if
196          * the request message was set but the entry wasn't present in the request message, {@link
197          * #STATUS_USER_AUTHENTICATION_FAILED} if the value wasn't retrieved because the necessary
198          * user authentication wasn't performed, {@link #STATUS_READER_AUTHENTICATION_FAILED} if
199          * the supplied reader certificate chain didn't match the set of certificates the entry was
200          * provisioned with, or {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was
201          * configured without any access control profiles.
202          *
203          * @param namespaceName the namespace name of the entry.
204          * @param name the name of the entry to get the value for.
205          * @return the status indicating whether the value was retrieved and if not, why.
206          */
getStatus(@onNull String namespaceName, @NonNull String name)207         @Status int getStatus(@NonNull String namespaceName, @NonNull String name);
208 
209         /**
210          * Gets the raw CBOR data for the value of an entry.
211          *
212          * <p>This should only be called on an entry for which the {@link #getStatus(String,
213          * String)} method returns {@link #STATUS_OK}.
214          *
215          * @param namespaceName the namespace name of the entry.
216          * @param name the name of the entry to get the value for.
217          * @return the raw CBOR data or {@code null} if no entry with the given name exists.
218          */
getEntry(@onNull String namespaceName, @NonNull String name)219         @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name);
220 
221         /**
222          * The type of the entry status.
223          * @hide
224          */
225         @Retention(SOURCE)
226         @IntDef({STATUS_OK, STATUS_NO_SUCH_ENTRY, STATUS_NOT_REQUESTED,
227                     STATUS_NOT_IN_REQUEST_MESSAGE, STATUS_USER_AUTHENTICATION_FAILED,
228                     STATUS_READER_AUTHENTICATION_FAILED, STATUS_NO_ACCESS_CONTROL_PROFILES})
229                     @interface Status {}
230     }
231 
232 }
233