blob: cf18fd1c6a0b87e2e1903dce476c9e3d8b5d5041 [file] [log] [blame]
Robert Berry5f138702018-01-17 15:18:05 +00001/*
2 * Copyright (C) 2017 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
17package android.security.keystore;
18
19import android.annotation.NonNull;
20import android.os.Parcel;
21import android.os.Parcelable;
22
23import com.android.internal.util.Preconditions;
24
25import java.util.List;
26
27/**
Robert Berry8cb582d2018-02-26 16:31:01 +000028 * @deprecated Use {@link android.security.keystore.recovery.KeyChainSnapshot}.
Robert Berry5f138702018-01-17 15:18:05 +000029 * @hide
30 */
31public final class KeychainSnapshot implements Parcelable {
Dmitry Dementyevadd1bad2018-01-18 16:44:08 -080032 private static final int DEFAULT_MAX_ATTEMPTS = 10;
33 private static final long DEFAULT_COUNTER_ID = 1L;
34
Robert Berry5f138702018-01-17 15:18:05 +000035 private int mSnapshotVersion;
Dmitry Dementyevadd1bad2018-01-18 16:44:08 -080036 private int mMaxAttempts = DEFAULT_MAX_ATTEMPTS;
37 private long mCounterId = DEFAULT_COUNTER_ID;
38 private byte[] mServerParams;
39 private byte[] mPublicKey;
Robert Berry9e1bd362018-01-17 23:28:45 +000040 private List<KeychainProtectionParams> mKeychainProtectionParams;
Robert Berry5f138702018-01-17 15:18:05 +000041 private List<WrappedApplicationKey> mEntryRecoveryData;
42 private byte[] mEncryptedRecoveryKeyBlob;
43
44 /**
45 * @hide
46 * Deprecated, consider using builder.
47 */
48 public KeychainSnapshot(
49 int snapshotVersion,
Robert Berry9e1bd362018-01-17 23:28:45 +000050 @NonNull List<KeychainProtectionParams> keychainProtectionParams,
Robert Berry5f138702018-01-17 15:18:05 +000051 @NonNull List<WrappedApplicationKey> wrappedApplicationKeys,
52 @NonNull byte[] encryptedRecoveryKeyBlob) {
53 mSnapshotVersion = snapshotVersion;
54 mKeychainProtectionParams =
55 Preconditions.checkCollectionElementsNotNull(keychainProtectionParams,
56 "keychainProtectionParams");
57 mEntryRecoveryData = Preconditions.checkCollectionElementsNotNull(wrappedApplicationKeys,
58 "wrappedApplicationKeys");
59 mEncryptedRecoveryKeyBlob = Preconditions.checkNotNull(encryptedRecoveryKeyBlob);
60 }
61
62 private KeychainSnapshot() {
63
64 }
65
66 /**
67 * Snapshot version for given account. It is incremented when user secret or list of application
68 * keys changes.
69 */
70 public int getSnapshotVersion() {
71 return mSnapshotVersion;
72 }
73
74 /**
Dmitry Dementyevadd1bad2018-01-18 16:44:08 -080075 * Number of user secret guesses allowed during Keychain recovery.
76 */
77 public int getMaxAttempts() {
78 return mMaxAttempts;
79 }
80
81 /**
82 * CounterId which is rotated together with user secret.
83 */
84 public long getCounterId() {
85 return mCounterId;
86 }
87
88 /**
89 * Server parameters.
90 */
91 public @NonNull byte[] getServerParams() {
92 return mServerParams;
93 }
94
95 /**
96 * Public key used to encrypt {@code encryptedRecoveryKeyBlob}.
97 *
98 * See implementation for binary key format
99 */
100 // TODO: document key format.
101 public @NonNull byte[] getTrustedHardwarePublicKey() {
102 return mPublicKey;
103 }
104
105 /**
Robert Berry5f138702018-01-17 15:18:05 +0000106 * UI and key derivation parameters. Note that combination of secrets may be used.
107 */
Robert Berry9e1bd362018-01-17 23:28:45 +0000108 public @NonNull List<KeychainProtectionParams> getKeychainProtectionParams() {
Robert Berry5f138702018-01-17 15:18:05 +0000109 return mKeychainProtectionParams;
110 }
111
112 /**
113 * List of application keys, with key material encrypted by
114 * the recovery key ({@link #getEncryptedRecoveryKeyBlob}).
115 */
116 public @NonNull List<WrappedApplicationKey> getWrappedApplicationKeys() {
117 return mEntryRecoveryData;
118 }
119
120 /**
121 * Recovery key blob, encrypted by user secret and recovery service public key.
122 */
123 public @NonNull byte[] getEncryptedRecoveryKeyBlob() {
124 return mEncryptedRecoveryKeyBlob;
125 }
126
127 public static final Parcelable.Creator<KeychainSnapshot> CREATOR =
128 new Parcelable.Creator<KeychainSnapshot>() {
129 public KeychainSnapshot createFromParcel(Parcel in) {
130 return new KeychainSnapshot(in);
131 }
132
133 public KeychainSnapshot[] newArray(int length) {
134 return new KeychainSnapshot[length];
135 }
136 };
137
138 /**
139 * Builder for creating {@link KeychainSnapshot}.
Dmitry Dementyevf8ae5de2018-01-08 18:08:23 -0800140 *
141 * @hide
Robert Berry5f138702018-01-17 15:18:05 +0000142 */
143 public static class Builder {
144 private KeychainSnapshot mInstance = new KeychainSnapshot();
145
146 /**
147 * Snapshot version for given account.
148 *
149 * @param snapshotVersion The snapshot version
150 * @return This builder.
151 */
152 public Builder setSnapshotVersion(int snapshotVersion) {
153 mInstance.mSnapshotVersion = snapshotVersion;
154 return this;
155 }
156
157 /**
Dmitry Dementyevadd1bad2018-01-18 16:44:08 -0800158 * Sets the number of user secret guesses allowed during Keychain recovery.
159 *
160 * @param maxAttempts The maximum number of guesses.
161 * @return This builder.
162 */
163 public Builder setMaxAttempts(int maxAttempts) {
164 mInstance.mMaxAttempts = maxAttempts;
165 return this;
166 }
167
168 /**
169 * Sets counter id.
170 *
171 * @param counterId The counter id.
172 * @return This builder.
173 */
174 public Builder setCounterId(long counterId) {
175 mInstance.mCounterId = counterId;
176 return this;
177 }
178
179 /**
180 * Sets server parameters.
181 *
182 * @param serverParams The server parameters
183 * @return This builder.
184 */
185 public Builder setServerParams(byte[] serverParams) {
186 mInstance.mServerParams = serverParams;
187 return this;
188 }
189
190 /**
191 * Sets public key used to encrypt recovery blob.
192 *
193 * @param publicKey The public key
194 * @return This builder.
195 */
196 public Builder setTrustedHardwarePublicKey(byte[] publicKey) {
197 mInstance.mPublicKey = publicKey;
198 return this;
199 }
200
201 /**
Robert Berry5f138702018-01-17 15:18:05 +0000202 * Sets UI and key derivation parameters
203 *
204 * @param recoveryMetadata The UI and key derivation parameters
205 * @return This builder.
206 */
207 public Builder setKeychainProtectionParams(
Robert Berry9e1bd362018-01-17 23:28:45 +0000208 @NonNull List<KeychainProtectionParams> recoveryMetadata) {
Robert Berry5f138702018-01-17 15:18:05 +0000209 mInstance.mKeychainProtectionParams = recoveryMetadata;
210 return this;
211 }
212
213 /**
214 * List of application keys.
215 *
216 * @param entryRecoveryData List of application keys
217 * @return This builder.
218 */
219 public Builder setWrappedApplicationKeys(List<WrappedApplicationKey> entryRecoveryData) {
220 mInstance.mEntryRecoveryData = entryRecoveryData;
221 return this;
222 }
223
224 /**
225 * Sets recovery key blob
226 *
227 * @param encryptedRecoveryKeyBlob The recovery key blob.
228 * @return This builder.
229 */
230 public Builder setEncryptedRecoveryKeyBlob(@NonNull byte[] encryptedRecoveryKeyBlob) {
231 mInstance.mEncryptedRecoveryKeyBlob = encryptedRecoveryKeyBlob;
232 return this;
233 }
234
235
236 /**
237 * Creates a new {@link KeychainSnapshot} instance.
238 *
239 * @return new instance
240 * @throws NullPointerException if some required fields were not set.
241 */
242 @NonNull public KeychainSnapshot build() {
243 Preconditions.checkCollectionElementsNotNull(mInstance.mKeychainProtectionParams,
244 "recoveryMetadata");
245 Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
246 "entryRecoveryData");
247 Preconditions.checkNotNull(mInstance.mEncryptedRecoveryKeyBlob);
Dmitry Dementyevadd1bad2018-01-18 16:44:08 -0800248 Preconditions.checkNotNull(mInstance.mServerParams);
249 Preconditions.checkNotNull(mInstance.mPublicKey);
Robert Berry5f138702018-01-17 15:18:05 +0000250 return mInstance;
251 }
252 }
253
Robert Berry5f138702018-01-17 15:18:05 +0000254 @Override
255 public void writeToParcel(Parcel out, int flags) {
256 out.writeInt(mSnapshotVersion);
257 out.writeTypedList(mKeychainProtectionParams);
258 out.writeByteArray(mEncryptedRecoveryKeyBlob);
259 out.writeTypedList(mEntryRecoveryData);
260 }
261
262 /**
263 * @hide
264 */
265 protected KeychainSnapshot(Parcel in) {
266 mSnapshotVersion = in.readInt();
Robert Berry9e1bd362018-01-17 23:28:45 +0000267 mKeychainProtectionParams = in.createTypedArrayList(KeychainProtectionParams.CREATOR);
Robert Berry5f138702018-01-17 15:18:05 +0000268 mEncryptedRecoveryKeyBlob = in.createByteArray();
269 mEntryRecoveryData = in.createTypedArrayList(WrappedApplicationKey.CREATOR);
270 }
271
272 @Override
273 public int describeContents() {
274 return 0;
275 }
276}