1 /*
2  * Copyright 2020 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  * An object that contains the result of retrieving data from a credential. This is used to return
30  * data requested from a {@link IdentityCredential}.
31  *
32  * @deprecated Use {@link PresentationSession} instead.
33  */
34 @Deprecated
35 public abstract class ResultData {
36 
37     /** Value was successfully retrieved. */
38     public static final int STATUS_OK = 0;
39 
40     /** The entry does not exist. */
41     public static final int STATUS_NO_SUCH_ENTRY = 1;
42 
43     /** The entry was not requested. */
44     public static final int STATUS_NOT_REQUESTED = 2;
45 
46     /** The entry wasn't in the request message. */
47     public static final int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
48 
49     /** The entry was not retrieved because user authentication failed. */
50     public static final int STATUS_USER_AUTHENTICATION_FAILED = 4;
51 
52     /** The entry was not retrieved because reader authentication failed. */
53     public static final int STATUS_READER_AUTHENTICATION_FAILED = 5;
54 
55     /**
56      * The entry was not retrieved because it was configured without any access
57      * control profile.
58      */
59     public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
60 
61     /**
62      * @hide
63      */
ResultData()64     protected ResultData() {}
65 
66     /**
67      * Returns a CBOR structure containing the retrieved data.
68      *
69      * <p>This structure - along with the session transcript - may be cryptographically
70      * authenticated to prove to the reader that the data is from a trusted credential and
71      * {@link #getMessageAuthenticationCode()} can be used to get a MAC.
72      *
73      * <p>The CBOR structure which is cryptographically authenticated is the
74      * {@code DeviceAuthenticationBytes} structure according to the following
75      * <a href="https://tools.ietf.org/html/rfc8610">CDDL</a> schema:
76      *
77      * <pre>
78      *   DeviceAuthentication = [
79      *     "DeviceAuthentication",
80      *     SessionTranscript,
81      *     DocType,
82      *     DeviceNameSpacesBytes
83      *   ]
84      *
85      *   DocType = tstr
86      *   SessionTranscript = any
87      *   DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
88      *   DeviceAuthenticationBytes = #6.24(bstr .cbor DeviceAuthentication)
89      * </pre>
90      *
91      * <p>where
92      *
93      * <pre>
94      *   DeviceNameSpaces = {
95      *     * NameSpace => DeviceSignedItems
96      *   }
97      *
98      *   DeviceSignedItems = {
99      *     + DataItemName => DataItemValue
100      *   }
101      *
102      *   NameSpace = tstr
103      *   DataItemName = tstr
104      *   DataItemValue = any
105      * </pre>
106      *
107      * <p>The returned data is the binary encoding of the {@code DeviceNameSpaces} structure
108      * as defined above.
109      *
110      * @return The bytes of the {@code DeviceNameSpaces} CBOR structure.
111      */
getAuthenticatedData()112     public abstract @NonNull byte[] getAuthenticatedData();
113 
114     /**
115      * Returns a message authentication code over the {@code DeviceAuthenticationBytes} CBOR
116      * specified in {@link #getAuthenticatedData()}, to prove to the reader that the data
117      * is from a trusted credential.
118      *
119      * <p>The MAC proves to the reader that the data is from a trusted credential. This code is
120      * produced by using the key agreement and key derivation function from the ciphersuite
121      * with the authentication private key and the reader ephemeral public key to compute a
122      * shared message authentication code (MAC) key, then using the MAC function from the
123      * ciphersuite to compute a MAC of the authenticated data. See section 9.2.3.5 of
124      * ISO/IEC 18013-5 for details of this operation.
125      *
126      * <p>If the {@code sessionTranscript} parameter passed to
127      * {@link IdentityCredential#getEntries(byte[], Map, byte[], byte[])} was {@code null}
128      * or the reader ephmeral public key was never set using
129      * {@link IdentityCredential#setReaderEphemeralPublicKey(PublicKey)}, no message
130      * authencation code will be produced and this method will return {@code null}.
131      *
132      * @return A COSE_Mac0 structure with the message authentication code as described above
133      *         or {@code null} if the conditions specified above are not met.
134      */
getMessageAuthenticationCode()135     public abstract @Nullable byte[] getMessageAuthenticationCode();
136 
getSignature()137     @Nullable byte[] getSignature() {
138         throw new UnsupportedOperationException();
139     }
140 
141     /**
142      * Returns the static authentication data associated with the dynamic authentication
143      * key used to sign or MAC the data returned by {@link #getAuthenticatedData()}.
144      *
145      * @return The static authentication data associated with dynamic authentication key used to
146      * MAC the data.
147      */
getStaticAuthenticationData()148     public abstract @NonNull byte[] getStaticAuthenticationData();
149 
150     /**
151      * Gets the names of namespaces with retrieved entries.
152      *
153      * @return collection of name of namespaces containing retrieved entries. May be empty if no
154      *     data was retrieved.
155      */
getNamespaces()156     public abstract @NonNull Collection<String> getNamespaces();
157 
158     /**
159      * Get the names of all entries.
160      *
161      * <p>This includes the name of entries that wasn't successfully retrieved.
162      *
163      * @param namespaceName the namespace name to get entries for.
164      * @return A collection of names or {@code null} if there are no entries for the given
165      *     namespace.
166      */
getEntryNames(@onNull String namespaceName)167     public abstract @Nullable Collection<String> getEntryNames(@NonNull String namespaceName);
168 
169     /**
170      * Get the names of all entries that was successfully retrieved.
171      *
172      * <p>This only return entries for which {@link #getStatus(String, String)} will return
173      * {@link #STATUS_OK}.
174      *
175      * @param namespaceName the namespace name to get entries for.
176      * @return A collection of names or {@code null} if there are no entries for the given
177      *     namespace.
178      */
getRetrievedEntryNames( @onNull String namespaceName)179     public abstract @Nullable Collection<String> getRetrievedEntryNames(
180             @NonNull String namespaceName);
181 
182     /**
183      * Gets the status of an entry.
184      *
185      * <p>This returns {@link #STATUS_OK} if the value was retrieved, {@link #STATUS_NO_SUCH_ENTRY}
186      * if the given entry wasn't retrieved, {@link #STATUS_NOT_REQUESTED} if it wasn't requested,
187      * {@link #STATUS_NOT_IN_REQUEST_MESSAGE} if the request message was set but the entry wasn't
188      * present in the request message, {@link #STATUS_USER_AUTHENTICATION_FAILED} if the value
189      * wasn't retrieved because the necessary user authentication wasn't performed,
190      * {@link #STATUS_READER_AUTHENTICATION_FAILED} if the supplied reader certificate chain didn't
191      * match the set of certificates the entry was provisioned with, or
192      * {@link #STATUS_NO_ACCESS_CONTROL_PROFILES} if the entry was configured without any access
193      * control profiles.
194      *
195      * @param namespaceName the namespace name of the entry.
196      * @param name the name of the entry to get the value for.
197      * @return the status indicating whether the value was retrieved and if not, why.
198      */
getStatus(@onNull String namespaceName, @NonNull String name)199     public abstract @Status int getStatus(@NonNull String namespaceName, @NonNull String name);
200 
201     /**
202      * Gets the raw CBOR data for the value of an entry.
203      *
204      * <p>This should only be called on an entry for which the {@link #getStatus(String, String)}
205      * method returns {@link #STATUS_OK}.
206      *
207      * @param namespaceName the namespace name of the entry.
208      * @param name the name of the entry to get the value for.
209      * @return the raw CBOR data or {@code null} if no entry with the given name exists.
210      */
getEntry(@onNull String namespaceName, @NonNull String name)211     public abstract @Nullable byte[] getEntry(@NonNull String namespaceName, @NonNull String name);
212 
213     /**
214      * The type of the entry status.
215      * @hide
216      */
217     @Retention(SOURCE)
218     @IntDef({STATUS_OK, STATUS_NO_SUCH_ENTRY, STATUS_NOT_REQUESTED, STATUS_NOT_IN_REQUEST_MESSAGE,
219                         STATUS_USER_AUTHENTICATION_FAILED, STATUS_READER_AUTHENTICATION_FAILED,
220                         STATUS_NO_ACCESS_CONTROL_PROFILES})
221     public @interface Status {
222     }
223 }
224