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 android.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.util.Collection; 23 import java.util.LinkedHashMap; 24 import java.util.Map; 25 26 /** 27 * An object representing a request for credential data. 28 */ 29 public class CredentialDataRequest { CredentialDataRequest()30 CredentialDataRequest() {} 31 32 /** 33 * Gets the device-signed entries to request. 34 * 35 * @return the device-signed entries to request. 36 */ getDeviceSignedEntriesToRequest()37 public @NonNull Map<String, Collection<String>> getDeviceSignedEntriesToRequest() { 38 return mDeviceSignedEntriesToRequest; 39 } 40 41 /** 42 * Gets the issuer-signed entries to request. 43 * 44 * @return the issuer-signed entries to request. 45 */ getIssuerSignedEntriesToRequest()46 public @NonNull Map<String, Collection<String>> getIssuerSignedEntriesToRequest() { 47 return mIssuerSignedEntriesToRequest; 48 } 49 50 /** 51 * Gets whether to allow using an authentication key which use count has been exceeded. 52 * 53 * <p>By default this is set to true. 54 * 55 * @return whether to allow using an authentication key which use 56 * count has been exceeded if no other key is available. 57 */ isAllowUsingExhaustedKeys()58 public boolean isAllowUsingExhaustedKeys() { 59 return mAllowUsingExhaustedKeys; 60 } 61 62 /** 63 * Gets whether to allow using an authentication key which is expired. 64 * 65 * <p>By default this is set to false. 66 * 67 * @return whether to allow using an authentication key which is 68 * expired if no other key is available. 69 */ isAllowUsingExpiredKeys()70 public boolean isAllowUsingExpiredKeys() { 71 return mAllowUsingExpiredKeys; 72 } 73 74 /** 75 * Gets whether to increment the use-count for the authentication key used. 76 * 77 * <p>By default this is set to true. 78 * 79 * @return whether to increment the use count of the authentication key used. 80 */ isIncrementUseCount()81 public boolean isIncrementUseCount() { 82 return mIncrementUseCount; 83 } 84 85 /** 86 * Gets the request message CBOR. 87 * 88 * <p>This data structure is described in the documentation for the 89 * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method. 90 * 91 * @return the request message CBOR as described above. 92 */ getRequestMessage()93 public @Nullable byte[] getRequestMessage() { 94 return mRequestMessage; 95 } 96 97 /** 98 * Gets the reader signature. 99 * 100 * <p>This data structure is described in the documentation for the 101 * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method. 102 * 103 * @return a {@code COSE_Sign1} structure as described above. 104 */ getReaderSignature()105 public @Nullable byte[] getReaderSignature() { 106 return mReaderSignature; 107 } 108 109 Map<String, Collection<String>> mDeviceSignedEntriesToRequest = new LinkedHashMap<>(); 110 Map<String, Collection<String>> mIssuerSignedEntriesToRequest = new LinkedHashMap<>(); 111 boolean mAllowUsingExhaustedKeys = true; 112 boolean mAllowUsingExpiredKeys = false; 113 boolean mIncrementUseCount = true; 114 byte[] mRequestMessage = null; 115 byte[] mReaderSignature = null; 116 117 /** 118 * A builder for {@link CredentialDataRequest}. 119 */ 120 public static final class Builder { 121 private CredentialDataRequest mData; 122 123 /** 124 * Creates a new builder. 125 */ Builder()126 public Builder() { 127 mData = new CredentialDataRequest(); 128 } 129 130 /** 131 * Sets the device-signed entries to request. 132 * 133 * @param entriesToRequest the device-signed entries to request. 134 */ setDeviceSignedEntriesToRequest( @onNull Map<String, Collection<String>> entriesToRequest)135 public @NonNull Builder setDeviceSignedEntriesToRequest( 136 @NonNull Map<String, Collection<String>> entriesToRequest) { 137 mData.mDeviceSignedEntriesToRequest = entriesToRequest; 138 return this; 139 } 140 141 /** 142 * Sets the issuer-signed entries to request. 143 * 144 * @param entriesToRequest the issuer-signed entries to request. 145 * @return the builder. 146 */ setIssuerSignedEntriesToRequest( @onNull Map<String, Collection<String>> entriesToRequest)147 public @NonNull Builder setIssuerSignedEntriesToRequest( 148 @NonNull Map<String, Collection<String>> entriesToRequest) { 149 mData.mIssuerSignedEntriesToRequest = entriesToRequest; 150 return this; 151 } 152 153 /** 154 * Sets whether to allow using an authentication key which use count has been exceeded. 155 * 156 * <p>This is useful in situations where the application hasn't had a chance to renew 157 * authentication keys, for example if the device hasn't been connected to the Internet or 158 * if the issuing authority server has been down. 159 * 160 * <p>The reason this could be useful is that the privacy risk of reusing an authentication 161 * key for a credential presentation could be significantly smaller compared to the 162 * inconvenience of not being able to present the credential at all. 163 * 164 * <p>By default this is set to true. 165 * 166 * @param allowUsingExhaustedKeys whether to allow using an authentication key which use 167 * count has been exceeded if no other key is available. 168 * @return the builder. 169 */ setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys)170 public @NonNull Builder setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) { 171 mData.mAllowUsingExhaustedKeys = allowUsingExhaustedKeys; 172 return this; 173 } 174 175 /** 176 * Sets whether to allow using an authentication key which is expired. 177 * 178 * <p>This is useful in situations where the application hasn't had a chance to renew 179 * authentication keys, for example if the device hasn't been connected to the Internet or 180 * if the issuing authority server has been down. 181 * 182 * <p>The reason this could be useful is that many verifiers are likely to accept a 183 * credential presentation using an expired authentication key (the credential itself 184 * wouldn't be expired) and it's likely better for the holder to be able to do this than 185 * not present their credential at all. 186 * 187 * <p>By default this is set to false. 188 * 189 * @param allowUsingExpiredKeys whether to allow using an authentication key which is 190 * expired if no other key is available. 191 * @return the builder. 192 */ setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys)193 public @NonNull Builder setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) { 194 mData.mAllowUsingExpiredKeys = allowUsingExpiredKeys; 195 return this; 196 } 197 198 /** 199 * Sets whether to increment the use-count for the authentication key used. 200 * 201 * <p>Not incrementing the use-count for an authentication key is useful in situations 202 * where the authentication key is known with certainty to not be leaked. For example, 203 * consider an application doing a credential presentation for the sole purpose of 204 * displaying the credential data to the user (not for verification). 205 * 206 * <p>By default this is set to true. 207 * 208 * @param incrementUseCount whether to increment the use count of the authentication 209 * key used. 210 * @return the builder. 211 */ setIncrementUseCount(boolean incrementUseCount)212 public @NonNull Builder setIncrementUseCount(boolean incrementUseCount) { 213 mData.mIncrementUseCount = incrementUseCount; 214 return this; 215 } 216 217 /** 218 * Sets the request message CBOR. 219 * 220 * <p>This data structure is described in the documentation for the 221 * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method. 222 * 223 * @param requestMessage the request message CBOR as described above. 224 * @return the builder. 225 */ setRequestMessage(@onNull byte[] requestMessage)226 public @NonNull Builder setRequestMessage(@NonNull byte[] requestMessage) { 227 mData.mRequestMessage = requestMessage; 228 return this; 229 } 230 231 /** 232 * Sets the reader signature. 233 * 234 * <p>This data structure is described in the documentation for the 235 * {@link PresentationSession#getCredentialData(String, CredentialDataRequest)} method. 236 * 237 * @param readerSignature a {@code COSE_Sign1} structure as described above. 238 * @return the builder. 239 */ setReaderSignature(@onNull byte[] readerSignature)240 public @NonNull Builder setReaderSignature(@NonNull byte[] readerSignature) { 241 mData.mReaderSignature = readerSignature; 242 return this; 243 } 244 245 /** 246 * Finishes building a {@link CredentialDataRequest}. 247 * 248 * @return the {@link CredentialDataRequest} object. 249 */ build()250 public @NonNull CredentialDataRequest build() { 251 return mData; 252 } 253 } 254 } 255