blob: 665c937591a38c4f8f9776bd39e3f86abf6cf000 [file] [log] [blame]
Robert Berry81ee34b2018-01-23 11:59:59 +00001/*
Robert Berry291bd322018-02-25 22:19:08 +00002 * Copyright (C) 2018 The Android Open Source Project
Robert Berry81ee34b2018-01-23 11:59:59 +00003 *
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.recovery;
18
19import android.annotation.NonNull;
Bo Zhuc7048342019-01-03 14:04:58 -080020import android.annotation.Nullable;
Dmitry Dementyevf8ae5de2018-01-08 18:08:23 -080021import android.annotation.SystemApi;
Robert Berry81ee34b2018-01-23 11:59:59 +000022import android.os.Parcel;
23import android.os.Parcelable;
24
25import com.android.internal.util.Preconditions;
26
27/**
28 * Helper class with data necessary recover a single application key, given a recovery key.
29 *
30 * <ul>
31 * <li>Alias - Keystore alias of the key.
32 * <li>Encrypted key material.
33 * </ul>
34 *
35 * Note that Application info is not included. Recovery Agent can only make its own keys
36 * recoverable.
37 *
38 * @hide
39 */
Dmitry Dementyevf8ae5de2018-01-08 18:08:23 -080040@SystemApi
Robert Berry81ee34b2018-01-23 11:59:59 +000041public final class WrappedApplicationKey implements Parcelable {
42 private String mAlias;
43 // The only supported format is AES-256 symmetric key.
44 private byte[] mEncryptedKeyMaterial;
Bo Zhuc7048342019-01-03 14:04:58 -080045 // The optional metadata that's authenticated (but unencrypted) with the key material.
46 private byte[] mMetadata;
Robert Berry81ee34b2018-01-23 11:59:59 +000047
Robert Berry52c15f12018-03-29 10:21:50 +010048 // IMPORTANT! PLEASE READ!
49 // -----------------------
50 // If you edit this file (e.g., to add new fields), please MAKE SURE to also do the following:
51 // - Update the #writeToParcel(Parcel) method below
52 // - Update the #(Parcel) constructor below
53 // - Update android.security.keystore.recovery.KeyChainSnapshotTest to make sure nobody
54 // accidentally breaks your fields in the Parcel in the future.
55 // - Update com.android.server.locksettings.recoverablekeystore.serialization
56 // .KeyChainSnapshotSerializer to correctly serialize your new field
57 // - Update com.android.server.locksettings.recoverablekeystore.serialization
58 // .KeyChainSnapshotSerializer to correctly deserialize your new field
59 // - Update com.android.server.locksettings.recoverablekeystore.serialization
60 // .KeychainSnapshotSerializerTest to make sure nobody breaks serialization of your field
61 // in the future.
62
Robert Berry81ee34b2018-01-23 11:59:59 +000063 /**
64 * Builder for creating {@link WrappedApplicationKey}.
65 */
66 public static class Builder {
Dmitry Dementyev0916e7c2018-01-23 13:02:08 -080067 private WrappedApplicationKey mInstance = new WrappedApplicationKey();
Robert Berry81ee34b2018-01-23 11:59:59 +000068
69 /**
70 * Sets Application-specific alias of the key.
71 *
72 * @param alias The alias.
73 * @return This builder.
74 */
Dmitry Dementyevebe53272019-03-05 13:33:24 -080075 public @NonNull Builder setAlias(@NonNull String alias) {
Robert Berry81ee34b2018-01-23 11:59:59 +000076 mInstance.mAlias = alias;
77 return this;
78 }
79
80 /**
81 * Sets key material encrypted by recovery key.
82 *
83 * @param encryptedKeyMaterial The key material
84 * @return This builder
85 */
Dmitry Dementyevebe53272019-03-05 13:33:24 -080086 public @NonNull Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
Robert Berry81ee34b2018-01-23 11:59:59 +000087 mInstance.mEncryptedKeyMaterial = encryptedKeyMaterial;
88 return this;
89 }
90
91 /**
Bo Zhuc7048342019-01-03 14:04:58 -080092 * Sets the metadata that is authenticated (but unecrypted) with the key material.
93 *
94 * @param metadata The metadata
95 * @return This builder
96 */
Dmitry Dementyevebe53272019-03-05 13:33:24 -080097 public @NonNull Builder setMetadata(@Nullable byte[] metadata) {
Bo Zhuc7048342019-01-03 14:04:58 -080098 mInstance.mMetadata = metadata;
99 return this;
100 }
101
102 /**
Robert Berry81ee34b2018-01-23 11:59:59 +0000103 * Creates a new {@link WrappedApplicationKey} instance.
104 *
105 * @return new instance
106 * @throws NullPointerException if some required fields were not set.
107 */
Dmitry Dementyevebe53272019-03-05 13:33:24 -0800108 public @NonNull WrappedApplicationKey build() {
Robert Berry81ee34b2018-01-23 11:59:59 +0000109 Preconditions.checkNotNull(mInstance.mAlias);
110 Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
111 return mInstance;
112 }
113 }
114
Robert Berry291bd322018-02-25 22:19:08 +0000115 private WrappedApplicationKey() { }
Robert Berry81ee34b2018-01-23 11:59:59 +0000116
117 /**
Bo Zhuc7048342019-01-03 14:04:58 -0800118 * @deprecated Use the builder instead.
Robert Berry81ee34b2018-01-23 11:59:59 +0000119 * @hide
120 */
Bo Zhuc7048342019-01-03 14:04:58 -0800121 @Deprecated
Robert Berry81ee34b2018-01-23 11:59:59 +0000122 public WrappedApplicationKey(@NonNull String alias, @NonNull byte[] encryptedKeyMaterial) {
123 mAlias = Preconditions.checkNotNull(alias);
124 mEncryptedKeyMaterial = Preconditions.checkNotNull(encryptedKeyMaterial);
125 }
126
127 /**
128 * Application-specific alias of the key.
129 *
130 * @see java.security.KeyStore.aliases
131 */
132 public @NonNull String getAlias() {
133 return mAlias;
134 }
135
136 /** Key material encrypted by recovery key. */
137 public @NonNull byte[] getEncryptedKeyMaterial() {
138 return mEncryptedKeyMaterial;
139 }
140
Bo Zhuc7048342019-01-03 14:04:58 -0800141 /** The metadata with the key. */
142 public @Nullable byte[] getMetadata() {
143 return mMetadata;
144 }
145
Dmitry Dementyevebe53272019-03-05 13:33:24 -0800146 public static final @NonNull Parcelable.Creator<WrappedApplicationKey> CREATOR =
Dmitry Dementyev0916e7c2018-01-23 13:02:08 -0800147 new Parcelable.Creator<WrappedApplicationKey>() {
Robert Berry81ee34b2018-01-23 11:59:59 +0000148 public WrappedApplicationKey createFromParcel(Parcel in) {
149 return new WrappedApplicationKey(in);
150 }
151
152 public WrappedApplicationKey[] newArray(int length) {
153 return new WrappedApplicationKey[length];
154 }
155 };
156
Robert Berry81ee34b2018-01-23 11:59:59 +0000157 @Override
158 public void writeToParcel(Parcel out, int flags) {
159 out.writeString(mAlias);
160 out.writeByteArray(mEncryptedKeyMaterial);
Bo Zhuc7048342019-01-03 14:04:58 -0800161 out.writeByteArray(mMetadata);
Robert Berry81ee34b2018-01-23 11:59:59 +0000162 }
163
164 /**
165 * @hide
166 */
167 protected WrappedApplicationKey(Parcel in) {
168 mAlias = in.readString();
169 mEncryptedKeyMaterial = in.createByteArray();
Bo Zhuc7048342019-01-03 14:04:58 -0800170 // Check if there is still data to be read.
171 if (in.dataAvail() > 0) {
172 mMetadata = in.createByteArray();
173 }
Robert Berry81ee34b2018-01-23 11:59:59 +0000174 }
175
176 @Override
177 public int describeContents() {
178 return 0;
179 }
180}